[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] merge with xen-unstable.hg



# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1181935991 21600
# Node ID 3b51eebdf9ab83e4473913358d4924370fa75763
# Parent  fe42519fb10eba65cf7034e105738f71010933ca
# Parent  f1ba2e652724cb505a85eef64eaafe9774421011
merge with xen-unstable.hg
---
 buildconfigs/mk.linux-2.6-xen                 |    6 
 docs/src/user.tex                             |    2 
 tools/libxen/src/xen_vbd.c                    |    4 
 tools/libxen/src/xen_vm.c                     |    6 
 tools/python/xen/xend/XendAPI.py              |   17 +
 tools/python/xen/xend/osdep.py                |   10 
 tools/python/xen/xend/server/DevController.py |   32 +-
 tools/xenfb/xenfb.c                           |    1 
 tools/xenstat/xentop/xentop.c                 |   53 ++-
 unmodified_drivers/linux-2.6/mkbuildtree      |    3 
 xen/arch/x86/genapic/es7000plat.c             |    4 
 xen/arch/x86/hvm/hpet.c                       |    3 
 xen/arch/x86/hvm/hvm.c                        |    4 
 xen/arch/x86/hvm/i8254.c                      |  379 ++++++++++++--------------
 xen/arch/x86/hvm/pmtimer.c                    |   15 -
 xen/arch/x86/hvm/rtc.c                        |  139 ++++-----
 xen/arch/x86/hvm/svm/svm.c                    |    9 
 xen/arch/x86/hvm/vlapic.c                     |    4 
 xen/arch/x86/hvm/vmx/intr.c                   |   73 ++---
 xen/arch/x86/hvm/vmx/vmcs.c                   |    5 
 xen/arch/x86/hvm/vmx/vmx.c                    |   18 +
 xen/arch/x86/hvm/vpt.c                        |  105 +++----
 xen/arch/x86/io_apic.c                        |    9 
 xen/include/asm-x86/hvm/vmx/vmcs.h            |   10 
 xen/include/asm-x86/hvm/vmx/vmx.h             |   14 
 xen/include/asm-x86/hvm/vpt.h                 |    8 
 xen/include/asm-x86/msr.h                     |    1 
 xen/include/public/io/ring.h                  |    2 
 xen/include/public/io/xs_wire.h               |    6 
 29 files changed, 509 insertions(+), 433 deletions(-)

diff -r fe42519fb10e -r 3b51eebdf9ab buildconfigs/mk.linux-2.6-xen
--- a/buildconfigs/mk.linux-2.6-xen     Fri Jun 15 12:38:35 2007 -0600
+++ b/buildconfigs/mk.linux-2.6-xen     Fri Jun 15 13:33:11 2007 -0600
@@ -49,7 +49,7 @@ endif
        mkdir -p $(INSTALL_BOOT_PATH)
        $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) 
INSTALL_PATH=$(INSTALL_BOOT_PATH) install
 
-$(LINUX_DIR)/include/linux/autoconf.h: CONFIG_FILE=$(PWD)/$(LINUX_DIR)/.config
+$(LINUX_DIR)/include/linux/autoconf.h: 
CONFIG_FILE=$(CURDIR)/$(LINUX_DIR)/.config
 $(LINUX_DIR)/include/linux/autoconf.h: $(LINUX_SRCDIR)/.valid-src
        rm -rf $(LINUX_DIR)
        mkdir -p $(LINUX_DIR)
@@ -90,8 +90,8 @@ endif
              echo "VERSION = 2"; \
              echo "PATCHLEVEL = 6"; \
              echo ""; \
-             echo "KERNELSRC    := $(PWD)/$(LINUX_SRCDIR)"; \
-             echo "KERNELOUTPUT := $(PWD)/$(LINUX_DIR)"; \
+             echo "KERNELSRC    := $(CURDIR)/$(LINUX_SRCDIR)"; \
+             echo "KERNELOUTPUT := $(CURDIR)/$(LINUX_DIR)"; \
              echo ""; \
              echo "MAKEFLAGS += --no-print-directory"; \
              echo ""; \
diff -r fe42519fb10e -r 3b51eebdf9ab docs/src/user.tex
--- a/docs/src/user.tex Fri Jun 15 12:38:35 2007 -0600
+++ b/docs/src/user.tex Fri Jun 15 13:33:11 2007 -0600
@@ -3195,6 +3195,8 @@ writing to the VGA console after domain 
 \item [ edid=no,force ] (x86 only) Either force retrieval of monitor
   EDID information via VESA DDC, or disable it (edid=no). This option
   should not normally be required except for debugging purposes.
+\item [ edd=off,on,skipmbr ] (x86 only) Control retrieval of Extended
+  Disc Data (EDD) from the BIOS during boot.
 \item [ console\_to\_ring ] Place guest console output into the
   hypervisor console ring buffer. This is disabled by default.
   When enabled, both hypervisor output and guest console output
diff -r fe42519fb10e -r 3b51eebdf9ab tools/libxen/src/xen_vbd.c
--- a/tools/libxen/src/xen_vbd.c        Fri Jun 15 12:38:35 2007 -0600
+++ b/tools/libxen/src/xen_vbd.c        Fri Jun 15 13:33:11 2007 -0600
@@ -463,7 +463,7 @@ xen_vbd_set_mode(xen_session *session, x
             { .type = &abstract_type_string,
               .u.string_val = vbd },
             { .type = &xen_vbd_mode_abstract_type_,
-              .u.string_val = xen_vbd_mode_to_string(mode) }
+              .u.enum_val = mode }
         };
 
     xen_call_(session, "VBD.set_mode", param_values, 2, NULL, NULL);
@@ -479,7 +479,7 @@ xen_vbd_set_type(xen_session *session, x
             { .type = &abstract_type_string,
               .u.string_val = vbd },
             { .type = &xen_vbd_type_abstract_type_,
-              .u.string_val = xen_vbd_type_to_string(type) }
+              .u.enum_val = type }
         };
 
     xen_call_(session, "VBD.set_type", param_values, 2, NULL, NULL);
diff -r fe42519fb10e -r 3b51eebdf9ab tools/libxen/src/xen_vm.c
--- a/tools/libxen/src/xen_vm.c Fri Jun 15 12:38:35 2007 -0600
+++ b/tools/libxen/src/xen_vm.c Fri Jun 15 13:33:11 2007 -0600
@@ -1142,7 +1142,7 @@ xen_vm_set_actions_after_shutdown(xen_se
             { .type = &abstract_type_string,
               .u.string_val = vm },
             { .type = &xen_on_normal_exit_abstract_type_,
-              .u.string_val = xen_on_normal_exit_to_string(after_shutdown) }
+              .u.enum_val = after_shutdown }
         };
 
     xen_call_(session, "VM.set_actions_after_shutdown", param_values, 2, NULL, 
NULL);
@@ -1158,7 +1158,7 @@ xen_vm_set_actions_after_reboot(xen_sess
             { .type = &abstract_type_string,
               .u.string_val = vm },
             { .type = &xen_on_normal_exit_abstract_type_,
-              .u.string_val = xen_on_normal_exit_to_string(after_reboot) }
+              .u.enum_val = after_reboot }
         };
 
     xen_call_(session, "VM.set_actions_after_reboot", param_values, 2, NULL, 
NULL);
@@ -1174,7 +1174,7 @@ xen_vm_set_actions_after_crash(xen_sessi
             { .type = &abstract_type_string,
               .u.string_val = vm },
             { .type = &xen_on_crash_behaviour_abstract_type_,
-              .u.string_val = xen_on_crash_behaviour_to_string(after_crash) }
+              .u.enum_val = after_crash }
         };
 
     xen_call_(session, "VM.set_actions_after_crash", param_values, 2, NULL, 
NULL);
diff -r fe42519fb10e -r 3b51eebdf9ab tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Fri Jun 15 12:38:35 2007 -0600
+++ b/tools/python/xen/xend/XendAPI.py  Fri Jun 15 13:33:11 2007 -0600
@@ -1483,6 +1483,12 @@ class XendAPI(object):
         else:
             return xen_api_success_void()
     
+    def VM_set_VCPUs_at_startup(self, session, vm_ref, num):
+        return self.VM_set('VCPUs_at_startup', session, vm_ref, num)
+
+    def VM_set_VCPUs_max(self, session, vm_ref, num):
+        return self.VM_set('VCPUs_max', session, vm_ref, num)
+
     def VM_set_actions_after_shutdown(self, session, vm_ref, action):
         if action not in XEN_API_ON_NORMAL_EXIT:
             return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
@@ -1887,6 +1893,17 @@ class XendAPI(object):
         xd.managed_config_save(vm)
         return xen_api_success_void()
 
+    def VBD_set_mode(self, session, vbd_ref, mode):
+        if mode == 'RW':
+            mode = 'w'
+        else:
+            mode = 'r'
+        xd = XendDomain.instance()
+        vm = xd.get_vm_with_dev_uuid('vbd', vbd_ref)
+        vm.set_dev_property('vbd', vbd_ref, 'mode', mode)
+        xd.managed_config_save(vm)
+        return xen_api_success_void()
+
     def VBD_get_all(self, session):
         xendom = XendDomain.instance()
         vbds = [d.get_vbds() for d in XendDomain.instance().list('all')]
diff -r fe42519fb10e -r 3b51eebdf9ab tools/python/xen/xend/osdep.py
--- a/tools/python/xen/xend/osdep.py    Fri Jun 15 12:38:35 2007 -0600
+++ b/tools/python/xen/xend/osdep.py    Fri Jun 15 13:33:11 2007 -0600
@@ -65,11 +65,11 @@ def _solaris_balloon_stat(label):
     import fcntl
     import array
     DEV_XEN_BALLOON = '/dev/xen/balloon'
-    BLN_IOCTL_CURRENT = 0x4201
-    BLN_IOCTL_TARGET = 0x4202
-    BLN_IOCTL_LOW = 0x4203
-    BLN_IOCTL_HIGH = 0x4204
-    BLN_IOCTL_LIMIT = 0x4205
+    BLN_IOCTL_CURRENT = 0x42410001
+    BLN_IOCTL_TARGET = 0x42410002
+    BLN_IOCTL_LOW = 0x42410003
+    BLN_IOCTL_HIGH = 0x42410004
+    BLN_IOCTL_LIMIT = 0x42410005
     label_to_ioctl = { 'Current allocation'    : BLN_IOCTL_CURRENT,
                        'Requested target'      : BLN_IOCTL_TARGET,
                        'Low-mem balloon'       : BLN_IOCTL_LOW,
diff -r fe42519fb10e -r 3b51eebdf9ab 
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py     Fri Jun 15 12:38:35 
2007 -0600
+++ b/tools/python/xen/xend/server/DevController.py     Fri Jun 15 13:33:11 
2007 -0600
@@ -213,7 +213,7 @@ class DevController:
         devid = int(devid)
 
         frontpath = self.frontendPath(devid)
-       if frontpath:
+        if frontpath:
             backpath = xstransact.Read(frontpath, "backend")
 
         # Modify online status /before/ updating state (latter is watched by
@@ -224,22 +224,22 @@ class DevController:
         if force:
             if backpath:
                 xstransact.Remove(backpath)
-           if frontpath:
+            if frontpath:
                 xstransact.Remove(frontpath)
-           return
-
-       # Wait till both frontpath and backpath are removed from
-       # xenstore, or timed out
-       if frontpath:
-           status = self.waitUntilDestroyed(frontpath)
-           if status == Timeout:
-               # Exception will be caught by destroyDevice in XendDomainInfo.py
-               raise EnvironmentError
-       if backpath:
-           status = self.waitUntilDestroyed(backpath)
-           if status == Timeout:
-               # Exception will be caught by destroyDevice in XendDomainInfo.py
-               raise EnvironmentError
+            return
+
+        # Wait till both frontpath and backpath are removed from
+        # xenstore, or timed out
+        if frontpath:
+            status = self.waitUntilDestroyed(frontpath)
+            if status == Timeout:
+                # Exception will be caught by destroyDevice in 
XendDomainInfo.py
+                raise EnvironmentError
+        if backpath:
+            status = self.waitUntilDestroyed(backpath)
+            if status == Timeout:
+                # Exception will be caught by destroyDevice in 
XendDomainInfo.py
+                raise EnvironmentError
 
         self.vm._removeVm("device/%s/%d" % (self.deviceClass, devid))
 
diff -r fe42519fb10e -r 3b51eebdf9ab tools/xenfb/xenfb.c
--- a/tools/xenfb/xenfb.c       Fri Jun 15 12:38:35 2007 -0600
+++ b/tools/xenfb/xenfb.c       Fri Jun 15 13:33:11 2007 -0600
@@ -10,7 +10,6 @@
 #include <xen/io/protocols.h>
 #include <sys/select.h>
 #include <stdbool.h>
-#include <xen/linux/evtchn.h>
 #include <xen/event_channel.h>
 #include <sys/mman.h>
 #include <errno.h>
diff -r fe42519fb10e -r 3b51eebdf9ab tools/xenstat/xentop/xentop.c
--- a/tools/xenstat/xentop/xentop.c     Fri Jun 15 12:38:35 2007 -0600
+++ b/tools/xenstat/xentop/xentop.c     Fri Jun 15 13:33:11 2007 -0600
@@ -290,12 +290,24 @@ static void print(const char *fmt, ...)
        }
 }
 
+static void xentop_attron(int attr)
+{
+       if (!batch)
+               attron(attr);
+}
+
+static void xentop_attroff(int attr)
+{
+       if (!batch)
+               attroff(attr);
+}
+
 /* Print a string with the given attributes set. */
 static void attr_addstr(int attr, const char *str)
 {
-       attron(attr);
+       xentop_attron(attr);
        addstr((curses_str_t)str);
-       attroff(attr);
+       xentop_attroff(attr);
 }
 
 /* Handle setting the delay from the user-supplied value in prompt_val */
@@ -780,18 +792,18 @@ void do_header(void)
        field_id i;
 
        /* Turn on REVERSE highlight attribute for headings */
-       attron(A_REVERSE);
+       xentop_attron(A_REVERSE);
        for(i = 0; i < NUM_FIELDS; i++) {
-               if(i != 0)
+               if (i != 0)
                        print(" ");
                /* The BOLD attribute is turned on for the sort column */
-               if(i == sort_field)
-                       attron(A_BOLD);
+               if (i == sort_field)
+                       xentop_attron(A_BOLD);
                print("%*s", fields[i].default_width, fields[i].header);
-               if(i == sort_field)
-                       attroff(A_BOLD);
-       }
-       attroff(A_REVERSE);
+               if (i == sort_field)
+                       xentop_attroff(A_BOLD);
+       }
+       xentop_attroff(A_REVERSE);
        print("\n");
 }
 
@@ -838,14 +850,14 @@ void do_domain(xenstat_domain *domain)
 void do_domain(xenstat_domain *domain)
 {
        unsigned int i;
-       for(i = 0; i < NUM_FIELDS; i++) {
-               if(i != 0)
+       for (i = 0; i < NUM_FIELDS; i++) {
+               if (i != 0)
                        print(" ");
-               if(i == sort_field)
-                       attron(A_BOLD);
+               if (i == sort_field)
+                       xentop_attron(A_BOLD);
                fields[i].print(domain);
-               if(i == sort_field)
-                       attroff(A_BOLD);
+               if (i == sort_field)
+                       xentop_attroff(A_BOLD);
        }
        print("\n");
 }
@@ -956,7 +968,8 @@ static void top(void)
                fail("Failed to retrieve statistics from libxenstat\n");
 
        /* dump summary top information */
-       do_summary();
+       if (!batch)
+               do_summary();
 
        /* Count the number of domains for which to report data */
        num_domains = xenstat_node_num_domains(cur_node);
@@ -976,7 +989,7 @@ static void top(void)
                first_domain_index = num_domains-1;
 
        for (i = first_domain_index; i < num_domains; i++) {
-               if(current_row() == lines()-1)
+               if(!batch && current_row() == lines()-1)
                        break;
                if (i == first_domain_index || repeat_header)
                        do_header();
@@ -989,8 +1002,8 @@ static void top(void)
                        do_vbd(domains[i]);
        }
 
-       if(!batch)
-       do_bottom_line();
+       if (!batch)
+               do_bottom_line();
 
        free(domains);
 }
diff -r fe42519fb10e -r 3b51eebdf9ab unmodified_drivers/linux-2.6/mkbuildtree
--- a/unmodified_drivers/linux-2.6/mkbuildtree  Fri Jun 15 12:38:35 2007 -0600
+++ b/unmodified_drivers/linux-2.6/mkbuildtree  Fri Jun 15 13:33:11 2007 -0600
@@ -51,6 +51,7 @@ in
     ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/hypercall.h include/asm
     ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/synch_bitops.h include/asm
     ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/maddr.h include/asm
+    ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/gnttab_dma.h include/asm
     mkdir -p include/asm-i386
     lndir -silent ${XL}/include/asm-i386 include/asm-i386
   ;;
@@ -59,12 +60,14 @@ i[34567]86)
     ln -sf ${XL}/include/asm-i386/mach-xen/asm/hypercall.h include/asm
     ln -sf ${XL}/include/asm-i386/mach-xen/asm/synch_bitops.h include/asm
     ln -sf ${XL}/include/asm-i386/mach-xen/asm/maddr.h include/asm
+    ln -sf ${XL}/include/asm-i386/mach-xen/asm/gnttab_dma.h include/asm
   ;;
 "ia64")
     ln -sf ${XL}/include/asm-ia64/hypervisor.h include/asm
     ln -sf ${XL}/include/asm-ia64/hypercall.h include/asm
     ln -sf ${XL}/include/asm-ia64/synch_bitops.h include/asm
     ln -sf ${XL}/include/asm-ia64/maddr.h include/asm
+    ln -sf ${XL}/include/asm-ia64/gnttab_dma.h include/asm
     mkdir -p include/asm/xen
     ln -sf ${XL}/include/asm-ia64/xen/xcom_hcall.h include/asm/xen
     ln -sf ${XL}/include/asm-ia64/xen/xencomm.h include/asm/xen
diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/genapic/es7000plat.c
--- a/xen/arch/x86/genapic/es7000plat.c Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/arch/x86/genapic/es7000plat.c Fri Jun 15 13:33:11 2007 -0600
@@ -299,12 +299,12 @@ void __init
 void __init
 es7000_sw_apic()
 {
-       if (es7000_plat) {
+       if (es7000_plat && (es7000_plat != ES7000_ZORRO)) {
                int mip_status;
                struct mip_reg es7000_mip_reg;
 
                printk("ES7000: Enabling APIC mode.\n");
-               memset(&es7000_mip_reg, 0, sizeof(struct mip_reg));
+               memset(&es7000_mip_reg, 0, sizeof(struct mip_reg));
                es7000_mip_reg.off_0 = MIP_SW_APIC;
                es7000_mip_reg.off_38 = (MIP_VALID);
                while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0)
diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/hpet.c
--- a/xen/arch/x86/hvm/hpet.c   Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/arch/x86/hvm/hpet.c   Fri Jun 15 13:33:11 2007 -0600
@@ -381,6 +381,9 @@ void hpet_migrate_timers(struct vcpu *v)
     struct HPETState *h = &v->domain->arch.hvm_domain.pl_time.vhpet;
     int i;
 
+    if ( v != h->vcpu )
+        return;
+
     for ( i = 0; i < HPET_TIMER_NUM; i++ )
         migrate_timer(&h->timers[i], v->processor);
 }
diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/arch/x86/hvm/hvm.c    Fri Jun 15 13:33:11 2007 -0600
@@ -109,11 +109,9 @@ u64 hvm_get_guest_time(struct vcpu *v)
 
 void hvm_migrate_timers(struct vcpu *v)
 {
-    pit_migrate_timers(v);
     rtc_migrate_timers(v);
     hpet_migrate_timers(v);
-    if ( vcpu_vlapic(v)->pt.enabled )
-        migrate_timer(&vcpu_vlapic(v)->pt.timer, v->processor);
+    pt_migrate(v);
 }
 
 void hvm_do_resume(struct vcpu *v)
diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/i8254.c
--- a/xen/arch/x86/hvm/i8254.c  Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/arch/x86/hvm/i8254.c  Fri Jun 15 13:33:11 2007 -0600
@@ -3,12 +3,13 @@
  * 
  * Copyright (c) 2003-2004 Fabrice Bellard
  * Copyright (c) 2006 Intel Corperation
+ * Copyright (c) 2007 Keir Fraser, XenSource Inc.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to 
deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
  * furnished to do so, subject to the following conditions:
  *
  * The above copyright notice and this permission notice shall be included in
@@ -18,14 +19,9 @@
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-/* Edwin Zhai <edwin.zhai@xxxxxxxxx>, Eddie Dong <eddie.dong@xxxxxxxxx>
- * Ported to xen:
- * Add a new layer of periodic time on top of PIT;
- * move speaker io access to hypervisor;
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
  */
 
 #include <xen/config.h>
@@ -41,8 +37,11 @@
 #include <asm/hvm/vpt.h>
 #include <asm/current.h>
 
-/* Enable DEBUG_PIT may cause guest calibration inaccuracy */
-/* #define DEBUG_PIT */
+#define domain_vpit(d)   (&(d)->arch.hvm_domain.pl_time.vpit)
+#define vcpu_vpit(vcpu)  (domain_vpit((vcpu)->domain))
+#define vpit_domain(pit) (container_of((pit), struct domain, \
+                                       arch.hvm_domain.pl_time.vpit))
+#define vpit_vcpu(pit)   (vpit_domain(pit)->vcpu[0])
 
 #define RW_STATE_LSB 1
 #define RW_STATE_MSB 2
@@ -52,8 +51,8 @@ static int handle_pit_io(ioreq_t *p);
 static int handle_pit_io(ioreq_t *p);
 static int handle_speaker_io(ioreq_t *p);
 
-/* compute with 96 bit intermediate result: (a*b)/c */
-uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
+/* Compute with 96 bit intermediate result: (a*b)/c */
+static uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 {
     union {
         uint64_t ll;
@@ -76,16 +75,18 @@ uint64_t muldiv64(uint64_t a, uint32_t b
     return res.ll;
 }
 
-static int pit_get_count(PITState *s, int channel)
+static int pit_get_count(PITState *pit, int channel)
 {
     uint64_t d;
     int  counter;
-    struct hvm_hw_pit_channel *c = &s->hw.channels[channel];
-    struct periodic_time *pt = &s->pt[channel];
-
-    d = muldiv64(hvm_get_guest_time(pt->vcpu) - s->count_load_time[channel],
-                 PIT_FREQ, ticks_per_sec(pt->vcpu));
-    switch(c->mode) {
+    struct hvm_hw_pit_channel *c = &pit->hw.channels[channel];
+    struct vcpu *v = vpit_vcpu(pit);
+
+    d = muldiv64(hvm_get_guest_time(v) - pit->count_load_time[channel],
+                 PIT_FREQ, ticks_per_sec(v));
+
+    switch ( c->mode )
+    {
     case 0:
     case 1:
     case 4:
@@ -103,16 +104,18 @@ static int pit_get_count(PITState *s, in
     return counter;
 }
 
-/* get pit output bit */
-int pit_get_out(PITState *pit, int channel, int64_t current_time)
+static int pit_get_out(PITState *pit, int channel)
 {
     struct hvm_hw_pit_channel *s = &pit->hw.channels[channel];
     uint64_t d;
     int out;
-
-    d = muldiv64(current_time - pit->count_load_time[channel], 
-                 PIT_FREQ, ticks_per_sec(pit->pt[channel].vcpu));
-    switch(s->mode) {
+    struct vcpu *v = vpit_vcpu(pit);
+
+    d = muldiv64(hvm_get_guest_time(v) - pit->count_load_time[channel], 
+                 PIT_FREQ, ticks_per_sec(v));
+
+    switch ( s->mode )
+    {
     default:
     case 0:
         out = (d >= s->count);
@@ -121,29 +124,27 @@ int pit_get_out(PITState *pit, int chann
         out = (d < s->count);
         break;
     case 2:
-        if ((d % s->count) == 0 && d != 0)
-            out = 1;
-        else
-            out = 0;
+        out = (((d % s->count) == 0) && (d != 0));
         break;
     case 3:
-        out = (d % s->count) < ((s->count + 1) >> 1);
+        out = ((d % s->count) < ((s->count + 1) >> 1));
         break;
     case 4:
     case 5:
         out = (d == s->count);
         break;
     }
+
     return out;
 }
 
-/* val must be 0 or 1 */
-void pit_set_gate(PITState *pit, int channel, int val)
+static void pit_set_gate(PITState *pit, int channel, int val)
 {
     struct hvm_hw_pit_channel *s = &pit->hw.channels[channel];
-    struct periodic_time *pt = &pit->pt[channel];
-
-    switch(s->mode) {
+    struct vcpu *v = vpit_vcpu(pit);
+
+    switch ( s->mode )
+    {
     default:
     case 0:
     case 4:
@@ -151,22 +152,14 @@ void pit_set_gate(PITState *pit, int cha
         break;
     case 1:
     case 5:
-        if (s->gate < val) {
-            /* restart counting on rising edge */
-            pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu);
-//            pit_irq_timer_update(s, s->count_load_time);
-        }
-        break;
     case 2:
     case 3:
-        if (s->gate < val) {
-            /* restart counting on rising edge */
-            pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu);
-//            pit_irq_timer_update(s, s->count_load_time);
-        }
-        /* XXX: disable/enable counting */
-        break;
-    }
+        /* Restart counting on rising edge. */
+        if ( s->gate < val )
+            pit->count_load_time[channel] = hvm_get_guest_time(v);
+        break;
+    }
+
     s->gate = val;
 }
 
@@ -175,57 +168,40 @@ int pit_get_gate(PITState *pit, int chan
     return pit->hw.channels[channel].gate;
 }
 
-void pit_time_fired(struct vcpu *v, void *priv)
+static void pit_time_fired(struct vcpu *v, void *priv)
 {
     uint64_t *count_load_time = priv;
     *count_load_time = hvm_get_guest_time(v);
 }
 
-static inline void pit_load_count(PITState *pit, int channel, int val)
+static void pit_load_count(PITState *pit, int channel, int val)
 {
     u32 period;
     struct hvm_hw_pit_channel *s = &pit->hw.channels[channel];
     struct periodic_time *pt = &pit->pt[channel];
-    struct vcpu *v;
-
-    if (val == 0)
+    struct vcpu *v = vpit_vcpu(pit);
+
+    if ( val == 0 )
         val = 0x10000;
+
     pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu);
     s->count = val;
     period = DIV_ROUND((val * 1000000000ULL), PIT_FREQ);
 
-    if (channel != 0)
+    if ( (v == NULL) || !is_hvm_vcpu(v) || (channel != 0) )
         return;
 
-#ifdef DEBUG_PIT
-    printk("HVM_PIT: pit-load-counter(%p), count=0x%x, period=%uns mode=%d, 
load_time=%lld\n",
-            s,
-            val,
-            period,
-            s->mode,
-            (long long)pit->count_load_time[channel]);
-#endif
-
-    /* Choose a vcpu to set the timer on: current if appropriate else vcpu 0 */
-    if ( likely(pit == &current->domain->arch.hvm_domain.pl_time.vpit) )
-        v = current;
-    else 
-        v = container_of(pit, struct domain, 
-                         arch.hvm_domain.pl_time.vpit)->vcpu[0];
-
-    switch (s->mode) {
+    switch ( s->mode )
+    {
         case 2:
-            /* create periodic time */
+            /* Periodic timer. */
             create_periodic_time(v, pt, period, 0, 0, pit_time_fired, 
                                  &pit->count_load_time[channel]);
             break;
         case 1:
-            /* create one shot time */
+            /* One-shot timer. */
             create_periodic_time(v, pt, period, 0, 1, pit_time_fired,
                                  &pit->count_load_time[channel]);
-#ifdef DEBUG_PIT
-            printk("HVM_PIT: create one shot time.\n");
-#endif
             break;
         default:
             destroy_periodic_time(pt);
@@ -233,63 +209,84 @@ static inline void pit_load_count(PITSta
     }
 }
 
-/* if already latched, do not latch again */
 static void pit_latch_count(PITState *s, int channel)
 {
     struct hvm_hw_pit_channel *c = &s->hw.channels[channel];
-    if (!c->count_latched) {
+    if ( !c->count_latched )
+    {
         c->latched_count = pit_get_count(s, channel);
         c->count_latched = c->rw_mode;
     }
 }
 
-static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
-    PITState *pit = opaque;
+static void pit_latch_status(PITState *s, int channel)
+{
+    struct hvm_hw_pit_channel *c = &s->hw.channels[channel];
+    if ( !c->status_latched )
+    {
+        /* TODO: Return NULL COUNT (bit 6). */
+        c->status = ((pit_get_out(s, channel) << 7) |
+                     (c->rw_mode << 4) |
+                     (c->mode << 1) |
+                     c->bcd);
+        c->status_latched = 1;
+    }
+}
+
+static void pit_ioport_write(struct PITState *pit, uint32_t addr, uint32_t val)
+{
     int channel, access;
     struct hvm_hw_pit_channel *s;
-    val &= 0xff;
-
+
+    val  &= 0xff;
     addr &= 3;
-    if (addr == 3) {
+
+    if ( addr == 3 )
+    {
         channel = val >> 6;
-        if (channel == 3) {
-            /* read back command */
-            for(channel = 0; channel < 3; channel++) {
+        if ( channel == 3 )
+        {
+            /* Read-Back Command. */
+            for ( channel = 0; channel < 3; channel++ )
+            {
                 s = &pit->hw.channels[channel];
-                if (val & (2 << channel)) {
-                    if (!(val & 0x20)) {
+                if ( val & (2 << channel) )
+                {
+                    if ( !(val & 0x20) )
                         pit_latch_count(pit, channel);
-                    }
-                    if (!(val & 0x10) && !s->status_latched) {
-                        /* status latch */
-                        /* XXX: add BCD and null count */
-                        s->status = (pit_get_out(pit, channel, 
hvm_get_guest_time(pit->pt[channel].vcpu)) << 7) |
-                            (s->rw_mode << 4) |
-                            (s->mode << 1) |
-                            s->bcd;
-                        s->status_latched = 1;
-                    }
+                    if ( !(val & 0x10) )
+                        pit_latch_status(pit, channel);
                 }
             }
-        } else {
+        }
+        else
+        {
+            /* Select Counter <channel>. */
             s = &pit->hw.channels[channel];
             access = (val >> 4) & 3;
-            if (access == 0) {
+            if ( access == 0 )
+            {
                 pit_latch_count(pit, channel);
-            } else {
+            }
+            else
+            {
                 s->rw_mode = access;
                 s->read_state = access;
                 s->write_state = access;
-
                 s->mode = (val >> 1) & 7;
+                if ( s->mode > 5 )
+                    s->mode -= 4;
                 s->bcd = val & 1;
                 /* XXX: update irq timer ? */
             }
         }
-    } else {
+    }
+    else
+    {
+        /* Write Count. */
         s = &pit->hw.channels[addr];
-        switch(s->write_state) {
+        switch ( s->write_state )
+        {
         default:
         case RW_STATE_LSB:
             pit_load_count(pit, addr, val);
@@ -309,19 +306,23 @@ static void pit_ioport_write(void *opaqu
     }
 }
 
-static uint32_t pit_ioport_read(void *opaque, uint32_t addr)
-{
-    PITState *pit = opaque;
+static uint32_t pit_ioport_read(struct PITState *pit, uint32_t addr)
+{
     int ret, count;
     struct hvm_hw_pit_channel *s;
     
     addr &= 3;
     s = &pit->hw.channels[addr];
-    if (s->status_latched) {
+
+    if ( s->status_latched )
+    {
         s->status_latched = 0;
         ret = s->status;
-    } else if (s->count_latched) {
-        switch(s->count_latched) {
+    }
+    else if ( s->count_latched )
+    {
+        switch ( s->count_latched )
+        {
         default:
         case RW_STATE_LSB:
             ret = s->latched_count & 0xff;
@@ -336,8 +337,11 @@ static uint32_t pit_ioport_read(void *op
             s->count_latched = RW_STATE_MSB;
             break;
         }
-    } else {
-        switch(s->read_state) {
+    }
+    else
+    {
+        switch ( s->read_state )
+        {
         default:
         case RW_STATE_LSB:
             count = pit_get_count(pit, addr);
@@ -359,10 +363,11 @@ static uint32_t pit_ioport_read(void *op
             break;
         }
     }
+
     return ret;
 }
 
-void pit_stop_channel0_irq(PITState * pit)
+void pit_stop_channel0_irq(PITState *pit)
 {
     destroy_periodic_time(&pit->pt[0]);
 }
@@ -374,7 +379,8 @@ static void pit_info(PITState *pit)
     struct periodic_time *pt;
     int i;
 
-    for(i = 0; i < 3; i++) {
+    for ( i = 0; i < 3; i++ )
+    {
         printk("*****pit channel %d's state:*****\n", i);
         s = &pit->hw.channels[i];
         printk("pit 0x%x.\n", s->count);
@@ -392,7 +398,8 @@ static void pit_info(PITState *pit)
         printk("pit %"PRId64"\n", pit->count_load_time[i]);
 
         pt = &pit->pt[i];
-        if (pt) {
+        if ( pt )
+        {
             printk("pit channel %d has a periodic timer:\n", i);
             printk("pt %d.\n", pt->enabled);
             printk("pt %d.\n", pt->one_shot);
@@ -405,7 +412,6 @@ static void pit_info(PITState *pit)
             printk("pt %"PRId64"\n", pt->last_plt_gtime);
         }
     }
-
 }
 #else
 static void pit_info(PITState *pit)
@@ -415,7 +421,7 @@ static void pit_info(PITState *pit)
 
 static int pit_save(struct domain *d, hvm_domain_context_t *h)
 {
-    PITState *pit = &d->arch.hvm_domain.pl_time.vpit;
+    PITState *pit = domain_vpit(d);
     
     pit_info(pit);
 
@@ -425,7 +431,7 @@ static int pit_save(struct domain *d, hv
 
 static int pit_load(struct domain *d, hvm_domain_context_t *h)
 {
-    PITState *pit = &d->arch.hvm_domain.pl_time.vpit;
+    PITState *pit = domain_vpit(d);
     int i;
 
     /* Restore the PIT hardware state */
@@ -435,8 +441,8 @@ static int pit_load(struct domain *d, hv
     /* Recreate platform timers from hardware state.  There will be some 
      * time jitter here, but the wall-clock will have jumped massively, so 
      * we hope the guest can handle it. */
-
-    for(i = 0; i < 3; i++) {
+    for ( i = 0; i < 3; i++ )
+    {
         pit_load_count(pit, i, pit->hw.channels[i].count);
         pit->pt[i].last_plt_gtime = hvm_get_guest_time(d->vcpu[0]);
     }
@@ -447,121 +453,94 @@ static int pit_load(struct domain *d, hv
 
 HVM_REGISTER_SAVE_RESTORE(PIT, pit_save, pit_load, 1, HVMSR_PER_DOM);
 
-static void pit_reset(void *opaque)
-{
-    PITState *pit = opaque;
+void pit_init(struct vcpu *v, unsigned long cpu_khz)
+{
+    PITState *pit = vcpu_vpit(v);
+    struct periodic_time *pt;
     struct hvm_hw_pit_channel *s;
     int i;
 
-    for(i = 0;i < 3; i++) {
-        s = &pit->hw.channels[i];
-        destroy_periodic_time(&pit->pt[i]);
-        s->mode = 0xff; /* the init mode */
-        s->gate = (i != 2);
-        pit_load_count(pit, i, 0);
-    }
-}
-
-void pit_init(struct vcpu *v, unsigned long cpu_khz)
-{
-    PITState *pit = &v->domain->arch.hvm_domain.pl_time.vpit;
-    struct periodic_time *pt;
-
     pt = &pit->pt[0];  
-    pt->vcpu = v;
-    /* the timer 0 is connected to an IRQ */
-    init_timer(&pt->timer, pt_timer_fn, pt, v->processor);
-    pt++; pt->vcpu = v;
-    pt++; pt->vcpu = v;
+    pt[0].vcpu = v;
+    pt[1].vcpu = v;
+    pt[2].vcpu = v;
 
     register_portio_handler(v->domain, PIT_BASE, 4, handle_pit_io);
     /* register the speaker port */
     register_portio_handler(v->domain, 0x61, 1, handle_speaker_io);
     ticks_per_sec(v) = cpu_khz * (int64_t)1000;
-#ifdef DEBUG_PIT
-    printk("HVM_PIT: guest frequency =%lld\n", (long long)ticks_per_sec(v));
-#endif
-    pit_reset(pit);
-    return;
-}
-
-void pit_migrate_timers(struct vcpu *v)
-{
-    PITState *pit = &v->domain->arch.hvm_domain.pl_time.vpit;
-    struct periodic_time *pt;
-
-    pt = &pit->pt[0];
-    if ( pt->vcpu == v && pt->enabled )
-        migrate_timer(&pt->timer, v->processor);
+
+    for ( i = 0; i < 3; i++ )
+    {
+        s = &pit->hw.channels[i];
+        s->mode = 0xff; /* the init mode */
+        s->gate = (i != 2);
+        pit_load_count(pit, i, 0);
+    }
 }
 
 void pit_deinit(struct domain *d)
 {
-    PITState *pit = &d->arch.hvm_domain.pl_time.vpit;
-
-    kill_timer(&pit->pt[0].timer);
+    PITState *pit = domain_vpit(d);
+    destroy_periodic_time(&pit->pt[0]);
 }
 
 /* the intercept action for PIT DM retval:0--not handled; 1--handled */  
 static int handle_pit_io(ioreq_t *p)
 {
-    struct vcpu *v = current;
-    struct PITState *vpit = &(v->domain->arch.hvm_domain.pl_time.vpit);
-
-    if (p->size != 1 ||
-        p->data_is_ptr ||
-        p->type != IOREQ_TYPE_PIO){
-        printk("HVM_PIT:wrong PIT IO!\n");
+    struct PITState *vpit = vcpu_vpit(current);
+
+    if ( (p->size != 1) || p->data_is_ptr || (p->type != IOREQ_TYPE_PIO) )
+    {
+        gdprintk(XENLOG_WARNING, "HVM_PIT bad access\n");
         return 1;
     }
     
-    if (p->dir == 0) {/* write */
+    if ( p->dir == IOREQ_WRITE )
+    {
         pit_ioport_write(vpit, p->addr, p->data);
-    } else if (p->dir == 1) { /* read */
-        if ( (p->addr & 3) != 3 ) {
+    }
+    else
+    {
+        if ( (p->addr & 3) != 3 )
             p->data = pit_ioport_read(vpit, p->addr);
-        } else {
-            printk("HVM_PIT: read A1:A0=3!\n");
-        }
-    }
+        else
+            gdprintk(XENLOG_WARNING, "HVM_PIT: read A1:A0=3!\n");
+    }
+
     return 1;
 }
 
-static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
-    PITState *pit = opaque;
+static void speaker_ioport_write(
+    struct PITState *pit, uint32_t addr, uint32_t val)
+{
     pit->hw.speaker_data_on = (val >> 1) & 1;
     pit_set_gate(pit, 2, val & 1);
 }
 
-static uint32_t speaker_ioport_read(void *opaque, uint32_t addr)
-{
-    PITState *pit = opaque;
-    int out = pit_get_out(pit, 2,
-                          hvm_get_guest_time(pit->pt[2].vcpu));
+static uint32_t speaker_ioport_read(
+    struct PITState *pit, uint32_t addr)
+{
     /* Refresh clock toggles at about 15us. We approximate as 2^14ns. */
     unsigned int refresh_clock = ((unsigned int)NOW() >> 14) & 1;
     return ((pit->hw.speaker_data_on << 1) | pit_get_gate(pit, 2) |
-            (out << 5) | refresh_clock << 4);
+            (pit_get_out(pit, 2) << 5) | (refresh_clock << 4));
 }
 
 static int handle_speaker_io(ioreq_t *p)
 {
-    struct vcpu *v = current;
-    struct PITState *vpit = &(v->domain->arch.hvm_domain.pl_time.vpit);
-
-    if (p->size != 1 ||
-        p->data_is_ptr ||
-        p->type != IOREQ_TYPE_PIO){
-        printk("HVM_SPEAKER:wrong SPEAKER IO!\n");
+    struct PITState *vpit = vcpu_vpit(current);
+
+    if ( (p->size != 1) || p->data_is_ptr || (p->type != IOREQ_TYPE_PIO) )
+    {
+        gdprintk(XENLOG_WARNING, "HVM_SPEAKER bad access\n");
         return 1;
     }
 
-    if (p->dir == 0) {/* write */
+    if ( p->dir == IOREQ_WRITE )
         speaker_ioport_write(vpit, p->addr, p->data);
-    } else if (p->dir == 1) {/* read */
+    else
         p->data = speaker_ioport_read(vpit, p->addr);
-    }
 
     return 1;
 }
@@ -576,7 +555,7 @@ int pv_pit_handler(int port, int data, i
         .data = write ? data : 0,
     };
 
-    if (port == 0x61)
+    if ( port == 0x61 )
         handle_speaker_io(&ioreq);
     else
         handle_pit_io(&ioreq);
diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/pmtimer.c
--- a/xen/arch/x86/hvm/pmtimer.c        Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/arch/x86/hvm/pmtimer.c        Fri Jun 15 13:33:11 2007 -0600
@@ -50,7 +50,6 @@
 #define TMR_VAL_MASK  (0xffffffff)
 #define TMR_VAL_MSB   (0x80000000)
 
-
 /* Dispatch SCIs based on the PM1a_STS and PM1a_EN registers */
 static void pmt_update_sci(PMTState *s)
 {
@@ -89,19 +88,19 @@ static void pmt_timer_callback(void *opa
     PMTState *s = opaque;
     uint32_t pmt_cycles_until_flip;
     uint64_t time_until_flip;
-    
+
     /* Recalculate the timer and make sure we get an SCI if we need one */
     pmt_update_time(s);
-    
+
     /* How close are we to the next MSB flip? */
     pmt_cycles_until_flip = TMR_VAL_MSB - (s->pm.tmr_val & (TMR_VAL_MSB - 1));
-    
+
     /* Overall time between MSB flips */
-    time_until_flip = (1000000000ULL << 31) / FREQUENCE_PMTIMER;
-    
+    time_until_flip = (1000000000ULL << 23) / FREQUENCE_PMTIMER;
+
     /* Reduced appropriately */
-    time_until_flip = (time_until_flip * pmt_cycles_until_flip) / (1ULL<<31);
-    
+    time_until_flip = (time_until_flip * pmt_cycles_until_flip) >> 23;
+
     /* Wake up again near the next bit-flip */
     set_timer(&s->timer, NOW() + time_until_flip + MILLISECS(1));
 }
diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/rtc.c
--- a/xen/arch/x86/hvm/rtc.c    Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/arch/x86/hvm/rtc.c    Fri Jun 15 13:33:11 2007 -0600
@@ -28,7 +28,11 @@
 #include <asm/hvm/support.h>
 #include <asm/current.h>
 
-/* #define DEBUG_RTC */
+#define domain_vrtc(d)   (&(d)->arch.hvm_domain.pl_time.vrtc)
+#define vcpu_vrtc(vcpu)  (domain_vrtc((vcpu)->domain))
+#define vrtc_domain(rtc) (container_of((rtc), struct domain, \
+                                       arch.hvm_domain.pl_time.vrtc))
+#define vrtc_vcpu(rtc)   (vrtc_domain(rtc)->vcpu[0])
 
 void rtc_periodic_cb(struct vcpu *v, void *opaque)
 {
@@ -41,31 +45,31 @@ int is_rtc_periodic_irq(void *opaque)
     RTCState *s = opaque;
 
     return !(s->hw.cmos_data[RTC_REG_C] & RTC_AF || 
-           s->hw.cmos_data[RTC_REG_C] & RTC_UF);
+             s->hw.cmos_data[RTC_REG_C] & RTC_UF);
 }
 
 /* Enable/configure/disable the periodic timer based on the RTC_PIE and
  * RTC_RATE_SELECT settings */
-static void rtc_timer_update(RTCState *s, struct vcpu *v)
-{
-    int period_code; 
-    int period;
+static void rtc_timer_update(RTCState *s)
+{
+    int period_code, period;
+    struct vcpu *v = vrtc_vcpu(s);
 
     period_code = s->hw.cmos_data[RTC_REG_A] & RTC_RATE_SELECT;
     if ( (period_code != 0) && (s->hw.cmos_data[RTC_REG_B] & RTC_PIE) )
     {
         if ( period_code <= 2 )
             period_code += 7;
-        
+
         period = 1 << (period_code - 1); /* period in 32 Khz cycles */
         period = DIV_ROUND((period * 1000000000ULL), 32768); /* period in ns */
-#ifdef DEBUG_RTC
-        printk("HVM_RTC: period = %uns\n", period);
-#endif
-        create_periodic_time(v, &s->pt, period, RTC_IRQ, 0, rtc_periodic_cb, 
s);
-    } 
-    else
+        create_periodic_time(v, &s->pt, period, RTC_IRQ,
+                             0, rtc_periodic_cb, s);
+    }
+    else
+    {
         destroy_periodic_time(&s->pt);
+    }
 }
 
 static void rtc_set_time(RTCState *s);
@@ -80,13 +84,8 @@ static int rtc_ioport_write(void *opaque
         return (s->hw.cmos_index < RTC_CMOS_SIZE);
     }
 
-    if (s->hw.cmos_index >= RTC_CMOS_SIZE)
+    if ( s->hw.cmos_index >= RTC_CMOS_SIZE )
         return 0;
-
-#ifdef DEBUG_RTC
-    printk("HVM_RTC: write index=0x%02x val=0x%02x\n",
-           s->hw.cmos_index, data);
-#endif
 
     switch ( s->hw.cmos_index )
     {
@@ -111,7 +110,7 @@ static int rtc_ioport_write(void *opaque
         /* UIP bit is read only */
         s->hw.cmos_data[RTC_REG_A] = (data & ~RTC_UIP) |
             (s->hw.cmos_data[RTC_REG_A] & RTC_UIP);
-        rtc_timer_update(s, current);
+        rtc_timer_update(s);
         break;
     case RTC_REG_B:
         if ( data & RTC_SET )
@@ -127,7 +126,7 @@ static int rtc_ioport_write(void *opaque
                 rtc_set_time(s);
         }
         s->hw.cmos_data[RTC_REG_B] = data;
-        rtc_timer_update(s, current);
+        rtc_timer_update(s);
         break;
     case RTC_REG_C:
     case RTC_REG_D:
@@ -181,10 +180,12 @@ static void rtc_copy_date(RTCState *s)
 static void rtc_copy_date(RTCState *s)
 {
     const struct tm *tm = &s->current_tm;
-
-    if (s->time_offset_seconds != s->pt.vcpu->domain->time_offset_seconds) {
-        s->current_tm = gmtime(get_localtime(s->pt.vcpu->domain));
-        s->time_offset_seconds = s->pt.vcpu->domain->time_offset_seconds;
+    struct domain *d = vrtc_domain(s);
+
+    if ( s->time_offset_seconds != d->time_offset_seconds )
+    {
+        s->current_tm = gmtime(get_localtime(d));
+        s->time_offset_seconds = d->time_offset_seconds;
     }
 
     s->hw.cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec);
@@ -228,34 +229,43 @@ static void rtc_next_second(RTCState *s)
 {
     struct tm *tm = &s->current_tm;
     int days_in_month;
-
-    if (s->time_offset_seconds != s->pt.vcpu->domain->time_offset_seconds) {
-        s->current_tm = gmtime(get_localtime(s->pt.vcpu->domain));
-        s->time_offset_seconds = s->pt.vcpu->domain->time_offset_seconds;
+    struct domain *d = vrtc_domain(s);
+
+    if ( s->time_offset_seconds != d->time_offset_seconds )
+    {
+        s->current_tm = gmtime(get_localtime(d));
+        s->time_offset_seconds = d->time_offset_seconds;
     }
 
     tm->tm_sec++;
-    if ((unsigned)tm->tm_sec >= 60) {
+    if ( (unsigned)tm->tm_sec >= 60 )
+    {
         tm->tm_sec = 0;
         tm->tm_min++;
-        if ((unsigned)tm->tm_min >= 60) {
+        if ( (unsigned)tm->tm_min >= 60 )
+        {
             tm->tm_min = 0;
             tm->tm_hour++;
-            if ((unsigned)tm->tm_hour >= 24) {
+            if ( (unsigned)tm->tm_hour >= 24 )
+            {
                 tm->tm_hour = 0;
                 /* next day */
                 tm->tm_wday++;
-                if ((unsigned)tm->tm_wday >= 7)
+                if ( (unsigned)tm->tm_wday >= 7 )
                     tm->tm_wday = 0;
                 days_in_month = get_days_in_month(tm->tm_mon, 
                                                   tm->tm_year + 1900);
                 tm->tm_mday++;
-                if (tm->tm_mday < 1) {
+                if ( tm->tm_mday < 1 )
+                {
                     tm->tm_mday = 1;
-                } else if (tm->tm_mday > days_in_month) {
+                }
+                else if ( tm->tm_mday > days_in_month )
+                {
                     tm->tm_mday = 1;
                     tm->tm_mon++;
-                    if (tm->tm_mon >= 12) {
+                    if ( tm->tm_mon >= 12 )
+                    {
                         tm->tm_mon = 0;
                         tm->tm_year++;
                     }
@@ -290,6 +300,7 @@ static void rtc_update_second2(void *opa
 static void rtc_update_second2(void *opaque)
 {
     RTCState *s = opaque;
+    struct domain *d = vrtc_domain(s);
 
     if ( !(s->hw.cmos_data[RTC_REG_B] & RTC_SET) )
         rtc_copy_date(s);
@@ -308,8 +319,8 @@ static void rtc_update_second2(void *opa
               s->current_tm.tm_hour) )
         {
             s->hw.cmos_data[RTC_REG_C] |= 0xa0; 
-            hvm_isa_irq_deassert(s->pt.vcpu->domain, RTC_IRQ);
-            hvm_isa_irq_assert(s->pt.vcpu->domain, RTC_IRQ);
+            hvm_isa_irq_deassert(d, RTC_IRQ);
+            hvm_isa_irq_assert(d, RTC_IRQ);
         }
     }
 
@@ -317,8 +328,8 @@ static void rtc_update_second2(void *opa
     if ( s->hw.cmos_data[RTC_REG_B] & RTC_UIE )
     {
         s->hw.cmos_data[RTC_REG_C] |= 0x90; 
-        hvm_isa_irq_deassert(s->pt.vcpu->domain, RTC_IRQ);
-        hvm_isa_irq_assert(s->pt.vcpu->domain, RTC_IRQ);
+        hvm_isa_irq_deassert(d, RTC_IRQ);
+        hvm_isa_irq_assert(d, RTC_IRQ);
     }
 
     /* clear update in progress bit */
@@ -352,39 +363,33 @@ static uint32_t rtc_ioport_read(void *op
         break;
     case RTC_REG_C:
         ret = s->hw.cmos_data[s->hw.cmos_index];
-        hvm_isa_irq_deassert(s->pt.vcpu->domain, RTC_IRQ);
-        s->hw.cmos_data[RTC_REG_C] = 0x00; 
+        hvm_isa_irq_deassert(vrtc_domain(s), RTC_IRQ);
+        s->hw.cmos_data[RTC_REG_C] = 0x00;
         break;
     default:
         ret = s->hw.cmos_data[s->hw.cmos_index];
         break;
     }
 
-#ifdef DEBUG_RTC
-    printk("HVM_RTC: read index=0x%02x val=0x%02x\n",
-           s->hw.cmos_index, ret);
-#endif
-
     return ret;
 }
 
 static int handle_rtc_io(ioreq_t *p)
 {
-    struct vcpu *v = current;
-    struct RTCState *vrtc = &v->domain->arch.hvm_domain.pl_time.vrtc;
+    struct RTCState *vrtc = vcpu_vrtc(current);
 
     if ( (p->size != 1) || p->data_is_ptr || (p->type != IOREQ_TYPE_PIO) )
     {
-        printk("HVM_RTC: wrong RTC IO!\n");
+        gdprintk(XENLOG_WARNING, "HVM_RTC bas access\n");
         return 1;
     }
     
-    if ( p->dir == 0 ) /* write */
+    if ( p->dir == IOREQ_WRITE )
     {
         if ( rtc_ioport_write(vrtc, p->addr, p->data & 0xFF) )
             return 1;
     }
-    else if ( (p->dir == 1) && (vrtc->hw.cmos_index < RTC_CMOS_SIZE) ) /* read 
*/
+    else if ( vrtc->hw.cmos_index < RTC_CMOS_SIZE )
     {
         p->data = rtc_ioport_read(vrtc, p->addr);
         return 1;
@@ -393,15 +398,12 @@ static int handle_rtc_io(ioreq_t *p)
     return 0;
 }
 
-/* Move the RTC timers on to this vcpu's current cpu */
 void rtc_migrate_timers(struct vcpu *v)
 {
-    RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc;
-
-    if ( s->pt.vcpu == v )
-    {
-        if ( s->pt.enabled )
-            migrate_timer(&s->pt.timer, v->processor);
+    RTCState *s = vcpu_vrtc(v);
+
+    if ( v->vcpu_id == 0 )
+    {
         migrate_timer(&s->second_timer, v->processor);
         migrate_timer(&s->second_timer2, v->processor);
     }
@@ -410,13 +412,14 @@ void rtc_migrate_timers(struct vcpu *v)
 /* Save RTC hardware state */
 static int rtc_save(struct domain *d, hvm_domain_context_t *h)
 {
-    return hvm_save_entry(RTC, 0, h, &d->arch.hvm_domain.pl_time.vrtc.hw);
+    RTCState *s = domain_vrtc(d);
+    return hvm_save_entry(RTC, 0, h, &s->hw);
 }
 
 /* Reload the hardware state from a saved domain */
 static int rtc_load(struct domain *d, hvm_domain_context_t *h)
 {
-    RTCState *s = &d->arch.hvm_domain.pl_time.vrtc;    
+    RTCState *s = domain_vrtc(d);
 
     /* Restore the registers */
     if ( hvm_load_entry(RTC, h, &s->hw) != 0 )
@@ -431,7 +434,7 @@ static int rtc_load(struct domain *d, hv
     set_timer(&s->second_timer2, s->next_second_time);
 
     /* Reset the periodic interrupt timer based on the registers */
-    rtc_timer_update(s, d->vcpu[0]);
+    rtc_timer_update(s);
 
     return 0;
 }
@@ -441,9 +444,8 @@ HVM_REGISTER_SAVE_RESTORE(RTC, rtc_save,
 
 void rtc_init(struct vcpu *v, int base)
 {
-    RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc;
-
-    s->pt.vcpu = v;
+    RTCState *s = vcpu_vrtc(v);
+
     s->hw.cmos_data[RTC_REG_A] = RTC_REF_CLCK_32KHZ | 6; /* ~1kHz */
     s->hw.cmos_data[RTC_REG_B] = RTC_24H;
     s->hw.cmos_data[RTC_REG_C] = 0;
@@ -452,7 +454,6 @@ void rtc_init(struct vcpu *v, int base)
     s->current_tm = gmtime(get_localtime(v->domain));
     rtc_copy_date(s);
 
-    init_timer(&s->pt.timer, pt_timer_fn, &s->pt, v->processor);
     init_timer(&s->second_timer, rtc_update_second, s, v->processor);
     init_timer(&s->second_timer2, rtc_update_second2, s, v->processor);
 
@@ -464,9 +465,9 @@ void rtc_init(struct vcpu *v, int base)
 
 void rtc_deinit(struct domain *d)
 {
-    RTCState *s = &d->arch.hvm_domain.pl_time.vrtc;
-
-    kill_timer(&s->pt.timer);
+    RTCState *s = domain_vrtc(d);
+
+    destroy_periodic_time(&s->pt);
     kill_timer(&s->second_timer);
     kill_timer(&s->second_timer2);
 }
diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c        Fri Jun 15 13:33:11 2007 -0600
@@ -2089,6 +2089,15 @@ static inline void svm_do_msr_access(
             msr_content = 1ULL << 61; /* MC4_MISC.Locked */
             break;
 
+        case MSR_IA32_EBC_FREQUENCY_ID:
+            /*
+             * This Intel-only register may be accessed if this HVM guest
+             * has been migrated from an Intel host. The value zero is not
+             * particularly meaningful, but at least avoids the guest crashing!
+             */
+            msr_content = 0;
+            break;
+
         default:
             if ( rdmsr_hypervisor_regs(ecx, &eax, &edx) ||
                  rdmsr_safe(ecx, eax, edx) == 0 )
diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/arch/x86/hvm/vlapic.c Fri Jun 15 13:33:11 2007 -0600
@@ -944,8 +944,6 @@ int vlapic_init(struct vcpu *v)
     if ( v->vcpu_id == 0 )
         vlapic->hw.apic_base_msr |= MSR_IA32_APICBASE_BSP;
 
-    init_timer(&vlapic->pt.timer, pt_timer_fn, &vlapic->pt, v->processor);
-
     return 0;
 }
 
@@ -953,7 +951,7 @@ void vlapic_destroy(struct vcpu *v)
 {
     struct vlapic *vlapic = vcpu_vlapic(v);
 
-    kill_timer(&vlapic->pt.timer);
+    destroy_periodic_time(&vlapic->pt);
     unmap_domain_page_global(vlapic->regs);
     free_domheap_page(vlapic->regs_page);
 }
diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/vmx/intr.c
--- a/xen/arch/x86/hvm/vmx/intr.c       Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/arch/x86/hvm/vmx/intr.c       Fri Jun 15 13:33:11 2007 -0600
@@ -1,6 +1,7 @@
 /*
- * io.c: handling I/O, interrupts related VMX entry/exit
+ * intr.c: handling I/O, interrupts related VMX entry/exit
  * Copyright (c) 2004, Intel Corporation.
+ * Copyright (c) 2004-2007, XenSource Inc.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -14,7 +15,6 @@
  * You should have received a copy of the GNU General Public License along with
  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
  */
 
 #include <xen/config.h>
@@ -24,7 +24,6 @@
 #include <xen/errno.h>
 #include <xen/trace.h>
 #include <xen/event.h>
-
 #include <asm/current.h>
 #include <asm/cpufeature.h>
 #include <asm/processor.h>
@@ -39,32 +38,48 @@
 #include <public/hvm/ioreq.h>
 #include <asm/hvm/trace.h>
 
+/*
+ * A few notes on virtual NMI and INTR delivery, and interactions with
+ * interruptibility states:
+ * 
+ * We can only inject an ExtInt if EFLAGS.IF = 1 and no blocking by
+ * STI nor MOV SS. Otherwise the VM entry fails. The 'virtual interrupt
+ * pending' control causes a VM exit when all these checks succeed. It will
+ * exit immediately after VM entry if the checks succeed at that point.
+ * 
+ * We can only inject an NMI if no blocking by MOV SS (also, depending on
+ * implementation, if no blocking by STI). If pin-based 'virtual NMIs'
+ * control is specified then the NMI-blocking interruptibility flag is
+ * also checked. The 'virtual NMI pending' control (available only in
+ * conjunction with 'virtual NMIs') causes a VM exit when all these checks
+ * succeed. It will exit immediately after VM entry if the checks succeed
+ * at that point.
+ * 
+ * Because a processor may or may not check blocking-by-STI when injecting
+ * a virtual NMI, it will be necessary to convert that to block-by-MOV-SS
+ * before specifying the 'virtual NMI pending' control. Otherwise we could
+ * enter an infinite loop where we check blocking-by-STI in software and
+ * thus delay delivery of a virtual NMI, but the processor causes immediate
+ * VM exit because it does not check blocking-by-STI.
+ * 
+ * Injecting a virtual NMI sets the NMI-blocking interruptibility flag only
+ * if the 'virtual NMIs' control is set. Injecting *any* kind of event clears
+ * the STI- and MOV-SS-blocking interruptibility-state flags.
+ * 
+ * If MOV/POP SS is executed while MOV-SS-blocking is in effect, the effect
+ * is cleared. If STI is executed while MOV-SS- or STI-blocking is in effect,
+ * the effect is cleared. (i.e., MOV-SS-blocking 'dominates' STI-blocking).
+ */
 
-static inline void
-enable_irq_window(struct vcpu *v)
+static void enable_irq_window(struct vcpu *v)
 {
     u32  *cpu_exec_control = &v->arch.hvm_vcpu.u.vmx.exec_control;
     
-    if (!(*cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING)) {
+    if ( !(*cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING) )
+    {
         *cpu_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
         __vmwrite(CPU_BASED_VM_EXEC_CONTROL, *cpu_exec_control);
     }
-}
-
-static inline void
-disable_irq_window(struct vcpu *v)
-{
-    u32  *cpu_exec_control = &v->arch.hvm_vcpu.u.vmx.exec_control;
-    
-    if ( *cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING ) {
-        *cpu_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
-        __vmwrite(CPU_BASED_VM_EXEC_CONTROL, *cpu_exec_control);
-    }
-}
-
-static inline int is_interruptibility_state(void)
-{
-    return __vmread(GUEST_INTERRUPTIBILITY_INFO);
 }
 
 static void update_tpr_threshold(struct vlapic *vlapic)
@@ -87,13 +102,11 @@ static void update_tpr_threshold(struct 
 
 asmlinkage void vmx_intr_assist(void)
 {
-    int intr_type = 0;
-    int intr_vector;
-    unsigned long eflags;
+    int has_ext_irq, intr_vector, intr_type = 0;
+    unsigned long eflags, intr_shadow;
     struct vcpu *v = current;
     unsigned int idtv_info_field;
     unsigned long inst_len;
-    int    has_ext_irq;
 
     pt_update_irq(v);
 
@@ -125,10 +138,10 @@ asmlinkage void vmx_intr_assist(void)
         inst_len = __vmread(VM_EXIT_INSTRUCTION_LEN); /* Safe */
         __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inst_len);
 
-        if (unlikely(idtv_info_field & 0x800)) /* valid error code */
+        if ( unlikely(idtv_info_field & 0x800) ) /* valid error code */
             __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE,
                       __vmread(IDT_VECTORING_ERROR_CODE));
-        if (unlikely(has_ext_irq))
+        if ( unlikely(has_ext_irq) )
             enable_irq_window(v);
 
         HVM_DBG_LOG(DBG_LEVEL_1, "idtv_info_field=%x", idtv_info_field);
@@ -138,9 +151,9 @@ asmlinkage void vmx_intr_assist(void)
     if ( likely(!has_ext_irq) )
         return;
 
-    if ( unlikely(is_interruptibility_state()) )
+    intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO);
+    if ( unlikely(intr_shadow & (VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS)) )
     {
-        /* pre-cleared for emulated instruction */
         enable_irq_window(v);
         HVM_DBG_LOG(DBG_LEVEL_1, "interruptibility");
         return;
diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Fri Jun 15 13:33:11 2007 -0600
@@ -70,8 +70,9 @@ void vmx_init_vmcs_config(void)
     u32 _vmx_vmexit_control;
     u32 _vmx_vmentry_control;
 
-    min = PIN_BASED_EXT_INTR_MASK | PIN_BASED_NMI_EXITING;
-    opt = 0;
+    min = (PIN_BASED_EXT_INTR_MASK |
+           PIN_BASED_NMI_EXITING);
+    opt = 0; /*PIN_BASED_VIRTUAL_NMIS*/
     _vmx_pin_based_exec_control = adjust_vmx_controls(
         min, opt, MSR_IA32_VMX_PINBASED_CTLS);
 
diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Fri Jun 15 13:33:11 2007 -0600
@@ -1300,11 +1300,17 @@ static int __get_instruction_length(void
 
 static void inline __update_guest_eip(unsigned long inst_len)
 {
-    unsigned long current_eip;
+    unsigned long current_eip, intr_shadow;
 
     current_eip = __vmread(GUEST_RIP);
     __vmwrite(GUEST_RIP, current_eip + inst_len);
-    __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
+
+    intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO);
+    if ( intr_shadow & (VMX_INTR_SHADOW_STI | VMX_INTR_SHADOW_MOV_SS) )
+    {
+        intr_shadow &= ~(VMX_INTR_SHADOW_STI | VMX_INTR_SHADOW_MOV_SS);
+        __vmwrite(GUEST_INTERRUPTIBILITY_INFO, intr_shadow);
+    }
 }
 
 static void vmx_do_no_device_fault(void)
@@ -2902,9 +2908,15 @@ asmlinkage void vmx_vmexit_handler(struc
     case EXIT_REASON_TRIPLE_FAULT:
         hvm_triple_fault();
         break;
-    case EXIT_REASON_PENDING_INTERRUPT:
+    case EXIT_REASON_PENDING_VIRT_INTR:
         /* Disable the interrupt window. */
         v->arch.hvm_vcpu.u.vmx.exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
+        __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
+                  v->arch.hvm_vcpu.u.vmx.exec_control);
+        break;
+    case EXIT_REASON_PENDING_VIRT_NMI:
+        /* Disable the NMI window. */
+        v->arch.hvm_vcpu.u.vmx.exec_control &= ~CPU_BASED_VIRTUAL_NMI_PENDING;
         __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
                   v->arch.hvm_vcpu.u.vmx.exec_control);
         break;
diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/hvm/vpt.c
--- a/xen/arch/x86/hvm/vpt.c    Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/arch/x86/hvm/vpt.c    Fri Jun 15 13:33:11 2007 -0600
@@ -22,31 +22,31 @@
 #include <asm/hvm/vpt.h>
 #include <asm/event.h>
 
-static __inline__ void missed_ticks(struct periodic_time *pt)
+static void missed_ticks(struct periodic_time *pt)
 {
     s_time_t missed_ticks;
 
     missed_ticks = NOW() - pt->scheduled;
-    if ( missed_ticks > 0 ) 
-    {
-        missed_ticks = missed_ticks / (s_time_t) pt->period + 1;
-        if ( missed_ticks > 1000 )
-        {
-            /* TODO: Adjust guest time together */
-            pt->pending_intr_nr++;
-        }
-        else
-        {
-            pt->pending_intr_nr += missed_ticks;
-        }
-        pt->scheduled += missed_ticks * pt->period;
-    }
+    if ( missed_ticks <= 0 )
+        return;
+
+    missed_ticks = missed_ticks / (s_time_t) pt->period + 1;
+    if ( missed_ticks > 1000 )
+    {
+        /* TODO: Adjust guest time together */
+        pt->pending_intr_nr++;
+    }
+    else
+    {
+        pt->pending_intr_nr += missed_ticks;
+    }
+
+    pt->scheduled += missed_ticks * pt->period;
 }
 
 void pt_freeze_time(struct vcpu *v)
 {
     struct list_head *head = &v->arch.hvm_vcpu.tm_list;
-    struct list_head *list;
     struct periodic_time *pt;
 
     if ( test_bit(_VPF_blocked, &v->pause_flags) )
@@ -54,17 +54,13 @@ void pt_freeze_time(struct vcpu *v)
 
     v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v);
 
-    list_for_each( list, head )
-    {
-        pt = list_entry(list, struct periodic_time, list);
+    list_for_each_entry ( pt, head, list )
         stop_timer(&pt->timer);
-    }
 }
 
 void pt_thaw_time(struct vcpu *v)
 {
     struct list_head *head = &v->arch.hvm_vcpu.tm_list;
-    struct list_head *list;
     struct periodic_time *pt;
 
     if ( v->arch.hvm_vcpu.guest_time )
@@ -72,17 +68,15 @@ void pt_thaw_time(struct vcpu *v)
         hvm_set_guest_time(v, v->arch.hvm_vcpu.guest_time);
         v->arch.hvm_vcpu.guest_time = 0;
 
-        list_for_each( list, head )
-        {
-            pt = list_entry(list, struct periodic_time, list);
+        list_for_each_entry ( pt, head, list )
+        {
             missed_ticks(pt);
             set_timer(&pt->timer, pt->scheduled);
         }
     }
 }
 
-/* Hook function for the platform periodic time */
-void pt_timer_fn(void *data)
+static void pt_timer_fn(void *data)
 {
     struct periodic_time *pt = data;
 
@@ -100,14 +94,12 @@ void pt_update_irq(struct vcpu *v)
 void pt_update_irq(struct vcpu *v)
 {
     struct list_head *head = &v->arch.hvm_vcpu.tm_list;
-    struct list_head *list;
     struct periodic_time *pt;
     uint64_t max_lag = -1ULL;
     int irq = -1;
 
-    list_for_each( list, head )
-    {
-        pt = list_entry(list, struct periodic_time, list);
+    list_for_each_entry ( pt, head, list )
+    {
         if ( !is_isa_irq_masked(v, pt->irq) && pt->pending_intr_nr &&
              ((pt->last_plt_gtime + pt->period_cycles) < max_lag) )
         {
@@ -130,14 +122,12 @@ struct periodic_time *is_pt_irq(struct v
 struct periodic_time *is_pt_irq(struct vcpu *v, int vector, int type)
 {
     struct list_head *head = &v->arch.hvm_vcpu.tm_list;
-    struct list_head *list;
     struct periodic_time *pt;
     struct RTCState *rtc = &v->domain->arch.hvm_domain.pl_time.vrtc;
     int vec;
 
-    list_for_each( list, head )
-    {
-        pt = list_entry(list, struct periodic_time, list);
+    list_for_each_entry ( pt, head, list )
+    {
         if ( !pt->pending_intr_nr )
             continue;
 
@@ -177,17 +167,14 @@ void pt_intr_post(struct vcpu *v, int ve
         pt->cb(pt->vcpu, pt->priv);
 }
 
-/* If pt is enabled, discard pending intr */
 void pt_reset(struct vcpu *v)
 {
     struct list_head *head = &v->arch.hvm_vcpu.tm_list;
-    struct list_head *list;
-    struct periodic_time *pt;
-
-    list_for_each( list, head )
-    {
-       pt = list_entry(list, struct periodic_time, list);
-       if ( pt->enabled )
+    struct periodic_time *pt;
+
+    list_for_each_entry ( pt, head, list )
+    {
+        if ( pt->enabled )
         {
             pt->pending_intr_nr = 0;
             pt->last_plt_gtime = hvm_get_guest_time(pt->vcpu);
@@ -197,11 +184,25 @@ void pt_reset(struct vcpu *v)
     }
 }
 
-void create_periodic_time(struct vcpu *v, struct periodic_time *pt, uint64_t 
period,
-                          uint8_t irq, char one_shot, time_cb *cb, void *data)
+void pt_migrate(struct vcpu *v)
+{
+    struct list_head *head = &v->arch.hvm_vcpu.tm_list;
+    struct periodic_time *pt;
+
+    list_for_each_entry ( pt, head, list )
+    {
+        if ( pt->enabled )
+            migrate_timer(&pt->timer, v->processor);
+    }
+}
+
+void create_periodic_time(
+    struct vcpu *v, struct periodic_time *pt, uint64_t period,
+    uint8_t irq, char one_shot, time_cb *cb, void *data)
 {
     destroy_periodic_time(pt);
 
+    init_timer(&pt->timer, pt_timer_fn, pt, v->processor);
     pt->enabled = 1;
     if ( period < 900000 ) /* < 0.9 ms */
     {
@@ -226,11 +227,11 @@ void create_periodic_time(struct vcpu *v
 
 void destroy_periodic_time(struct periodic_time *pt)
 {
-    if ( pt->enabled )
-    {
-        pt->enabled = 0;
-        pt->pending_intr_nr = 0;
-        list_del(&pt->list);
-        stop_timer(&pt->timer);
-    }
-}
+    if ( !pt->enabled )
+        return;
+
+    pt->enabled = 0;
+    pt->pending_intr_nr = 0;
+    list_del(&pt->list);
+    kill_timer(&pt->timer);
+}
diff -r fe42519fb10e -r 3b51eebdf9ab xen/arch/x86/io_apic.c
--- a/xen/arch/x86/io_apic.c    Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/arch/x86/io_apic.c    Fri Jun 15 13:33:11 2007 -0600
@@ -2114,6 +2114,15 @@ int ioapic_guest_write(unsigned long phy
         return 0;
     }
 
+    /* Special delivery modes (SMI,NMI,INIT,ExtInt) should have no vector.  */
+    if ( (old_rte.delivery_mode > dest_LowestPrio) && (old_rte.vector != 0) )
+    {
+        WARN_BOGUS_WRITE("Special delivery mode %d with non-zero vector "
+                         "%02x\n", old_rte.delivery_mode, old_rte.vector);
+        /* Nobble the vector here as it does not relate to a valid irq. */
+        old_rte.vector = 0;
+    }
+
     if ( old_rte.vector >= FIRST_DYNAMIC_VECTOR )
         old_irq = vector_irq[old_rte.vector];
     if ( new_rte.vector >= FIRST_DYNAMIC_VECTOR )
diff -r fe42519fb10e -r 3b51eebdf9ab xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Fri Jun 15 13:33:11 2007 -0600
@@ -104,6 +104,7 @@ void vmx_vmcs_exit(struct vcpu *v);
 #define CPU_BASED_CR8_LOAD_EXITING            0x00080000
 #define CPU_BASED_CR8_STORE_EXITING           0x00100000
 #define CPU_BASED_TPR_SHADOW                  0x00200000
+#define CPU_BASED_VIRTUAL_NMI_PENDING         0x00400000
 #define CPU_BASED_MOV_DR_EXITING              0x00800000
 #define CPU_BASED_UNCOND_IO_EXITING           0x01000000
 #define CPU_BASED_ACTIVATE_IO_BITMAP          0x02000000
@@ -115,6 +116,7 @@ extern u32 vmx_cpu_based_exec_control;
 
 #define PIN_BASED_EXT_INTR_MASK         0x00000001
 #define PIN_BASED_NMI_EXITING           0x00000008
+#define PIN_BASED_VIRTUAL_NMIS          0x00000020
 extern u32 vmx_pin_based_exec_control;
 
 #define VM_EXIT_IA32E_MODE              0x00000200
@@ -137,7 +139,13 @@ extern u32 vmx_secondary_exec_control;
     (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_MSR_BITMAP)
 extern char *vmx_msr_bitmap;
 
-/* VMCS Encordings */
+/* GUEST_INTERRUPTIBILITY_INFO flags. */
+#define VMX_INTR_SHADOW_STI             0x00000001
+#define VMX_INTR_SHADOW_MOV_SS          0x00000002
+#define VMX_INTR_SHADOW_SMI             0x00000004
+#define VMX_INTR_SHADOW_NMI             0x00000008
+
+/* VMCS field encodings. */
 enum vmcs_field {
     GUEST_ES_SELECTOR               = 0x00000800,
     GUEST_CS_SELECTOR               = 0x00000802,
diff -r fe42519fb10e -r 3b51eebdf9ab xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Fri Jun 15 13:33:11 2007 -0600
@@ -46,8 +46,8 @@ void vmx_vlapic_msr_changed(struct vcpu 
 #define EXIT_REASON_SIPI                4
 #define EXIT_REASON_IO_SMI              5
 #define EXIT_REASON_OTHER_SMI           6
-#define EXIT_REASON_PENDING_INTERRUPT   7
-
+#define EXIT_REASON_PENDING_VIRT_INTR   7
+#define EXIT_REASON_PENDING_VIRT_NMI    8
 #define EXIT_REASON_TASK_SWITCH         9
 #define EXIT_REASON_CPUID               10
 #define EXIT_REASON_HLT                 12
@@ -295,7 +295,14 @@ static inline void __vmx_inject_exceptio
 {
     unsigned long intr_fields;
 
-    /* Reflect it back into the guest */
+    /*
+     * NB. Callers do not need to worry about clearing STI/MOV-SS blocking:
+     *  "If the VM entry is injecting, there is no blocking by STI or by
+     *   MOV SS following the VM entry, regardless of the contents of the
+     *   interruptibility-state field [in the guest-state area before the
+     *   VM entry]", PRM Vol. 3, 22.6.1 (Interruptibility State).
+     */
+
     intr_fields = (INTR_INFO_VALID_MASK | type | trap);
     if ( error_code != VMX_DELIVER_NO_ERROR_CODE ) {
         __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
@@ -332,7 +339,6 @@ static inline void vmx_inject_extint(str
 static inline void vmx_inject_extint(struct vcpu *v, int trap, int error_code)
 {
     __vmx_inject_exception(v, trap, INTR_TYPE_EXT_INTR, error_code, 0);
-    __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
 }
 
 #endif /* __ASM_X86_HVM_VMX_VMX_H__ */
diff -r fe42519fb10e -r 3b51eebdf9ab xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h     Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/include/asm-x86/hvm/vpt.h     Fri Jun 15 13:33:11 2007 -0600
@@ -115,19 +115,19 @@ struct pl_time {    /* platform time */
 
 void pt_freeze_time(struct vcpu *v);
 void pt_thaw_time(struct vcpu *v);
-void pt_timer_fn(void *data);
 void pt_update_irq(struct vcpu *v);
 struct periodic_time *is_pt_irq(struct vcpu *v, int vector, int type);
 void pt_intr_post(struct vcpu *v, int vector, int type);
 void pt_reset(struct vcpu *v);
-void create_periodic_time(struct vcpu *v, struct periodic_time *pt, uint64_t 
period,
-                          uint8_t irq, char one_shot, time_cb *cb, void *data);
+void pt_migrate(struct vcpu *v);
+void create_periodic_time(
+    struct vcpu *v, struct periodic_time *pt, uint64_t period,
+    uint8_t irq, char one_shot, time_cb *cb, void *data);
 void destroy_periodic_time(struct periodic_time *pt);
 
 int pv_pit_handler(int port, int data, int write);
 void pit_init(struct vcpu *v, unsigned long cpu_khz);
 void pit_stop_channel0_irq(PITState * pit);
-void pit_migrate_timers(struct vcpu *v);
 void pit_deinit(struct domain *d);
 void rtc_init(struct vcpu *v, int base);
 void rtc_migrate_timers(struct vcpu *v);
diff -r fe42519fb10e -r 3b51eebdf9ab xen/include/asm-x86/msr.h
--- a/xen/include/asm-x86/msr.h Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/include/asm-x86/msr.h Fri Jun 15 13:33:11 2007 -0600
@@ -96,6 +96,7 @@ static inline void wrmsrl(unsigned int m
 #define MSR_IA32_TIME_STAMP_COUNTER     0x10
 #define MSR_IA32_PLATFORM_ID           0x17
 #define MSR_IA32_EBL_CR_POWERON                0x2a
+#define MSR_IA32_EBC_FREQUENCY_ID      0x2c
 
 #define MSR_IA32_APICBASE              0x1b
 #define MSR_IA32_APICBASE_BSP          (1<<8)
diff -r fe42519fb10e -r 3b51eebdf9ab xen/include/public/io/ring.h
--- a/xen/include/public/io/ring.h      Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/include/public/io/ring.h      Fri Jun 15 13:33:11 2007 -0600
@@ -133,7 +133,7 @@ typedef struct __name##_back_ring __name
 #define SHARED_RING_INIT(_s) do {                                       \
     (_s)->req_prod  = (_s)->rsp_prod  = 0;                              \
     (_s)->req_event = (_s)->rsp_event = 1;                              \
-    memset((_s)->pad, 0, sizeof((_s)->pad));                            \
+    (void)memset((_s)->pad, 0, sizeof((_s)->pad));                      \
 } while(0)
 
 #define FRONT_RING_INIT(_r, _s, __size) do {                            \
diff -r fe42519fb10e -r 3b51eebdf9ab xen/include/public/io/xs_wire.h
--- a/xen/include/public/io/xs_wire.h   Fri Jun 15 12:38:35 2007 -0600
+++ b/xen/include/public/io/xs_wire.h   Fri Jun 15 13:33:11 2007 -0600
@@ -60,7 +60,11 @@ struct xsd_errors
     const char *errstring;
 };
 #define XSD_ERROR(x) { x, #x }
-static struct xsd_errors xsd_errors[] __attribute__((unused)) = {
+static struct xsd_errors xsd_errors[]
+#if defined(__GNUC__)
+__attribute__((unused))
+#endif
+    = {
     XSD_ERROR(EINVAL),
     XSD_ERROR(EACCES),
     XSD_ERROR(EEXIST),

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.