WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sat, 16 Jun 2007 05:57:11 -0700
Delivery-date: Sat, 16 Jun 2007 05:55:44 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>