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 (staging)

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-unstable.hg (staging)
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 04 Oct 2007 17:41:33 -0700
Delivery-date: Thu, 04 Oct 2007 18:47:10 -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 1191346315 21600
# Node ID 3165e43ce73421bf6308844a3d0d4f27dab47639
# Parent  d6c09be8c5f53e327f401a7062a1e95d2d2a1ed4
# Parent  385b9b6bb61f076d06bbffba2ef3bf667428168c
merge with xen-unstable.hg (staging)
---
 tools/examples/external-device-migrate   |   11 +-
 tools/flask/libflask/Makefile            |    2 
 tools/flask/libflask/include/flask_op.h  |    2 
 tools/flask/loadpolicy/Makefile          |   11 --
 tools/ioemu/vl.c                         |    2 
 tools/libxc/xc_hvm_build.c               |   76 +++-----------
 tools/libxc/xc_private.c                 |    6 -
 tools/python/xen/util/xsm/acm/acm.py     |    2 
 tools/python/xen/xend/XendDomain.py      |   26 ----
 tools/python/xen/xend/XendDomainInfo.py  |   10 +
 tools/xenstat/xentop/xentop.c            |   32 ++++--
 tools/xentrace/xenctx.c                  |   55 +++++++++-
 tools/xentrace/xentrace.8                |    2 
 tools/xentrace/xentrace_format           |   91 +++++++++++++----
 tools/xm-test/configure.ac               |    4 
 tools/xm-test/lib/XmTestLib/NetConfig.py |    2 
 xen/arch/x86/domain.c                    |  162 +++++++++++++++----------------
 xen/arch/x86/hvm/hvm.c                   |   16 ++-
 xen/arch/x86/hvm/irq.c                   |   84 +++++++++-------
 xen/arch/x86/hvm/svm/intr.c              |   91 +++++------------
 xen/arch/x86/hvm/svm/svm.c               |  117 +++++++---------------
 xen/arch/x86/hvm/svm/vmcb.c              |    9 -
 xen/arch/x86/hvm/vlapic.c                |   31 +++--
 xen/arch/x86/hvm/vmx/intr.c              |  109 ++++++++------------
 xen/arch/x86/hvm/vmx/vmx.c               |   34 ++++--
 xen/arch/x86/hvm/vmx/vtd/intel-iommu.c   |   14 +-
 xen/arch/x86/hvm/vmx/vtd/io.c            |   83 +++++++++------
 xen/arch/x86/hvm/vpic.c                  |    2 
 xen/arch/x86/hvm/vpt.c                   |   15 +-
 xen/arch/x86/platform_hypercall.c        |   47 +++++++-
 xen/arch/x86/time.c                      |    2 
 xen/arch/x86/traps.c                     |    2 
 xen/arch/x86/x86_32/domain_page.c        |  107 ++++++++++----------
 xen/arch/x86/x86_32/entry.S              |    2 
 xen/arch/x86/x86_64/entry.S              |    2 
 xen/common/sysctl.c                      |   12 --
 xen/include/asm-x86/domain.h             |   36 ++++--
 xen/include/asm-x86/hvm/hvm.h            |   33 ++++--
 xen/include/asm-x86/hvm/irq.h            |   24 ++--
 xen/include/asm-x86/hvm/vlapic.h         |    4 
 xen/include/asm-x86/hvm/vpic.h           |    2 
 xen/include/asm-x86/hvm/vpt.h            |    2 
 xen/include/public/platform.h            |   14 ++
 43 files changed, 744 insertions(+), 646 deletions(-)

diff -r d6c09be8c5f5 -r 3165e43ce734 tools/examples/external-device-migrate
--- a/tools/examples/external-device-migrate    Tue Oct 02 10:07:35 2007 -0600
+++ b/tools/examples/external-device-migrate    Tue Oct 02 11:31:55 2007 -0600
@@ -16,6 +16,7 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #
 
+set -x
 
 # This script is called by XenD for migration of external devices
 # It does not handle the migration of those devices itself, but
@@ -57,11 +58,11 @@ function evaluate_params()
        stype=""
        while [ $# -ge 1 ]; do
                case "$1" in
-               -step)          step=$2; shift 2;;
-               -host)          host=$2; shift 2;;
-               -domname)       domname=$2; shift 2;;
-               -type)          typ=$2; shift 2;;
-               -subtype)       stype=$2; shift 2;;
+               -step)          step=$2; shift; shift;;
+               -host)          host=$2; shift; shift;;
+               -domname)       domname=$2; shift; shift;;
+               -type)          typ=$2; shift; shift;;
+               -subtype)       stype=$2; shift; shift;;
                -recover)       recover=1; shift;;
                -help)          ext_dev_migrate_usage; exit 0;;
                *)              break;;
diff -r d6c09be8c5f5 -r 3165e43ce734 tools/flask/libflask/Makefile
--- a/tools/flask/libflask/Makefile     Tue Oct 02 10:07:35 2007 -0600
+++ b/tools/flask/libflask/Makefile     Tue Oct 02 11:31:55 2007 -0600
@@ -60,6 +60,6 @@ libflask.so.$(MAJOR): libflask.so.$(MAJO
        ln -sf $< $@
 
 libflask.so.$(MAJOR).$(MINOR): $(PIC_OBJS)
-       $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libflask.so.$(MAJOR) -shared 
-o $@ $^
+       $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) 
-Wl,libflask.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^
 
 -include $(DEPS)
diff -r d6c09be8c5f5 -r 3165e43ce734 tools/flask/libflask/include/flask_op.h
--- a/tools/flask/libflask/include/flask_op.h   Tue Oct 02 10:07:35 2007 -0600
+++ b/tools/flask/libflask/include/flask_op.h   Tue Oct 02 11:31:55 2007 -0600
@@ -39,7 +39,7 @@ typedef struct flask_op {
 } flask_op_t;
 
 int flask_load(int xc_handle, char *buf, int size);
-int flask_context_to_sid(int xc_handle, char *buf, int size, u_int32_t *sid);
+int flask_context_to_sid(int xc_handle, char *buf, int size, uint32_t *sid);
 int flask_sid_to_context(int xc_handle, int sid, char *buf, int size);
 int do_flask_op(int xc_handle, flask_op_t *op);
 
diff -r d6c09be8c5f5 -r 3165e43ce734 tools/flask/loadpolicy/Makefile
--- a/tools/flask/loadpolicy/Makefile   Tue Oct 02 10:07:35 2007 -0600
+++ b/tools/flask/loadpolicy/Makefile   Tue Oct 02 11:31:55 2007 -0600
@@ -1,11 +1,6 @@ XEN_ROOT=../../..
 XEN_ROOT=../../..
 include $(XEN_ROOT)/tools/Rules.mk
 XEN_LIBXC          = $(XEN_ROOT)/tools/libxc
-
-INSTALL         = install
-INSTALL_DATA    = $(INSTALL) -m0644
-INSTALL_PROG    = $(INSTALL) -m0755
-INSTALL_DIR     = $(INSTALL) -d -m0755
 
 LIBXC_ROOT = $(XEN_ROOT)/tools/libxc
 LIBFLASK_ROOT = $(XEN_ROOT)/tools/flask/libflask
@@ -28,13 +23,17 @@ TESTENV  = XENSTORED_ROOTDIR=$(TESTDIR) 
 TESTENV  = XENSTORED_ROOTDIR=$(TESTDIR) XENSTORED_RUNDIR=$(TESTDIR)
 
 CLIENTS := flask-loadpolicy
+CLIENTS_SRCS := $(patsubst flask-%,%.c,$(CLIENTS))
 CLIENTS_OBJS := $(patsubst flask-%,%.o,$(CLIENTS))
 
 .PHONY: all
 all: $(CLIENTS)
 
 $(CLIENTS): flask-%: %.o
-       $(LINK.o) $< $(LOADLIBES) $(LDLIBS) -L. -lflask -lxenctrl -o $@
+       $(CC) $(CFLAGS) $(LDFLAGS) $< $(LOADLIBES) $(LDLIBS) -L. -lflask 
-lxenctrl -o $@
+
+$(CLIENTS_OBJS): $(CLIENTS_SRCS)
+       $(COMPILE.c) -o $@ $<
 
 .PHONY: clean
 clean: 
diff -r d6c09be8c5f5 -r 3165e43ce734 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Tue Oct 02 10:07:35 2007 -0600
+++ b/tools/ioemu/vl.c  Tue Oct 02 11:31:55 2007 -0600
@@ -7102,6 +7102,7 @@ int main(int argc, char **argv)
     char qemu_dm_logfilename[128];
     const char *direct_pci = NULL;
 
+#ifndef __sun__
     /* Maximise rlimits. Needed where default constraints are tight (*BSD). */
     if (getrlimit(RLIMIT_STACK, &rl) != 0) {
        perror("getrlimit(RLIMIT_STACK)");
@@ -7125,6 +7126,7 @@ int main(int argc, char **argv)
     rl.rlim_max = RLIM_INFINITY;
     if (setrlimit(RLIMIT_MEMLOCK, &rl) != 0)
        perror("setrlimit(RLIMIT_MEMLOCK)");
+#endif
 
     /* Ensure that SIGUSR2 is blocked by default when a new thread is created,
        then only the threads that use the signal unblock it -- this fixes a
diff -r d6c09be8c5f5 -r 3165e43ce734 tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c        Tue Oct 02 10:07:35 2007 -0600
+++ b/tools/libxc/xc_hvm_build.c        Tue Oct 02 11:31:55 2007 -0600
@@ -20,14 +20,6 @@
 #include <xen/libelf.h>
 
 #define SCRATCH_PFN 0xFFFFF
-
-/* Need to provide the right flavour of vcpu context for Xen */
-typedef union
-{
-    vcpu_guest_context_x86_64_t c64;
-    vcpu_guest_context_x86_32_t c32;   
-    vcpu_guest_context_t c;
-} vcpu_guest_context_either_t;
 
 static void build_e820map(void *e820_page, unsigned long long mem_size)
 {
@@ -154,12 +146,11 @@ static int loadelfimage(
 
 static int setup_guest(int xc_handle,
                        uint32_t dom, int memsize,
-                       char *image, unsigned long image_size,
-                       vcpu_guest_context_either_t *ctxt)
+                       char *image, unsigned long image_size)
 {
     xen_pfn_t *page_array = NULL;
     unsigned long i, nr_pages = (unsigned long)memsize << (20 - PAGE_SHIFT);
-    unsigned long shared_page_nr;
+    unsigned long shared_page_nr, entry_eip;
     struct xen_add_to_physmap xatp;
     struct shared_info *shared_info;
     void *e820_page;
@@ -263,20 +254,20 @@ static int setup_guest(int xc_handle,
     xc_set_hvm_param(xc_handle, dom, HVM_PARAM_BUFIOREQ_PFN, shared_page_nr-2);
     xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN, shared_page_nr);
 
+    /* Insert JMP <rel32> instruction at address 0x0 to reach entry point. */
+    entry_eip = elf_uval(&elf, elf.ehdr, e_entry);
+    if ( entry_eip != 0 )
+    {
+        char *page0 = xc_map_foreign_range(
+            xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, 0);
+        if ( page0 == NULL )
+            goto error_out;
+        page0[0] = 0xe9;
+        *(uint32_t *)&page0[1] = entry_eip - 5;
+        munmap(page0, PAGE_SIZE);
+    }
+
     free(page_array);
-
-    /* Set [er]ip in the way that's right for Xen */
-    if ( strstr(caps, "x86_64") )
-    {
-        ctxt->c64.user_regs.rip = elf_uval(&elf, elf.ehdr, e_entry); 
-        ctxt->c64.flags = VGCF_online;
-    }
-    else
-    {
-        ctxt->c32.user_regs.eip = elf_uval(&elf, elf.ehdr, e_entry);
-        ctxt->c32.flags = VGCF_online;
-    }
-
     return 0;
 
  error_out:
@@ -290,42 +281,13 @@ static int xc_hvm_build_internal(int xc_
                                  char *image,
                                  unsigned long image_size)
 {
-    struct xen_domctl launch_domctl;
-    vcpu_guest_context_either_t ctxt;
-    int rc;
-
     if ( (image == NULL) || (image_size == 0) )
     {
         ERROR("Image required");
-        goto error_out;
-    }
-
-    memset(&ctxt, 0, sizeof(ctxt));
-
-    if ( setup_guest(xc_handle, domid, memsize, image, image_size, &ctxt) < 0 )
-    {
-        goto error_out;
-    }
-
-    if ( lock_pages(&ctxt, sizeof(ctxt) ) )
-    {
-        PERROR("%s: ctxt mlock failed", __func__);
-        goto error_out;
-    }
-
-    memset(&launch_domctl, 0, sizeof(launch_domctl));
-    launch_domctl.domain = (domid_t)domid;
-    launch_domctl.u.vcpucontext.vcpu = 0;
-    set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, &ctxt.c);
-    launch_domctl.cmd = XEN_DOMCTL_setvcpucontext;
-    rc = xc_domctl(xc_handle, &launch_domctl);
-
-    unlock_pages(&ctxt, sizeof(ctxt));
-
-    return rc;
-
- error_out:
-    return -1;
+        return -1;
+    }
+
+    return setup_guest(xc_handle, domid, memsize, image, image_size);
 }
 
 static inline int is_loadable_phdr(Elf32_Phdr *phdr)
diff -r d6c09be8c5f5 -r 3165e43ce734 tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c  Tue Oct 02 10:07:35 2007 -0600
+++ b/tools/libxc/xc_private.c  Tue Oct 02 11:31:55 2007 -0600
@@ -130,7 +130,8 @@ int lock_pages(void *addr, size_t len)
       int e = 0;
 #ifndef __sun__
       void *laddr = (void *)((unsigned long)addr & PAGE_MASK);
-      size_t llen = (len + PAGE_SIZE - 1) & PAGE_MASK;
+      size_t llen = (len + ((unsigned long)addr - (unsigned long)laddr) +
+                     PAGE_SIZE - 1) & PAGE_MASK;
       e = mlock(laddr, llen);
 #endif
       return e;
@@ -140,7 +141,8 @@ void unlock_pages(void *addr, size_t len
 {
 #ifndef __sun__
     void *laddr = (void *)((unsigned long)addr & PAGE_MASK);
-    size_t llen = (len + PAGE_SIZE - 1) & PAGE_MASK;
+    size_t llen = (len + ((unsigned long)addr - (unsigned long)laddr) +
+                   PAGE_SIZE - 1) & PAGE_MASK;
     safe_munlock(laddr, llen);
 #endif
 }
diff -r d6c09be8c5f5 -r 3165e43ce734 tools/python/xen/util/xsm/acm/acm.py
--- a/tools/python/xen/util/xsm/acm/acm.py      Tue Oct 02 10:07:35 2007 -0600
+++ b/tools/python/xen/util/xsm/acm/acm.py      Tue Oct 02 11:31:55 2007 -0600
@@ -1309,7 +1309,7 @@ def parse_security_label(security_label)
         return security_label
 
 def set_security_label(policy, label):
-    if label != "" and policy != "":
+    if label and policy and label != "" and policy != "":
         return "%s:%s:%s" % (xsconstants.ACM_POLICY_ID, policy, label)
     else:
         return ""
diff -r d6c09be8c5f5 -r 3165e43ce734 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Tue Oct 02 10:07:35 2007 -0600
+++ b/tools/python/xen/xend/XendDomain.py       Tue Oct 02 11:31:55 2007 -0600
@@ -51,7 +51,6 @@ from xen.xend.xenstore.xswatch import xs
 from xen.xend.xenstore.xswatch import xswatch
 from xen.util import mkdir
 from xen.xend import uuid
-from xen.xend import sxp
 
 xc = xen.lowlevel.xc.xc()
 xoptions = XendOptions.instance() 
@@ -969,31 +968,6 @@ class XendDomain:
         try:
             try:
                 domconfig = XendConfig.XendConfig(sxp_obj = config)
-                
-                domains = self.list('all')
-                domains = map(lambda dom: dom.sxpr(), domains)
-                for dom in domains:
-                    if sxp.child_value(config, 'uuid', None):
-                        if domconfig['uuid'] == sxp.child_value(dom, 'uuid'):
-                            if domconfig['name_label'] != sxp.child_value(dom, 
'name'):
-                                raise XendError("Domain UUID '%s' is already 
used." % \
-                                                domconfig['uuid'])
-                            else:
-                                # Update the config for that existing domain
-                                # because it is same name and same UUID.
-                                break
-                        else:
-                            if domconfig['name_label'] == sxp.child_value(dom, 
'name'):
-                                raise XendError("Domain name '%s' is already 
used." % \
-                                                domconfig['name_label'])
-                    else:
-                        if domconfig['name_label'] == sxp.child_value(dom, 
'name'):
-                            # Overwrite the auto-generated UUID by the UUID
-                            # of the existing domain. And update the config
-                            # for that existing domain.
-                            domconfig['uuid'] = sxp.child_value(dom, 'uuid')
-                            break
-                
                 dominfo = XendDomainInfo.createDormant(domconfig)
                 log.debug("Creating new managed domain: %s" %
                           dominfo.getName())
diff -r d6c09be8c5f5 -r 3165e43ce734 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Tue Oct 02 10:07:35 2007 -0600
+++ b/tools/python/xen/xend/XendDomainInfo.py   Tue Oct 02 11:31:55 2007 -0600
@@ -74,9 +74,15 @@ def create(config):
     @return: An up and running XendDomainInfo instance
     @raise VmError: Invalid configuration or failure to start.
     """
-
+    from xen.xend import XendDomain
+    domconfig = XendConfig.XendConfig(sxp_obj = config)
+    othervm = XendDomain.instance().domain_lookup_nr(domconfig["name_label"])
+    if othervm is None or othervm.domid is None:
+        othervm = XendDomain.instance().domain_lookup_nr(domconfig["uuid"])
+    if othervm is not None and othervm.domid is not None:
+        raise VmError("Domain '%s' already exists with ID '%d'" % 
(domconfig["name_label"], othervm.domid))
     log.debug("XendDomainInfo.create(%s)", scrub_password(config))
-    vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config))
+    vm = XendDomainInfo(domconfig)
     try:
         vm.start()
     except:
diff -r d6c09be8c5f5 -r 3165e43ce734 tools/xenstat/xentop/xentop.c
--- a/tools/xenstat/xentop/xentop.c     Tue Oct 02 10:07:35 2007 -0600
+++ b/tools/xenstat/xentop/xentop.c     Tue Oct 02 11:31:55 2007 -0600
@@ -28,6 +28,7 @@
 #include <sys/time.h>
 #include <time.h>
 #include <unistd.h>
+#include <signal.h>
 #if defined(__linux__)
 #include <linux/kdev_t.h>
 #endif
@@ -1011,6 +1012,13 @@ static void top(void)
        free(domains);
 }
 
+static int signal_exit;
+
+void signal_exit_handler(int sig)
+{
+       signal_exit = 1;
+}
+
 int main(int argc, char **argv)
 {
        int opt, optind = 0;
@@ -1102,14 +1110,22 @@ int main(int argc, char **argv)
                        ch = getch();
                } while (handle_key(ch));
        } else {
-                       do {
-                               gettimeofday(&curtime, NULL);
-                               top();
-                               oldtime = curtime;
-                               if ((!loop) && !(--iterations))
-                                       break;
-                               sleep(delay);
-                       } while (1);
+               struct sigaction sa = {
+                       .sa_handler = signal_exit_handler,
+                       .sa_flags = 0
+               };
+               sigemptyset(&sa.sa_mask);
+               sigaction(SIGINT, &sa, NULL);
+               sigaction(SIGTERM, &sa, NULL);
+
+               do {
+                       gettimeofday(&curtime, NULL);
+                       top();
+                       oldtime = curtime;
+                       if ((!loop) && !(--iterations))
+                               break;
+                       sleep(delay);
+               } while (!signal_exit);
        }
 
        /* Cleanup occurs in cleanup(), so no work to do here. */
diff -r d6c09be8c5f5 -r 3165e43ce734 tools/xentrace/xenctx.c
--- a/tools/xentrace/xenctx.c   Tue Oct 02 10:07:35 2007 -0600
+++ b/tools/xentrace/xenctx.c   Tue Oct 02 11:31:55 2007 -0600
@@ -21,6 +21,7 @@
 #include <argp.h>
 #include <signal.h>
 #include <string.h>
+#include <inttypes.h>
 #include <getopt.h>
 
 #include "xenctrl.h"
@@ -152,9 +153,9 @@ void print_symbol(size_t addr)
         return;
 
     if (addr==s->address)
-        printf("%s", s->name);
+        printf("%s ", s->name);
     else
-        printf("%s+%#x", s->name, (unsigned int)(addr - s->address));
+        printf("%s+%#x ", s->name, (unsigned int)(addr - s->address));
 }
 
 void read_symbol_table(const char *symtab)
@@ -207,6 +208,46 @@ void read_symbol_table(const char *symta
     fclose(f);
 }
 
+#if defined(__i386__) || defined(__x86_64__)
+char *flag_values[22][2] =
+{/*  clear,     set,       bit# */
+    { NULL,     "c"    }, // 0        Carry
+    { NULL,     NULL   }, // 1
+    { NULL,     "p"    }, // 2        Parity
+    { NULL,     NULL   }, // 3
+    { NULL,     "a"    }, // 4        Adjust
+    { NULL,     NULL   }, // 5
+    { "nz",     "z"    }, // 6        Zero
+    { NULL,     "s"    }, // 7        Sign
+    { NULL,     "tf"   }, // 8        Trap
+    { NULL,     "i"    }, // 9        Interrupt (enabled)
+    { NULL,     "d=b"  }, // 10       Direction
+    { NULL,     "o"    }, // 11       Overflow
+    { NULL,     NULL   }, // 12       12+13 == IOPL
+    { NULL,     NULL   }, // 13
+    { NULL,     "nt"   }, // 14       Nested Task
+    { NULL,     NULL   }, // 15
+    { NULL,     "rf"   }, // 16       Resume Flag
+    { NULL,     "v86"  }, // 17       Virtual 8086 mode
+    { NULL,     "ac"   }, // 18       Alignment Check (enabled)
+    { NULL,     "vif"  }, // 19       Virtual Interrupt (enabled)
+    { NULL,     "vip"  }, // 20       Virtual Interrupt Pending
+    { NULL,     "cid"  }  // 21       Cpuid Identification Flag
+};
+
+void print_flags(uint64_t flags)
+{
+    int i;
+
+    printf("flags: %08" PRIx64, flags);
+    for (i = 21; i >= 0; i--) {
+        char *s = flag_values[i][(flags >> i) & 1];
+        if (s != NULL)
+            printf(" %s", s);
+    }
+}
+#endif
+
 #ifdef __i386__
 void print_ctx(vcpu_guest_context_t *ctx1)
 {
@@ -214,6 +255,7 @@ void print_ctx(vcpu_guest_context_t *ctx
 
     printf("eip: %08x ", regs->eip);
     print_symbol(regs->eip);
+    print_flags(regs->eflags);
     printf("\n");
 
     printf("esp: %08x\n", regs->esp);
@@ -240,6 +282,7 @@ void print_ctx(vcpu_guest_context_t *ctx
 
     printf("rip: %08lx ", regs->rip);
     print_symbol(regs->rip);
+    print_flags(regs->rflags);
     printf("\n");
     printf("rsp: %08lx\n", regs->rsp);
 
@@ -262,10 +305,10 @@ void print_ctx(vcpu_guest_context_t *ctx
     printf("r14: %08lx\t", regs->r14);
     printf("r15: %08lx\n", regs->r15);
 
-    printf(" cs: %08x\t", regs->cs);
-    printf(" ds: %08x\t", regs->ds);
-    printf(" fs: %08x\t", regs->fs);
-    printf(" gs: %08x\n", regs->gs);
+    printf(" cs:     %04x\t", regs->cs);
+    printf(" ds:     %04x\t", regs->ds);
+    printf(" fs:     %04x\t", regs->fs);
+    printf(" gs:     %04x\n", regs->gs);
 
 }
 #elif defined(__ia64__)
diff -r d6c09be8c5f5 -r 3165e43ce734 tools/xentrace/xentrace.8
--- a/tools/xentrace/xentrace.8 Tue Oct 02 10:07:35 2007 -0600
+++ b/tools/xentrace/xentrace.8 Tue Oct 02 11:31:55 2007 -0600
@@ -131,4 +131,4 @@ Mark A. Williamson <mark.a.williamson@in
 Mark A. Williamson <mark.a.williamson@xxxxxxxxx>
 
 .SH "SEE ALSO"
-xentrace_cpuinfo(1), xentrace_format(1)
+xentrace_format(1)
diff -r d6c09be8c5f5 -r 3165e43ce734 tools/xentrace/xentrace_format
--- a/tools/xentrace/xentrace_format    Tue Oct 02 10:07:35 2007 -0600
+++ b/tools/xentrace/xentrace_format    Tue Oct 02 11:31:55 2007 -0600
@@ -83,11 +83,24 @@ interrupted = 0
 
 defs = read_defs(arg[0])
 
-# structure of trace record + prepended CPU id (as output by xentrace):
-# CPU(I) TSC(Q) EVENT(L) D1(L) D2(L) D3(L) D4(L) D5(L)
-# read CPU id separately to avoid structure packing problems on 64-bit arch.
-CPUREC = "I"
-TRCREC = "QLLLLLL"
+# structure of trace record (as output by xentrace):
+# HDR(I) {TSC(Q)} D1(I) D2(I) D3(I) D4(I) D5(I)
+#
+# HDR consists of EVENT:28:, n_data:3:, tsc_in:1:
+# EVENT means Event ID
+# n_data means number of data (like D1, D2, ...)
+# tsc_in means TSC data exists(1) or not(0).
+# if tsc_in == 0, TSC(Q) does not exists.
+#
+# CPU ID exists on trace data of EVENT=0x0001f003
+#
+HDRREC = "I"
+TSCREC = "Q"
+D1REC  = "I"
+D2REC  = "II"
+D3REC  = "III"
+D4REC  = "IIII"
+D5REC  = "IIIII"
 
 last_tsc = [0]
 
@@ -96,19 +109,58 @@ while not interrupted:
 while not interrupted:
     try:
        i=i+1
-        line = sys.stdin.read(struct.calcsize(CPUREC))
+        line = sys.stdin.read(struct.calcsize(HDRREC))
         if not line:
             break
-        cpu = struct.unpack(CPUREC, line)[0]
-
-        line = sys.stdin.read(struct.calcsize(TRCREC))
-        if not line:
-            break
-
-        (tsc, event, d1, d2, d3, d4, d5) = struct.unpack(TRCREC, line)
-
-        # Event field is 'uint32_t', not 'long'.
-        event &= 0xffffffff
+        event = struct.unpack(HDRREC, line)[0]
+        n_data = event >> 28 & 0x7
+        tsc_in = event >> 31
+
+        d1 = 0
+        d2 = 0
+        d3 = 0
+        d4 = 0
+        d5 = 0
+  
+        tsc = 0
+
+        if tsc_in == 1:
+            line = sys.stdin.read(struct.calcsize(TSCREC))
+            if not line:
+                break
+            tsc = struct.unpack(TSCREC, line)[0]
+
+        if n_data == 1:
+            line = sys.stdin.read(struct.calcsize(D1REC))
+            if not line:
+                break
+            (d1) = struct.unpack(D1REC, line)
+        if n_data == 2:
+            line = sys.stdin.read(struct.calcsize(D2REC))
+            if not line:
+                break
+            (d1, d2) = struct.unpack(D2REC, line)
+        if n_data == 3:
+            line = sys.stdin.read(struct.calcsize(D3REC))
+            if not line:
+                break
+            (d1, d2, d3) = struct.unpack(D3REC, line)
+        if n_data == 4:
+            line = sys.stdin.read(struct.calcsize(D4REC))
+            if not line:
+                break
+            (d1, d2, d3, d4) = struct.unpack(D4REC, line)
+        if n_data == 5:
+            line = sys.stdin.read(struct.calcsize(D5REC))
+            if not line:
+                break
+            (d1, d2, d3, d4, d5) = struct.unpack(D5REC, line)
+
+        # Event field is 28bit of 'uint32_t' in header, not 'long'.
+        event &= 0x0fffffff
+        if event == 0x1f003:
+            cpu = d1
+
 
        #tsc = (tscH<<32) | tscL
 
@@ -116,16 +168,17 @@ while not interrupted:
 
         if cpu >= len(last_tsc):
             last_tsc += [0] * (cpu - len(last_tsc) + 1)
-       elif tsc < last_tsc[cpu]:
+       elif tsc < last_tsc[cpu] and tsc_in == 1:
            print "TSC stepped backward cpu %d !  %d %d" % 
(cpu,tsc,last_tsc[cpu])
 
        # provide relative TSC
-       if last_tsc[cpu] > 0:
+       if last_tsc[cpu] > 0 and tsc_in == 1:
                reltsc = tsc - last_tsc[cpu]
        else:
                reltsc = 0
 
-       last_tsc[cpu] = tsc
+       if tsc_in == 1:
+           last_tsc[cpu] = tsc
 
        if mhz:
            tsc = tsc / (mhz*1000000.0)
diff -r d6c09be8c5f5 -r 3165e43ce734 tools/xm-test/configure.ac
--- a/tools/xm-test/configure.ac        Tue Oct 02 10:07:35 2007 -0600
+++ b/tools/xm-test/configure.ac        Tue Oct 02 11:31:55 2007 -0600
@@ -85,9 +85,9 @@ AC_SUBST(NETWORK_ADDRESS)
 AC_SUBST(NETWORK_ADDRESS)
 AC_SUBST(NETMASK)
 
-DOM0_INTF="vif0.0"
+DOM0_INTF="eth0"
 AC_ARG_WITH(dom0-intf,
-        [ --with-dom0-intf=intf Set dom0 interface name [[default="vif0.0"]]],
+        [ --with-dom0-intf=intf Set dom0 interface name [[default="eth0"]]],
         [ DOM0_INTF="$withval" ])
 
 AC_SUBST(DOM0_INTF)
diff -r d6c09be8c5f5 -r 3165e43ce734 tools/xm-test/lib/XmTestLib/NetConfig.py
--- a/tools/xm-test/lib/XmTestLib/NetConfig.py  Tue Oct 02 10:07:35 2007 -0600
+++ b/tools/xm-test/lib/XmTestLib/NetConfig.py  Tue Oct 02 11:31:55 2007 -0600
@@ -71,7 +71,7 @@ def getXendNetConfig():
 
 def checkZeroconfAddresses():
     # Make sure there aren't existing zeroconf addresses.
-    rc, out = traceCommand("ip addr show |grep \"inet 169.254\" | grep -v vif")
+    rc, out = traceCommand("ip addr show |grep \"inet 169.254\" | grep eth0")
     if rc == 0:
         raise NetworkError("Zeroconf addresses already used: %s" % out)
 
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/domain.c     Tue Oct 02 11:31:55 2007 -0600
@@ -382,6 +382,10 @@ int vcpu_initialise(struct vcpu *v)
 
     v->arch.flags = TF_kernel_mode;
 
+#if defined(__i386__)
+    mapcache_vcpu_init(v);
+#endif
+
     pae_l3_cache_init(&v->arch.pae_l3_cache);
 
     paging_vcpu_init(v);
@@ -461,7 +465,7 @@ int arch_domain_create(struct domain *d)
 
 #if defined(__i386__)
 
-    mapcache_init(d);
+    mapcache_domain_init(d);
 
 #else /* __x86_64__ */
 
@@ -645,21 +649,21 @@ int arch_set_info_guest(
 
     v->arch.guest_context.user_regs.eflags |= 2;
 
+    if ( is_hvm_vcpu(v) )
+        goto out;
+
     /* Only CR0.TS is modifiable by guest or admin. */
     v->arch.guest_context.ctrlreg[0] &= X86_CR0_TS;
     v->arch.guest_context.ctrlreg[0] |= read_cr0() & ~X86_CR0_TS;
 
     init_int80_direct_trap(v);
 
-    if ( !is_hvm_vcpu(v) )
-    {
-        /* IOPL privileges are virtualised. */
-        v->arch.iopl = (v->arch.guest_context.user_regs.eflags >> 12) & 3;
-        v->arch.guest_context.user_regs.eflags &= ~EF_IOPL;
-
-        /* Ensure real hardware interrupts are enabled. */
-        v->arch.guest_context.user_regs.eflags |= EF_IE;
-    }
+    /* IOPL privileges are virtualised. */
+    v->arch.iopl = (v->arch.guest_context.user_regs.eflags >> 12) & 3;
+    v->arch.guest_context.user_regs.eflags &= ~EF_IOPL;
+
+    /* Ensure real hardware interrupts are enabled. */
+    v->arch.guest_context.user_regs.eflags |= EF_IE;
 
     if ( v->is_initialised )
         goto out;
@@ -672,29 +676,44 @@ int arch_set_info_guest(
     if ( v->vcpu_id == 0 )
         d->vm_assist = c(vm_assist);
 
-    if ( !is_hvm_vcpu(v) )
-    {
-        if ( !compat )
-            rc = (int)set_gdt(v, c.nat->gdt_frames, c.nat->gdt_ents);
+    if ( !compat )
+        rc = (int)set_gdt(v, c.nat->gdt_frames, c.nat->gdt_ents);
 #ifdef CONFIG_COMPAT
-        else
-        {
-            unsigned long gdt_frames[ARRAY_SIZE(c.cmp->gdt_frames)];
-            unsigned int i, n = (c.cmp->gdt_ents + 511) / 512;
-
-            if ( n > ARRAY_SIZE(c.cmp->gdt_frames) )
-                return -EINVAL;
-            for ( i = 0; i < n; ++i )
-                gdt_frames[i] = c.cmp->gdt_frames[i];
-            rc = (int)set_gdt(v, gdt_frames, c.cmp->gdt_ents);
-        }
-#endif
-        if ( rc != 0 )
-            return rc;
-
-        if ( !compat )
-        {
-            cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[3]));
+    else
+    {
+        unsigned long gdt_frames[ARRAY_SIZE(c.cmp->gdt_frames)];
+        unsigned int i, n = (c.cmp->gdt_ents + 511) / 512;
+
+        if ( n > ARRAY_SIZE(c.cmp->gdt_frames) )
+            return -EINVAL;
+        for ( i = 0; i < n; ++i )
+            gdt_frames[i] = c.cmp->gdt_frames[i];
+        rc = (int)set_gdt(v, gdt_frames, c.cmp->gdt_ents);
+    }
+#endif
+    if ( rc != 0 )
+        return rc;
+
+    if ( !compat )
+    {
+        cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[3]));
+
+        if ( !mfn_valid(cr3_pfn) ||
+             (paging_mode_refcounts(d)
+              ? !get_page(mfn_to_page(cr3_pfn), d)
+              : !get_page_and_type(mfn_to_page(cr3_pfn), d,
+                                   PGT_base_page_table)) )
+        {
+            destroy_gdt(v);
+            return -EINVAL;
+        }
+
+        v->arch.guest_table = pagetable_from_pfn(cr3_pfn);
+
+#ifdef __x86_64__
+        if ( c.nat->ctrlreg[1] )
+        {
+            cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[1]));
 
             if ( !mfn_valid(cr3_pfn) ||
                  (paging_mode_refcounts(d)
@@ -702,59 +721,42 @@ int arch_set_info_guest(
                   : !get_page_and_type(mfn_to_page(cr3_pfn), d,
                                        PGT_base_page_table)) )
             {
+                cr3_pfn = pagetable_get_pfn(v->arch.guest_table);
+                v->arch.guest_table = pagetable_null();
+                if ( paging_mode_refcounts(d) )
+                    put_page(mfn_to_page(cr3_pfn));
+                else
+                    put_page_and_type(mfn_to_page(cr3_pfn));
                 destroy_gdt(v);
                 return -EINVAL;
             }
 
-            v->arch.guest_table = pagetable_from_pfn(cr3_pfn);
-
-#ifdef __x86_64__
-            if ( c.nat->ctrlreg[1] )
-            {
-                cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[1]));
-
-                if ( !mfn_valid(cr3_pfn) ||
-                     (paging_mode_refcounts(d)
-                      ? !get_page(mfn_to_page(cr3_pfn), d)
-                      : !get_page_and_type(mfn_to_page(cr3_pfn), d,
-                                           PGT_base_page_table)) )
-                {
-                    cr3_pfn = pagetable_get_pfn(v->arch.guest_table);
-                    v->arch.guest_table = pagetable_null();
-                    if ( paging_mode_refcounts(d) )
-                        put_page(mfn_to_page(cr3_pfn));
-                    else
-                        put_page_and_type(mfn_to_page(cr3_pfn));
-                    destroy_gdt(v);
-                    return -EINVAL;
-                }
-
-                v->arch.guest_table_user = pagetable_from_pfn(cr3_pfn);
-            }
-#endif
-        }
+            v->arch.guest_table_user = pagetable_from_pfn(cr3_pfn);
+        }
+#endif
+    }
 #ifdef CONFIG_COMPAT
-        else
-        {
-            l4_pgentry_t *l4tab;
-
-            cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c.cmp->ctrlreg[3]));
-
-            if ( !mfn_valid(cr3_pfn) ||
-                 (paging_mode_refcounts(d)
-                  ? !get_page(mfn_to_page(cr3_pfn), d)
-                  : !get_page_and_type(mfn_to_page(cr3_pfn), d,
-                                       PGT_l3_page_table)) )
-            {
-                destroy_gdt(v);
-                return -EINVAL;
-            }
-
-            l4tab = __va(pagetable_get_paddr(v->arch.guest_table));
-            *l4tab = l4e_from_pfn(cr3_pfn, 
_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED);
-        }
-#endif
-    }    
+    else
+    {
+        l4_pgentry_t *l4tab;
+
+        cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c.cmp->ctrlreg[3]));
+
+        if ( !mfn_valid(cr3_pfn) ||
+             (paging_mode_refcounts(d)
+              ? !get_page(mfn_to_page(cr3_pfn), d)
+              : !get_page_and_type(mfn_to_page(cr3_pfn), d,
+                                   PGT_l3_page_table)) )
+        {
+            destroy_gdt(v);
+            return -EINVAL;
+        }
+
+        l4tab = __va(pagetable_get_paddr(v->arch.guest_table));
+        *l4tab = l4e_from_pfn(
+            cr3_pfn, _PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED);
+    }
+#endif
 
     if ( v->vcpu_id == 0 )
         update_domain_wallclock_time(d);
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/hvm/hvm.c    Tue Oct 02 11:31:55 2007 -0600
@@ -443,6 +443,8 @@ int hvm_vcpu_initialise(struct vcpu *v)
     spin_lock_init(&v->arch.hvm_vcpu.tm_lock);
     INIT_LIST_HEAD(&v->arch.hvm_vcpu.tm_list);
 
+    v->arch.guest_context.user_regs.eflags = 2;
+
     if ( v->vcpu_id == 0 )
     {
         /* NB. All these really belong in hvm_domain_initialise(). */
@@ -453,6 +455,10 @@ int hvm_vcpu_initialise(struct vcpu *v)
  
         /* Init guest TSC to start from zero. */
         hvm_set_guest_time(v, 0);
+
+        /* Can start up without SIPI-SIPI or setvcpucontext domctl. */
+        v->is_initialised = 1;
+        clear_bit(_VPF_down, &v->pause_flags);
     }
 
     return 0;
@@ -737,7 +743,7 @@ int hvm_set_cr4(unsigned long value)
     old_cr = v->arch.hvm_vcpu.guest_cr[4];
     v->arch.hvm_vcpu.guest_cr[4] = value;
     hvm_update_guest_cr(v, 4);
-  
+
     /* Modifying CR4.{PSE,PAE,PGE} invalidates all TLB entries, inc. Global. */
     if ( (old_cr ^ value) & (X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE) )
         paging_update_paging_modes(v);
@@ -1651,7 +1657,15 @@ static int hvmop_set_pci_link_route(
 
 static int hvmop_flush_tlb_all(void)
 {
+    struct vcpu *v;
+
+    /* Flush paging-mode soft state (e.g., va->gfn cache; PAE PDPE cache). */
+    for_each_vcpu ( current->domain, v )
+        paging_update_cr3(v);
+
+    /* Flush all dirty TLBs. */
     flush_tlb_mask(current->domain->domain_dirty_cpumask);
+
     return 0;
 }
 
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/hvm/irq.c
--- a/xen/arch/x86/hvm/irq.c    Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/hvm/irq.c    Tue Oct 02 11:31:55 2007 -0600
@@ -285,49 +285,63 @@ void hvm_set_callback_via(struct domain 
     }
 }
 
-enum hvm_intack hvm_vcpu_has_pending_irq(struct vcpu *v)
+struct hvm_intack hvm_vcpu_has_pending_irq(struct vcpu *v)
 {
     struct hvm_domain *plat = &v->domain->arch.hvm_domain;
+    int vector;
 
     if ( unlikely(v->nmi_pending) )
         return hvm_intack_nmi;
 
-    if ( vlapic_has_interrupt(v) != -1 )
-        return hvm_intack_lapic;
-
-    if ( !vlapic_accept_pic_intr(v) )
-        return hvm_intack_none;
-
-    return plat->vpic[0].int_output ? hvm_intack_pic : hvm_intack_none;
-}
-
-int hvm_vcpu_ack_pending_irq(struct vcpu *v, enum hvm_intack type, int *vector)
-{
-    switch ( type )
-    {
-    case hvm_intack_nmi:
-        return test_and_clear_bool(v->nmi_pending);
-    case hvm_intack_lapic:
-        return ((*vector = cpu_get_apic_interrupt(v)) != -1);
-    case hvm_intack_pic:
+    if ( vlapic_accept_pic_intr(v) && plat->vpic[0].int_output )
+        return hvm_intack_pic(0);
+
+    vector = vlapic_has_pending_irq(v);
+    if ( vector != -1 )
+        return hvm_intack_lapic(vector);
+
+    return hvm_intack_none;
+}
+
+struct hvm_intack hvm_vcpu_ack_pending_irq(
+    struct vcpu *v, struct hvm_intack intack)
+{
+    int vector;
+
+    switch ( intack.source )
+    {
+    case hvm_intsrc_nmi:
+        if ( !test_and_clear_bool(v->nmi_pending) )
+            intack = hvm_intack_none;
+        break;
+    case hvm_intsrc_pic:
         ASSERT(v->vcpu_id == 0);
-        return ((*vector = cpu_get_pic_interrupt(v)) != -1);
+        if ( (vector = vpic_ack_pending_irq(v)) == -1 )
+            intack = hvm_intack_none;
+        else
+            intack.vector = (uint8_t)vector;
+        break;
+    case hvm_intsrc_lapic:
+        if ( !vlapic_ack_pending_irq(v, intack.vector) )
+            intack = hvm_intack_none;
+        break;
     default:
-        break;
-    }
-
-    return 0;
-}
-
-int get_isa_irq_vector(struct vcpu *v, int isa_irq, enum hvm_intack src)
+        intack = hvm_intack_none;
+        break;
+    }
+
+    return intack;
+}
+
+int get_isa_irq_vector(struct vcpu *v, int isa_irq, enum hvm_intsrc src)
 {
     unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
 
-    if ( src == hvm_intack_pic )
+    if ( src == hvm_intsrc_pic )
         return (v->domain->arch.hvm_domain.vpic[isa_irq >> 3].irq_base
                 + (isa_irq & 7));
 
-    ASSERT(src == hvm_intack_lapic);
+    ASSERT(src == hvm_intsrc_lapic);
     return domain_vioapic(v->domain)->redirtbl[gsi].fields.vector;
 }
 
@@ -345,18 +359,18 @@ int is_isa_irq_masked(struct vcpu *v, in
 
 int hvm_local_events_need_delivery(struct vcpu *v)
 {
-    enum hvm_intack type;
+    struct hvm_intack intack;
 
     /* TODO: Get rid of event-channel special case. */
     if ( vcpu_info(v, evtchn_upcall_pending) )
-        type = hvm_intack_pic;
+        intack = hvm_intack_pic(0);
     else
-        type = hvm_vcpu_has_pending_irq(v);
-
-    if ( likely(type == hvm_intack_none) )
+        intack = hvm_vcpu_has_pending_irq(v);
+
+    if ( likely(intack.source == hvm_intsrc_none) )
         return 0;
 
-    return hvm_interrupts_enabled(v, type);
+    return !hvm_interrupt_blocked(v, intack);
 }
 
 #if 0 /* Keep for debugging */
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c       Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/hvm/svm/intr.c       Tue Oct 02 11:31:55 2007 -0600
@@ -39,19 +39,6 @@
 #include <xen/domain_page.h>
 #include <asm/hvm/trace.h>
 
-static void svm_inject_dummy_vintr(struct vcpu *v)
-{
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-    vintr_t intr = vmcb->vintr;
-
-    intr.fields.irq = 1;
-    intr.fields.intr_masking = 1;
-    intr.fields.vector = 0;
-    intr.fields.prio = 0xF;
-    intr.fields.ign_tpr = 1;
-    vmcb->vintr = intr;
-}
-    
 static void svm_inject_nmi(struct vcpu *v)
 {
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
@@ -80,11 +67,14 @@ static void svm_inject_extint(struct vcp
     vmcb->eventinj = event;
 }
     
-static void enable_intr_window(struct vcpu *v, enum hvm_intack intr_source)
+static void enable_intr_window(struct vcpu *v, struct hvm_intack intack)
 {
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+    vintr_t intr;
 
-    ASSERT(intr_source != hvm_intack_none);
+    ASSERT(intack.source != hvm_intsrc_none);
+
+    HVMTRACE_2D(INJ_VIRQ, v, 0x0, /*fake=*/ 1);
 
     /*
      * Create a dummy virtual interrupt to intercept as soon as the
@@ -95,53 +85,29 @@ static void enable_intr_window(struct vc
      * track 'NMI blocking' from NMI injection until IRET. This can be done
      * quite easily in software by intercepting the unblocking IRET.
      */
+    intr = vmcb->vintr;
+    intr.fields.irq     = 1;
+    intr.fields.vector  = 0;
+    intr.fields.prio    = intack.vector >> 4;
+    intr.fields.ign_tpr = (intack.source != hvm_intsrc_lapic);
+    vmcb->vintr = intr;
     vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
-    HVMTRACE_2D(INJ_VIRQ, v, 0x0, /*fake=*/ 1);
-    svm_inject_dummy_vintr(v);
-}
-
-static void update_cr8_intercept(
-    struct vcpu *v, enum hvm_intack masked_intr_source)
-{
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-    struct vlapic *vlapic = vcpu_vlapic(v);
-    int max_irr;
-
-    vmcb->cr_intercepts &= ~CR_INTERCEPT_CR8_WRITE;
-
-    /*
-     * If ExtInts are masked then that dominates the TPR --- the 'interrupt
-     * window' has already been enabled in this case.
-     */
-    if ( (masked_intr_source == hvm_intack_lapic) ||
-         (masked_intr_source == hvm_intack_pic) )
-        return;
-
-    /* Is there an interrupt pending at the LAPIC? Nothing to do if not. */
-    if ( !vlapic_enabled(vlapic) || 
-         ((max_irr = vlapic_find_highest_irr(vlapic)) == -1) )
-        return;
-
-    /* Highest-priority pending interrupt is masked by the TPR? */
-    if ( (vmcb->vintr.fields.tpr & 0xf) >= (max_irr >> 4) )
-        vmcb->cr_intercepts |= CR_INTERCEPT_CR8_WRITE;
 }
 
 asmlinkage void svm_intr_assist(void) 
 {
     struct vcpu *v = current;
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-    enum hvm_intack intr_source;
-    int intr_vector;
+    struct hvm_intack intack;
 
     /* Crank the handle on interrupt state. */
     pt_update_irq(v);
     hvm_set_callback_irq_level();
 
     do {
-        intr_source = hvm_vcpu_has_pending_irq(v);
-        if ( likely(intr_source == hvm_intack_none) )
-            goto out;
+        intack = hvm_vcpu_has_pending_irq(v);
+        if ( likely(intack.source == hvm_intsrc_none) )
+            return;
 
         /*
          * Pending IRQs must be delayed if:
@@ -158,31 +124,30 @@ asmlinkage void svm_intr_assist(void)
          * 2. The IRQ is masked.
          */
         if ( unlikely(vmcb->eventinj.fields.v) ||
-             !hvm_interrupts_enabled(v, intr_source) )
+             hvm_interrupt_blocked(v, intack) )
         {
-            enable_intr_window(v, intr_source);
-            goto out;
+            enable_intr_window(v, intack);
+            return;
         }
-    } while ( !hvm_vcpu_ack_pending_irq(v, intr_source, &intr_vector) );
 
-    if ( intr_source == hvm_intack_nmi )
+        intack = hvm_vcpu_ack_pending_irq(v, intack);
+    } while ( intack.source == hvm_intsrc_none );
+
+    if ( intack.source == hvm_intsrc_nmi )
     {
         svm_inject_nmi(v);
     }
     else
     {
-        HVMTRACE_2D(INJ_VIRQ, v, intr_vector, /*fake=*/ 0);
-        svm_inject_extint(v, intr_vector);
-        pt_intr_post(v, intr_vector, intr_source);
+        HVMTRACE_2D(INJ_VIRQ, v, intack.vector, /*fake=*/ 0);
+        svm_inject_extint(v, intack.vector);
+        pt_intr_post(v, intack);
     }
 
     /* Is there another IRQ to queue up behind this one? */
-    intr_source = hvm_vcpu_has_pending_irq(v);
-    if ( unlikely(intr_source != hvm_intack_none) )
-        enable_intr_window(v, intr_source);
-
- out:
-    update_cr8_intercept(v, intr_source);
+    intack = hvm_vcpu_has_pending_irq(v);
+    if ( unlikely(intack.source != hvm_intsrc_none) )
+        enable_intr_window(v, intack);
 }
 
 /*
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c        Tue Oct 02 11:31:55 2007 -0600
@@ -425,16 +425,28 @@ static void svm_restore_dr(struct vcpu *
         __restore_debug_registers(v);
 }
 
-static int svm_interrupts_enabled(struct vcpu *v, enum hvm_intack type)
-{
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
-    if ( type == hvm_intack_nmi )
-        return !vmcb->interrupt_shadow;
-
-    ASSERT((type == hvm_intack_pic) || (type == hvm_intack_lapic));
-    return (!irq_masked(guest_cpu_user_regs()->eflags) &&
-            !vmcb->interrupt_shadow);
+static enum hvm_intblk svm_interrupt_blocked(
+    struct vcpu *v, struct hvm_intack intack)
+{
+    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+
+    if ( vmcb->interrupt_shadow )
+        return hvm_intblk_shadow;
+
+    if ( intack.source == hvm_intsrc_nmi )
+        return hvm_intblk_none;
+
+    ASSERT((intack.source == hvm_intsrc_pic) ||
+           (intack.source == hvm_intsrc_lapic));
+
+    if ( irq_masked(guest_cpu_user_regs()->eflags) )
+        return hvm_intblk_rflags_ie;
+
+    if ( (intack.source == hvm_intsrc_lapic) &&
+         ((vmcb->vintr.fields.tpr & 0xf) >= (intack.vector >> 4)) )
+        return hvm_intblk_tpr;
+
+    return hvm_intblk_none;
 }
 
 static int svm_guest_x86_mode(struct vcpu *v)
@@ -855,7 +867,7 @@ static struct hvm_function_table svm_fun
     .vcpu_destroy         = svm_vcpu_destroy,
     .save_cpu_ctxt        = svm_save_vmcb_ctxt,
     .load_cpu_ctxt        = svm_load_vmcb_ctxt,
-    .interrupts_enabled   = svm_interrupts_enabled,
+    .interrupt_blocked    = svm_interrupt_blocked,
     .guest_x86_mode       = svm_guest_x86_mode,
     .get_segment_base     = svm_get_segment_base,
     .get_segment_register = svm_get_segment_register,
@@ -1552,7 +1564,6 @@ static void mov_from_cr(int cr, int gp, 
 {
     unsigned long value = 0;
     struct vcpu *v = current;
-    struct vlapic *vlapic = vcpu_vlapic(v);
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 
     switch ( cr )
@@ -1560,21 +1571,14 @@ static void mov_from_cr(int cr, int gp, 
     case 0:
         value = v->arch.hvm_vcpu.guest_cr[0];
         break;
-    case 2:
-        value = vmcb->cr2;
-        break;
     case 3:
         value = (unsigned long)v->arch.hvm_vcpu.guest_cr[3];
         break;
     case 4:
         value = (unsigned long)v->arch.hvm_vcpu.guest_cr[4];
         break;
-    case 8:
-        value = (unsigned long)vlapic_get_reg(vlapic, APIC_TASKPRI);
-        value = (value & 0xF0) >> 4;
-        break;
-        
     default:
+        gdprintk(XENLOG_ERR, "invalid cr: %d\n", cr);
         domain_crash(v->domain);
         return;
     }
@@ -1590,7 +1594,6 @@ static int mov_to_cr(int gpreg, int cr, 
 {
     unsigned long value;
     struct vcpu *v = current;
-    struct vlapic *vlapic = vcpu_vlapic(v);
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 
     value = get_reg(gpreg, regs, vmcb);
@@ -1604,18 +1607,10 @@ static int mov_to_cr(int gpreg, int cr, 
     {
     case 0: 
         return svm_set_cr0(value);
-
     case 3:
         return hvm_set_cr3(value);
-
     case 4:
         return hvm_set_cr4(value);
-
-    case 8:
-        vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
-        vmcb->vintr.fields.tpr = value & 0x0F;
-        break;
-
     default:
         gdprintk(XENLOG_ERR, "invalid cr: %d\n", cr);
         domain_crash(v->domain);
@@ -1894,13 +1889,14 @@ static void svm_vmexit_do_hlt(struct vmc
 static void svm_vmexit_do_hlt(struct vmcb_struct *vmcb,
                               struct cpu_user_regs *regs)
 {
-    enum hvm_intack type = hvm_vcpu_has_pending_irq(current);
+    struct hvm_intack intack = hvm_vcpu_has_pending_irq(current);
 
     __update_guest_eip(regs, 1);
 
     /* Check for interrupt not handled or new interrupt. */
     if ( vmcb->eventinj.fields.v ||
-         ((type != hvm_intack_none) && svm_interrupts_enabled(current, type)) )
+         ((intack.source != hvm_intsrc_none) &&
+          !svm_interrupt_blocked(current, intack)) )
     {
         HVMTRACE_1D(HLT, current, /*int pending=*/ 1);
         return;
@@ -2080,13 +2076,11 @@ asmlinkage void svm_vmexit_handler(struc
 
     /*
      * Before doing anything else, we need to sync up the VLAPIC's TPR with
-     * SVM's vTPR if CR8 writes are currently disabled.  It's OK if the 
-     * guest doesn't touch the CR8 (e.g. 32-bit Windows) because we update
-     * the vTPR on MMIO writes to the TPR
+     * SVM's vTPR. It's OK if the guest doesn't touch CR8 (e.g. 32-bit Windows)
+     * because we update the vTPR on MMIO writes to the TPR.
      */
-    if ( !(vmcb->cr_intercepts & CR_INTERCEPT_CR8_WRITE) )
-        vlapic_set_reg(vcpu_vlapic(v), APIC_TASKPRI,
-                       (vmcb->vintr.fields.tpr & 0x0F) << 4);
+    vlapic_set_reg(vcpu_vlapic(v), APIC_TASKPRI,
+                   (vmcb->vintr.fields.tpr & 0x0F) << 4);
 
     exit_reason = vmcb->exitcode;
 
@@ -2164,9 +2158,9 @@ asmlinkage void svm_vmexit_handler(struc
         break;
     }
 
+    /* Asynchronous event, handled when we STGI'd after the VMEXIT. */
     case VMEXIT_EXCEPTION_MC:
         HVMTRACE_0D(MCE, v);
-        do_machine_check(regs);
         break;
 
     case VMEXIT_VINTR:
@@ -2222,45 +2216,14 @@ asmlinkage void svm_vmexit_handler(struc
         }
         break;
 
-    case VMEXIT_CR0_READ:
-        svm_cr_access(v, 0, TYPE_MOV_FROM_CR, regs);
-        break;
-
-    case VMEXIT_CR2_READ:
-        svm_cr_access(v, 2, TYPE_MOV_FROM_CR, regs);
-        break;
-
-    case VMEXIT_CR3_READ:
-        svm_cr_access(v, 3, TYPE_MOV_FROM_CR, regs);
-        break;
-
-    case VMEXIT_CR4_READ:
-        svm_cr_access(v, 4, TYPE_MOV_FROM_CR, regs);
-        break;
-
-    case VMEXIT_CR8_READ:
-        svm_cr_access(v, 8, TYPE_MOV_FROM_CR, regs);
-        break;
-
-    case VMEXIT_CR0_WRITE:
-        svm_cr_access(v, 0, TYPE_MOV_TO_CR, regs);
-        break;
-
-    case VMEXIT_CR2_WRITE:
-        svm_cr_access(v, 2, TYPE_MOV_TO_CR, regs);
-        break;
-
-    case VMEXIT_CR3_WRITE:
-        svm_cr_access(v, 3, TYPE_MOV_TO_CR, regs);
-        local_flush_tlb();
-        break;
-
-    case VMEXIT_CR4_WRITE:
-        svm_cr_access(v, 4, TYPE_MOV_TO_CR, regs);
-        break;
-
-    case VMEXIT_CR8_WRITE:
-        svm_cr_access(v, 8, TYPE_MOV_TO_CR, regs);
+    case VMEXIT_CR0_READ ... VMEXIT_CR15_READ:
+        svm_cr_access(v, exit_reason - VMEXIT_CR0_READ,
+                      TYPE_MOV_FROM_CR, regs);
+        break;
+
+    case VMEXIT_CR0_WRITE ... VMEXIT_CR15_WRITE:
+        svm_cr_access(v, exit_reason - VMEXIT_CR0_WRITE,
+                      TYPE_MOV_TO_CR, regs);
         break;
 
     case VMEXIT_DR0_WRITE ... VMEXIT_DR7_WRITE:
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c       Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/hvm/svm/vmcb.c       Tue Oct 02 11:31:55 2007 -0600
@@ -130,14 +130,11 @@ static int construct_vmcb(struct vcpu *v
     /* Intercept all debug-register writes. */
     vmcb->dr_intercepts = DR_INTERCEPT_ALL_WRITES;
 
-    /*
-     * Intercept all control-register accesses except for CR2 reads/writes
-     * and CR8 reads (and actually CR8 writes, but that's a special case
-     * that's handled in svm/intr.c). 
-     */
+    /* Intercept all control-register accesses except for CR2 and CR8. */
     vmcb->cr_intercepts = ~(CR_INTERCEPT_CR2_READ |
                             CR_INTERCEPT_CR2_WRITE |
-                            CR_INTERCEPT_CR8_READ);
+                            CR_INTERCEPT_CR8_READ |
+                            CR_INTERCEPT_CR8_WRITE);
 
     /* I/O and MSR permission bitmaps. */
     arch_svm->msrpm = alloc_xenheap_pages(get_order_from_bytes(MSRPM_SIZE));
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/hvm/vlapic.c Tue Oct 02 11:31:55 2007 -0600
@@ -732,33 +732,34 @@ int vlapic_accept_pic_intr(struct vcpu *
              vlapic_hw_disabled(vlapic)));
 }
 
-int vlapic_has_interrupt(struct vcpu *v)
+int vlapic_has_pending_irq(struct vcpu *v)
 {
     struct vlapic *vlapic = vcpu_vlapic(v);
-    int highest_irr;
+    int irr, isr;
 
     if ( !vlapic_enabled(vlapic) )
         return -1;
 
-    highest_irr = vlapic_find_highest_irr(vlapic);
-    if ( (highest_irr == -1) ||
-         ((highest_irr & 0xF0) <= vlapic_get_ppr(vlapic)) )
+    irr = vlapic_find_highest_irr(vlapic);
+    if ( irr == -1 )
         return -1;
 
-    return highest_irr;
-}
-
-int cpu_get_apic_interrupt(struct vcpu *v)
-{
-    int vector = vlapic_has_interrupt(v);
+    isr = vlapic_find_highest_isr(vlapic);
+    isr = (isr != -1) ? isr : 0;
+    if ( (isr & 0xf0) >= (irr & 0xf0) )
+        return -1;
+
+    return irr;
+}
+
+int vlapic_ack_pending_irq(struct vcpu *v, int vector)
+{
     struct vlapic *vlapic = vcpu_vlapic(v);
 
-    if ( vector == -1 )
-        return -1;
- 
     vlapic_set_vector(vector, &vlapic->regs->data[APIC_ISR]);
     vlapic_clear_irr(vector, vlapic);
-    return vector;
+
+    return 1;
 }
 
 /* Reset the VLPAIC back to its power-on/reset state. */
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/hvm/vmx/intr.c
--- a/xen/arch/x86/hvm/vmx/intr.c       Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/hvm/vmx/intr.c       Tue Oct 02 11:31:55 2007 -0600
@@ -71,14 +71,14 @@
  * the effect is cleared. (i.e., MOV-SS-blocking 'dominates' STI-blocking).
  */
 
-static void enable_intr_window(struct vcpu *v, enum hvm_intack intr_source)
+static void enable_intr_window(struct vcpu *v, struct hvm_intack intack)
 {
     u32 *cpu_exec_control = &v->arch.hvm_vmx.exec_control;
     u32 ctl = CPU_BASED_VIRTUAL_INTR_PENDING;
 
-    ASSERT(intr_source != hvm_intack_none);
+    ASSERT(intack.source != hvm_intsrc_none);
 
-    if ( (intr_source == hvm_intack_nmi) && cpu_has_vmx_vnmi )
+    if ( (intack.source == hvm_intsrc_nmi) && cpu_has_vmx_vnmi )
     {
         /*
          * We set MOV-SS blocking in lieu of STI blocking when delivering an
@@ -107,105 +107,84 @@ static void enable_intr_window(struct vc
     }
 }
 
-static void update_tpr_threshold(
-    struct vcpu *v, enum hvm_intack masked_intr_source)
-{
-    struct vlapic *vlapic = vcpu_vlapic(v);
-    int max_irr, tpr, threshold = 0;
-
-    if ( !cpu_has_vmx_tpr_shadow )
-        return;
-
-    /*
-     * If ExtInts are masked then that dominates the TPR --- the 'interrupt
-     * window' has already been enabled in this case.
-     */
-    if ( (masked_intr_source == hvm_intack_lapic) ||
-         (masked_intr_source == hvm_intack_pic) )
-        goto out;
-
-    /* Is there an interrupt pending at the LAPIC? Nothing to do if not. */
-    if ( !vlapic_enabled(vlapic) || 
-         ((max_irr = vlapic_find_highest_irr(vlapic)) == -1) )
-        goto out;
-
-    /* Highest-priority pending interrupt is masked by the TPR? */
-    tpr = vlapic_get_reg(vlapic, APIC_TASKPRI) & 0xF0;
-    if ( (tpr >> 4) >= (max_irr >> 4) )
-        threshold = max_irr >> 4;
-
- out:
-    __vmwrite(TPR_THRESHOLD, threshold);
-}
-
-static void vmx_dirq_assist(struct domain *d)
+static void vmx_dirq_assist(struct vcpu *v)
 {
     unsigned int irq;
     uint32_t device, intx;
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct domain *d = v->domain;
+    struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
 
-    for ( irq = find_first_bit(hvm_irq->dirq_mask, NR_IRQS);
+    if ( !vtd_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
+        return;
+
+    for ( irq = find_first_bit(hvm_irq_dpci->dirq_mask, NR_IRQS);
           irq < NR_IRQS;
-          irq = find_next_bit(hvm_irq->dirq_mask, NR_IRQS, irq + 1) )
+          irq = find_next_bit(hvm_irq_dpci->dirq_mask, NR_IRQS, irq + 1) )
     {
-        test_and_clear_bit(irq, &hvm_irq->dirq_mask);
-        device = hvm_irq->mirq[irq].device;
-        intx = hvm_irq->mirq[irq].intx;
+        test_and_clear_bit(irq, &hvm_irq_dpci->dirq_mask);
+        device = hvm_irq_dpci->mirq[irq].device;
+        intx = hvm_irq_dpci->mirq[irq].intx;
         hvm_pci_intx_assert(d, device, intx);
     }
 }
 
 asmlinkage void vmx_intr_assist(void)
 {
-    int intr_vector;
-    enum hvm_intack intr_source;
+    struct hvm_intack intack;
     struct vcpu *v = current;
-    unsigned int intr_info;
+    unsigned int tpr_threshold = 0;
+    enum hvm_intblk intblk;
 
     /* Crank the handle on interrupt state. */
     pt_update_irq(v);
 
-    if ( vtd_enabled && (v->vcpu_id == 0) )
-        vmx_dirq_assist(v->domain);
+    vmx_dirq_assist(v);
   
     hvm_set_callback_irq_level();
 
     do {
-        intr_source = hvm_vcpu_has_pending_irq(v);
-        if ( likely(intr_source == hvm_intack_none) )
+        intack = hvm_vcpu_has_pending_irq(v);
+        if ( likely(intack.source == hvm_intsrc_none) )
             goto out;
 
-        /*
-         * An event is already pending or the pending interrupt is masked?
-         * Then the pending interrupt must be delayed.
-         */
-        intr_info = __vmread(VM_ENTRY_INTR_INFO);
-        if ( unlikely(intr_info & INTR_INFO_VALID_MASK) ||
-             !hvm_interrupts_enabled(v, intr_source) )
+        intblk = hvm_interrupt_blocked(v, intack);
+        if ( intblk == hvm_intblk_tpr )
         {
-            enable_intr_window(v, intr_source);
+            ASSERT(vlapic_enabled(vcpu_vlapic(v)));
+            ASSERT(intack.source == hvm_intsrc_lapic);
+            tpr_threshold = intack.vector >> 4;
             goto out;
         }
-    } while ( !hvm_vcpu_ack_pending_irq(v, intr_source, &intr_vector) );
 
-    if ( intr_source == hvm_intack_nmi )
+        if ( (intblk != hvm_intblk_none) ||
+             (__vmread(VM_ENTRY_INTR_INFO) & INTR_INFO_VALID_MASK) )
+        {
+            enable_intr_window(v, intack);
+            goto out;
+        }
+
+        intack = hvm_vcpu_ack_pending_irq(v, intack);
+    } while ( intack.source == hvm_intsrc_none );
+
+    if ( intack.source == hvm_intsrc_nmi )
     {
         vmx_inject_nmi(v);
     }
     else
     {
-        HVMTRACE_2D(INJ_VIRQ, v, intr_vector, /*fake=*/ 0);
-        vmx_inject_extint(v, intr_vector);
-        pt_intr_post(v, intr_vector, intr_source);
+        HVMTRACE_2D(INJ_VIRQ, v, intack.vector, /*fake=*/ 0);
+        vmx_inject_extint(v, intack.vector);
+        pt_intr_post(v, intack);
     }
 
     /* Is there another IRQ to queue up behind this one? */
-    intr_source = hvm_vcpu_has_pending_irq(v);
-    if ( unlikely(intr_source != hvm_intack_none) )
-        enable_intr_window(v, intr_source);
+    intack = hvm_vcpu_has_pending_irq(v);
+    if ( unlikely(intack.source != hvm_intsrc_none) )
+        enable_intr_window(v, intack);
 
  out:
-    update_tpr_threshold(v, intr_source);
+    if ( cpu_has_vmx_tpr_shadow )
+        __vmwrite(TPR_THRESHOLD, tpr_threshold);
 }
 
 /*
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Tue Oct 02 11:31:55 2007 -0600
@@ -975,20 +975,34 @@ static void vmx_init_hypercall_page(stru
     *(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */
 }
 
-static int vmx_interrupts_enabled(struct vcpu *v, enum hvm_intack type)
+static enum hvm_intblk vmx_interrupt_blocked(
+    struct vcpu *v, struct hvm_intack intack)
 {
     unsigned long intr_shadow;
 
     intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO);
 
-    if ( type == hvm_intack_nmi )
-        return !(intr_shadow & (VMX_INTR_SHADOW_STI|
-                                VMX_INTR_SHADOW_MOV_SS|
-                                VMX_INTR_SHADOW_NMI));
-
-    ASSERT((type == hvm_intack_pic) || (type == hvm_intack_lapic));
-    return (!irq_masked(guest_cpu_user_regs()->eflags) &&
-            !(intr_shadow & (VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS)));
+    if ( intr_shadow & (VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS) )
+        return hvm_intblk_shadow;
+
+    if ( intack.source == hvm_intsrc_nmi )
+        return ((intr_shadow & VMX_INTR_SHADOW_NMI) ?
+                hvm_intblk_nmi_iret : hvm_intblk_none);
+
+    ASSERT((intack.source == hvm_intsrc_pic) ||
+           (intack.source == hvm_intsrc_lapic));
+
+    if ( irq_masked(guest_cpu_user_regs()->eflags) )
+        return hvm_intblk_rflags_ie;
+
+    if ( intack.source == hvm_intsrc_lapic )
+    {
+        uint32_t tpr = vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xF0;
+        if ( (tpr >> 4) >= (intack.vector >> 4) )
+            return hvm_intblk_tpr;
+    }
+
+    return hvm_intblk_none;
 }
 
 static void vmx_update_host_cr3(struct vcpu *v)
@@ -1112,7 +1126,7 @@ static struct hvm_function_table vmx_fun
     .vcpu_destroy         = vmx_vcpu_destroy,
     .save_cpu_ctxt        = vmx_save_vmcs_ctxt,
     .load_cpu_ctxt        = vmx_load_vmcs_ctxt,
-    .interrupts_enabled   = vmx_interrupts_enabled,
+    .interrupt_blocked    = vmx_interrupt_blocked,
     .guest_x86_mode       = vmx_guest_x86_mode,
     .get_segment_base     = vmx_get_segment_base,
     .get_segment_register = vmx_get_segment_register,
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/hvm/vmx/vtd/intel-iommu.c
--- a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c    Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c    Tue Oct 02 11:31:55 2007 -0600
@@ -173,7 +173,7 @@ static struct page_info *addr_to_dma_pag
         if ( dma_pte_addr(*pte) == 0 )
         {
             pg = alloc_domheap_page(NULL);
-            vaddr = map_domain_page(mfn_x(page_to_mfn(pg)));
+            vaddr = map_domain_page(page_to_mfn(pg));
             if ( !vaddr )
             {
                 spin_unlock_irqrestore(&hd->mapping_lock, flags);
@@ -195,7 +195,7 @@ static struct page_info *addr_to_dma_pag
         else
         {
             pg = maddr_to_page(pte->val);
-            vaddr = map_domain_page(mfn_x(page_to_mfn(pg)));
+            vaddr = map_domain_page(page_to_mfn(pg));
             if ( !vaddr )
             {
                 spin_unlock_irqrestore(&hd->mapping_lock, flags);
@@ -250,7 +250,7 @@ static struct page_info *dma_addr_level_
         if ( level == total )
             return pg;
 
-        parent = map_domain_page(mfn_x(page_to_mfn(pg)));
+        parent = map_domain_page(page_to_mfn(pg));
         total--;
     }
 
@@ -542,7 +542,7 @@ static void dma_pte_clear_one(struct dom
     pg = dma_addr_level_page(domain, addr, 1);
     if ( !pg )
         return;
-    pte = (struct dma_pte *)map_domain_page(mfn_x(page_to_mfn(pg)));
+    pte = (struct dma_pte *)map_domain_page(page_to_mfn(pg));
     pte += address_level_offset(addr, 1);
     if ( pte )
     {
@@ -612,7 +612,7 @@ void dma_pte_free_pagetable(struct domai
             pg = dma_addr_level_page(domain, tmp, level);
             if ( !pg )
                 return;
-            pte = (struct dma_pte *)map_domain_page(mfn_x(page_to_mfn(pg)));
+            pte = (struct dma_pte *)map_domain_page(page_to_mfn(pg));
             pte += address_level_offset(tmp, level);
             dma_clear_pte(*pte);
             iommu_flush_cache_entry(iommu, pte);
@@ -1493,7 +1493,7 @@ int iommu_map_page(struct domain *d, pad
     pg = addr_to_dma_page(d, gfn << PAGE_SHIFT_4K);
     if ( !pg )
         return -ENOMEM;
-    pte = (struct dma_pte *)map_domain_page(mfn_x(page_to_mfn(pg)));
+    pte = (struct dma_pte *)map_domain_page(page_to_mfn(pg));
     pte += mfn & LEVEL_MASK;
     dma_set_pte_addr(*pte, mfn << PAGE_SHIFT_4K);
     dma_set_pte_prot(*pte, DMA_PTE_READ | DMA_PTE_WRITE);
@@ -1554,7 +1554,7 @@ int iommu_page_mapping(struct domain *do
         pg = addr_to_dma_page(domain, iova + PAGE_SIZE_4K * index);
         if ( !pg )
             return -ENOMEM;
-        pte = (struct dma_pte *)map_domain_page(mfn_x(page_to_mfn(pg)));
+        pte = (struct dma_pte *)map_domain_page(page_to_mfn(pg));
         pte += start_pfn & LEVEL_MASK;
         dma_set_pte_addr(*pte, start_pfn << PAGE_SHIFT_4K);
         dma_set_pte_prot(*pte, prot);
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/hvm/vmx/vtd/io.c
--- a/xen/arch/x86/hvm/vmx/vtd/io.c     Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/hvm/vmx/vtd/io.c     Tue Oct 02 11:31:55 2007 -0600
@@ -46,27 +46,41 @@
 #include <public/domctl.h>
 
 int pt_irq_create_bind_vtd(
-    struct domain *d,
-    xen_domctl_bind_pt_irq_t * pt_irq_bind)
+    struct domain *d, xen_domctl_bind_pt_irq_t *pt_irq_bind)
 {
-    struct hvm_domain *hd = &d->arch.hvm_domain;
+    struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
     uint32_t machine_gsi, guest_gsi;
     uint32_t device, intx;
+
+    if ( hvm_irq_dpci == NULL )
+    {
+        hvm_irq_dpci = xmalloc(struct hvm_irq_dpci);
+        if ( hvm_irq_dpci == NULL )
+            return -ENOMEM;
+
+        memset(hvm_irq_dpci, 0, sizeof(*hvm_irq_dpci));
+
+        if ( cmpxchg((unsigned long *)&d->arch.hvm_domain.irq.dpci,
+                     0, (unsigned long)hvm_irq_dpci) != 0 )
+            xfree(hvm_irq_dpci);
+
+        hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
+    }
 
     machine_gsi = pt_irq_bind->machine_irq;
     device = pt_irq_bind->u.pci.device;
     intx = pt_irq_bind->u.pci.intx;
     guest_gsi = hvm_pci_intx_gsi(device, intx);
 
-    hd->irq.mirq[machine_gsi].valid = 1;
-    hd->irq.mirq[machine_gsi].device = device;
-    hd->irq.mirq[machine_gsi].intx = intx;
-    hd->irq.mirq[machine_gsi].guest_gsi = guest_gsi;
+    hvm_irq_dpci->mirq[machine_gsi].valid = 1;
+    hvm_irq_dpci->mirq[machine_gsi].device = device;
+    hvm_irq_dpci->mirq[machine_gsi].intx = intx;
+    hvm_irq_dpci->mirq[machine_gsi].guest_gsi = guest_gsi;
 
-    hd->irq.girq[guest_gsi].valid = 1;
-    hd->irq.girq[guest_gsi].device = device;
-    hd->irq.girq[guest_gsi].intx = intx;
-    hd->irq.girq[guest_gsi].machine_gsi = machine_gsi;
+    hvm_irq_dpci->girq[guest_gsi].valid = 1;
+    hvm_irq_dpci->girq[guest_gsi].device = device;
+    hvm_irq_dpci->girq[guest_gsi].intx = intx;
+    hvm_irq_dpci->girq[guest_gsi].machine_gsi = machine_gsi;
 
     /* Deal with gsi for legacy devices */
     pirq_guest_bind(d->vcpu[0], machine_gsi, BIND_PIRQ__WILL_SHARE);
@@ -76,31 +90,31 @@ int pt_irq_create_bind_vtd(
 
     return 0;
 }
+
 int hvm_do_IRQ_dpci(struct domain *d, unsigned int mirq)
 {
     uint32_t device, intx;
     uint32_t link, isa_irq;
-    struct hvm_irq *hvm_irq;
+    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
 
-    if ( !vtd_enabled || (d == dom0) ||
-         !d->arch.hvm_domain.irq.mirq[mirq].valid )
+    if ( !vtd_enabled || (d == dom0) || (hvm_irq->dpci == NULL) ||
+         !hvm_irq->dpci->mirq[mirq].valid )
         return 0;
 
-    device = d->arch.hvm_domain.irq.mirq[mirq].device;
-    intx = d->arch.hvm_domain.irq.mirq[mirq].intx;
+    device = hvm_irq->dpci->mirq[mirq].device;
+    intx = hvm_irq->dpci->mirq[mirq].intx;
     link = hvm_pci_intx_link(device, intx);
-    hvm_irq = &d->arch.hvm_domain.irq;
     isa_irq = hvm_irq->pci_link.route[link];
 
-    if ( !d->arch.hvm_domain.irq.girq[isa_irq].valid )
+    if ( !hvm_irq->dpci->girq[isa_irq].valid )
     {
-        d->arch.hvm_domain.irq.girq[isa_irq].valid = 1;
-        d->arch.hvm_domain.irq.girq[isa_irq].device = device;
-        d->arch.hvm_domain.irq.girq[isa_irq].intx = intx;
-        d->arch.hvm_domain.irq.girq[isa_irq].machine_gsi = mirq;
+        hvm_irq->dpci->girq[isa_irq].valid = 1;
+        hvm_irq->dpci->girq[isa_irq].device = device;
+        hvm_irq->dpci->girq[isa_irq].intx = intx;
+        hvm_irq->dpci->girq[isa_irq].machine_gsi = mirq;
     }
 
-    if ( !test_and_set_bit(mirq, d->arch.hvm_domain.irq.dirq_mask) )
+    if ( !test_and_set_bit(mirq, hvm_irq->dpci->dirq_mask) )
     {
         vcpu_kick(d->vcpu[0]);
         return 1;
@@ -113,17 +127,19 @@ void hvm_dpci_eoi(unsigned int guest_gsi
 void hvm_dpci_eoi(unsigned int guest_gsi, union vioapic_redir_entry *ent)
 {
     struct domain *d = current->domain;
+    struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
     uint32_t device, intx, machine_gsi;
     irq_desc_t *desc;
 
     ASSERT(spin_is_locked(&d->arch.hvm_domain.irq_lock));
 
-    if ( !vtd_enabled || !d->arch.hvm_domain.irq.girq[guest_gsi].valid )
+    if ( !vtd_enabled || (hvm_irq_dpci == NULL) ||
+         !hvm_irq_dpci->girq[guest_gsi].valid )
         return;
 
-    device = d->arch.hvm_domain.irq.girq[guest_gsi].device;
-    intx = d->arch.hvm_domain.irq.girq[guest_gsi].intx;
-    machine_gsi = d->arch.hvm_domain.irq.girq[guest_gsi].machine_gsi;
+    device = hvm_irq_dpci->girq[guest_gsi].device;
+    intx = hvm_irq_dpci->girq[guest_gsi].intx;
+    machine_gsi = hvm_irq_dpci->girq[guest_gsi].machine_gsi;
     gdprintk(XENLOG_INFO, "hvm_dpci_eoi:: device %x intx %x\n",
              device, intx);
     __hvm_pci_intx_deassert(d, device, intx);
@@ -136,15 +152,20 @@ void hvm_dpci_eoi(unsigned int guest_gsi
 
 void iommu_domain_destroy(struct domain *d)
 {
-    struct hvm_domain *hd = &d->arch.hvm_domain;
+    struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
     uint32_t i;
 
     if ( !vtd_enabled )
         return;
 
-    for ( i = 0; i < NR_IRQS; i++ )
-        if ( hd->irq.mirq[i].valid )
-            pirq_guest_unbind(d, i);
+    if ( hvm_irq_dpci != NULL )
+    {
+        for ( i = 0; i < NR_IRQS; i++ )
+            if ( hvm_irq_dpci->mirq[i].valid )
+                pirq_guest_unbind(d, i);
+        d->arch.hvm_domain.irq.dpci = NULL;
+        xfree(hvm_irq_dpci);
+    }
 
     iommu_domain_teardown(d);
 }
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/hvm/vpic.c
--- a/xen/arch/x86/hvm/vpic.c   Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/hvm/vpic.c   Tue Oct 02 11:31:55 2007 -0600
@@ -503,7 +503,7 @@ void vpic_irq_negative_edge(struct domai
         vpic_update_int_output(vpic);
 }
 
-int cpu_get_pic_interrupt(struct vcpu *v)
+int vpic_ack_pending_irq(struct vcpu *v)
 {
     int irq, vector;
     struct hvm_hw_vpic *vpic = &v->domain->arch.hvm_domain.vpic[0];
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/hvm/vpt.c
--- a/xen/arch/x86/hvm/vpt.c    Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/hvm/vpt.c    Tue Oct 02 11:31:55 2007 -0600
@@ -165,12 +165,12 @@ void pt_update_irq(struct vcpu *v)
 }
 
 static struct periodic_time *is_pt_irq(
-    struct vcpu *v, int vector, enum hvm_intack src)
+    struct vcpu *v, struct hvm_intack intack)
 {
     struct list_head *head = &v->arch.hvm_vcpu.tm_list;
     struct periodic_time *pt;
     struct RTCState *rtc = &v->domain->arch.hvm_domain.pl_time.vrtc;
-    int vec;
+    int vector;
 
     list_for_each_entry ( pt, head, list )
     {
@@ -179,15 +179,16 @@ static struct periodic_time *is_pt_irq(
 
         if ( is_lvtt(v, pt->irq) )
         {
-            if ( pt->irq != vector )
+            if ( pt->irq != intack.vector )
                 continue;
             return pt;
         }
 
-        vec = get_isa_irq_vector(v, pt->irq, src);
+        vector = get_isa_irq_vector(v, pt->irq, intack.source);
 
         /* RTC irq need special care */
-        if ( (vector != vec) || (pt->irq == 8 && !is_rtc_periodic_irq(rtc)) )
+        if ( (intack.vector != vector) ||
+             ((pt->irq == 8) && !is_rtc_periodic_irq(rtc)) )
             continue;
 
         return pt;
@@ -196,7 +197,7 @@ static struct periodic_time *is_pt_irq(
     return NULL;
 }
 
-void pt_intr_post(struct vcpu *v, int vector, enum hvm_intack src)
+void pt_intr_post(struct vcpu *v, struct hvm_intack intack)
 {
     struct periodic_time *pt;
     time_cb *cb;
@@ -204,7 +205,7 @@ void pt_intr_post(struct vcpu *v, int ve
 
     spin_lock(&v->arch.hvm_vcpu.tm_lock);
 
-    pt = is_pt_irq(v, vector, src);
+    pt = is_pt_irq(v, intack);
     if ( pt == NULL )
     {
         spin_unlock(&v->arch.hvm_vcpu.tm_lock);
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/platform_hypercall.c
--- a/xen/arch/x86/platform_hypercall.c Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/platform_hypercall.c Tue Oct 02 11:31:55 2007 -0600
@@ -36,6 +36,8 @@ DEFINE_SPINLOCK(xenpf_lock);
 # define copy_from_compat copy_from_guest
 # undef copy_to_compat
 # define copy_to_compat copy_to_guest
+# undef guest_from_compat_handle
+# define guest_from_compat_handle(x,y) ((x)=(y))
 #else
 extern spinlock_t xenpf_lock;
 #endif
@@ -142,21 +144,14 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
     case XENPF_microcode_update:
     {
         extern int microcode_update(XEN_GUEST_HANDLE(void), unsigned long len);
-#ifdef COMPAT
         XEN_GUEST_HANDLE(void) data;
-#endif
 
         ret = xsm_microcode();
         if ( ret )
             break;
 
-#ifndef COMPAT
-        ret = microcode_update(op->u.microcode.data,
-                               op->u.microcode.length);
-#else
         guest_from_compat_handle(data, op->u.microcode.data);
         ret = microcode_update(data, op->u.microcode.length);
-#endif
     }
     break;
 
@@ -286,6 +281,9 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
         break;
 
     case XENPF_change_freq:
+        ret = -ENOSYS;
+        if ( cpufreq_controller != FREQCTL_dom0_kernel )
+            break;
         ret = -EINVAL;
         if ( op->u.change_freq.flags != 0 )
             break;
@@ -294,11 +292,46 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
                                         &op->u.change_freq.freq);
         break;
 
+    case XENPF_getidletime:
+    {
+        uint32_t i, nr_cpus;
+        uint64_t idletime;
+        struct vcpu *v;
+        XEN_GUEST_HANDLE(uint64_t) idletimes;
+
+        ret = -ENOSYS;
+        if ( cpufreq_controller != FREQCTL_dom0_kernel )
+            break;
+
+        guest_from_compat_handle(idletimes, op->u.getidletime.idletime);
+        nr_cpus = min_t(uint32_t, op->u.getidletime.max_cpus, NR_CPUS);
+
+        for ( i = 0; i < nr_cpus; i++ )
+        {
+            /* Assume no holes in idle-vcpu map. */
+            if ( (v = idle_vcpu[i]) == NULL )
+                break;
+
+            idletime = v->runstate.time[RUNSTATE_running];
+            if ( v->is_running )
+                idletime += NOW() - v->runstate.state_entry_time;
+
+            ret = -EFAULT;
+            if ( copy_to_guest_offset(idletimes, i, &idletime, 1) )
+                goto out;
+        }
+
+        op->u.getidletime.nr_cpus = i;
+        ret = copy_to_guest(u_xenpf_op, op, 1) ? -EFAULT : 0;
+    }
+    break;
+
     default:
         ret = -ENOSYS;
         break;
     }
 
+ out:
     spin_unlock(&xenpf_lock);
 
     return ret;
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c       Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/time.c       Tue Oct 02 11:31:55 2007 -0600
@@ -728,11 +728,11 @@ int cpu_frequency_change(u64 freq)
     u64 curr_tsc;
 
     local_irq_disable();
-    set_time_scale(&t->tsc_scale, freq);
     rdtscll(curr_tsc);
     t->local_tsc_stamp = curr_tsc;
     t->stime_local_stamp = get_s_time();
     t->stime_master_stamp = read_platform_stime();
+    set_time_scale(&t->tsc_scale, freq);
     local_irq_enable();
 
     /* A full epoch should pass before we check for deviation. */
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/traps.c      Tue Oct 02 11:31:55 2007 -0600
@@ -2009,7 +2009,7 @@ void unset_nmi_callback(void)
     nmi_callback = dummy_nmi_callback;
 }
 
-asmlinkage int math_state_restore(struct cpu_user_regs *regs)
+asmlinkage int do_device_not_available(struct cpu_user_regs *regs)
 {
     BUG_ON(!guest_mode(regs));
 
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/x86_32/domain_page.c
--- a/xen/arch/x86/x86_32/domain_page.c Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/x86_32/domain_page.c Tue Oct 02 11:31:55 2007 -0600
@@ -43,9 +43,10 @@ void *map_domain_page(unsigned long mfn)
 void *map_domain_page(unsigned long mfn)
 {
     unsigned long va;
-    unsigned int idx, i, vcpu;
-    struct vcpu *v;
-    struct mapcache *cache;
+    unsigned int idx, i;
+    struct vcpu *v;
+    struct mapcache_domain *dcache;
+    struct mapcache_vcpu *vcache;
     struct vcpu_maphash_entry *hashent;
 
     ASSERT(!in_irq());
@@ -54,59 +55,59 @@ void *map_domain_page(unsigned long mfn)
 
     v = mapcache_current_vcpu();
 
-    vcpu  = v->vcpu_id;
-    cache = &v->domain->arch.mapcache;
-
-    hashent = &cache->vcpu_maphash[vcpu].hash[MAPHASH_HASHFN(mfn)];
+    dcache = &v->domain->arch.mapcache;
+    vcache = &v->arch.mapcache;
+
+    hashent = &vcache->hash[MAPHASH_HASHFN(mfn)];
     if ( hashent->mfn == mfn )
     {
         idx = hashent->idx;
         hashent->refcnt++;
         ASSERT(idx < MAPCACHE_ENTRIES);
         ASSERT(hashent->refcnt != 0);
-        ASSERT(l1e_get_pfn(cache->l1tab[idx]) == mfn);
+        ASSERT(l1e_get_pfn(dcache->l1tab[idx]) == mfn);
         goto out;
     }
 
-    spin_lock(&cache->lock);
+    spin_lock(&dcache->lock);
 
     /* Has some other CPU caused a wrap? We must flush if so. */
-    if ( unlikely(cache->epoch != cache->shadow_epoch[vcpu]) )
-    {
-        cache->shadow_epoch[vcpu] = cache->epoch;
-        if ( NEED_FLUSH(this_cpu(tlbflush_time), cache->tlbflush_timestamp) )
+    if ( unlikely(dcache->epoch != vcache->shadow_epoch) )
+    {
+        vcache->shadow_epoch = dcache->epoch;
+        if ( NEED_FLUSH(this_cpu(tlbflush_time), dcache->tlbflush_timestamp) )
         {
             perfc_incr(domain_page_tlb_flush);
             local_flush_tlb();
         }
     }
 
-    idx = find_next_zero_bit(cache->inuse, MAPCACHE_ENTRIES, cache->cursor);
+    idx = find_next_zero_bit(dcache->inuse, MAPCACHE_ENTRIES, dcache->cursor);
     if ( unlikely(idx >= MAPCACHE_ENTRIES) )
     {
         /* /First/, clean the garbage map and update the inuse list. */
-        for ( i = 0; i < ARRAY_SIZE(cache->garbage); i++ )
-        {
-            unsigned long x = xchg(&cache->garbage[i], 0);
-            cache->inuse[i] &= ~x;
+        for ( i = 0; i < ARRAY_SIZE(dcache->garbage); i++ )
+        {
+            unsigned long x = xchg(&dcache->garbage[i], 0);
+            dcache->inuse[i] &= ~x;
         }
 
         /* /Second/, flush TLBs. */
         perfc_incr(domain_page_tlb_flush);
         local_flush_tlb();
-        cache->shadow_epoch[vcpu] = ++cache->epoch;
-        cache->tlbflush_timestamp = tlbflush_current_time();
-
-        idx = find_first_zero_bit(cache->inuse, MAPCACHE_ENTRIES);
+        vcache->shadow_epoch = ++dcache->epoch;
+        dcache->tlbflush_timestamp = tlbflush_current_time();
+
+        idx = find_first_zero_bit(dcache->inuse, MAPCACHE_ENTRIES);
         BUG_ON(idx >= MAPCACHE_ENTRIES);
     }
 
-    set_bit(idx, cache->inuse);
-    cache->cursor = idx + 1;
-
-    spin_unlock(&cache->lock);
-
-    l1e_write(&cache->l1tab[idx], l1e_from_pfn(mfn, __PAGE_HYPERVISOR));
+    set_bit(idx, dcache->inuse);
+    dcache->cursor = idx + 1;
+
+    spin_unlock(&dcache->lock);
+
+    l1e_write(&dcache->l1tab[idx], l1e_from_pfn(mfn, __PAGE_HYPERVISOR));
 
  out:
     va = MAPCACHE_VIRT_START + (idx << PAGE_SHIFT);
@@ -117,7 +118,7 @@ void unmap_domain_page(void *va)
 {
     unsigned int idx;
     struct vcpu *v;
-    struct mapcache *cache;
+    struct mapcache_domain *dcache;
     unsigned long mfn;
     struct vcpu_maphash_entry *hashent;
 
@@ -128,11 +129,11 @@ void unmap_domain_page(void *va)
 
     v = mapcache_current_vcpu();
 
-    cache = &v->domain->arch.mapcache;
+    dcache = &v->domain->arch.mapcache;
 
     idx = ((unsigned long)va - MAPCACHE_VIRT_START) >> PAGE_SHIFT;
-    mfn = l1e_get_pfn(cache->l1tab[idx]);
-    hashent = &cache->vcpu_maphash[v->vcpu_id].hash[MAPHASH_HASHFN(mfn)];
+    mfn = l1e_get_pfn(dcache->l1tab[idx]);
+    hashent = &v->arch.mapcache.hash[MAPHASH_HASHFN(mfn)];
 
     if ( hashent->idx == idx )
     {
@@ -145,10 +146,10 @@ void unmap_domain_page(void *va)
         if ( hashent->idx != MAPHASHENT_NOTINUSE )
         {
             /* /First/, zap the PTE. */
-            ASSERT(l1e_get_pfn(cache->l1tab[hashent->idx]) == hashent->mfn);
-            l1e_write(&cache->l1tab[hashent->idx], l1e_empty());
+            ASSERT(l1e_get_pfn(dcache->l1tab[hashent->idx]) == hashent->mfn);
+            l1e_write(&dcache->l1tab[hashent->idx], l1e_empty());
             /* /Second/, mark as garbage. */
-            set_bit(hashent->idx, cache->garbage);
+            set_bit(hashent->idx, dcache->garbage);
         }
 
         /* Add newly-freed mapping to the maphash. */
@@ -158,30 +159,30 @@ void unmap_domain_page(void *va)
     else
     {
         /* /First/, zap the PTE. */
-        l1e_write(&cache->l1tab[idx], l1e_empty());
+        l1e_write(&dcache->l1tab[idx], l1e_empty());
         /* /Second/, mark as garbage. */
-        set_bit(idx, cache->garbage);
-    }
-}
-
-void mapcache_init(struct domain *d)
-{
-    unsigned int i, j;
-    struct vcpu_maphash_entry *hashent;
-
+        set_bit(idx, dcache->garbage);
+    }
+}
+
+void mapcache_domain_init(struct domain *d)
+{
     d->arch.mapcache.l1tab = d->arch.mm_perdomain_pt +
         (GDT_LDT_MBYTES << (20 - PAGE_SHIFT));
     spin_lock_init(&d->arch.mapcache.lock);
+}
+
+void mapcache_vcpu_init(struct vcpu *v)
+{
+    unsigned int i;
+    struct vcpu_maphash_entry *hashent;
 
     /* Mark all maphash entries as not in use. */
-    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
-    {
-        for ( j = 0; j < MAPHASH_ENTRIES; j++ )
-        {
-            hashent = &d->arch.mapcache.vcpu_maphash[i].hash[j];
-            hashent->mfn = ~0UL; /* never valid to map */
-            hashent->idx = MAPHASHENT_NOTINUSE;
-        }
+    for ( i = 0; i < MAPHASH_ENTRIES; i++ )
+    {
+        hashent = &v->arch.mapcache.hash[i];
+        hashent->mfn = ~0UL; /* never valid to map */
+        hashent->idx = MAPHASHENT_NOTINUSE;
     }
 }
 
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S       Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/x86_32/entry.S       Tue Oct 02 11:31:55 2007 -0600
@@ -623,7 +623,7 @@ ENTRY(exception_table)
         .long do_overflow
         .long do_bounds
         .long do_invalid_op
-        .long math_state_restore
+        .long do_device_not_available
         .long 0 # double fault
         .long do_coprocessor_segment_overrun
         .long do_invalid_TSS
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S       Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/arch/x86/x86_64/entry.S       Tue Oct 02 11:31:55 2007 -0600
@@ -559,7 +559,7 @@ ENTRY(exception_table)
         .quad do_overflow
         .quad do_bounds
         .quad do_invalid_op
-        .quad math_state_restore
+        .quad do_device_not_available
         .quad 0 # double_fault
         .quad do_coprocessor_segment_overrun
         .quad do_invalid_TSS
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/common/sysctl.c
--- a/xen/common/sysctl.c       Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/common/sysctl.c       Tue Oct 02 11:31:55 2007 -0600
@@ -177,18 +177,13 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
             if ( v->is_running )
                 cpuinfo.idletime += NOW() - v->runstate.state_entry_time;
 
+            ret = -EFAULT;
             if ( copy_to_guest_offset(op->u.getcpuinfo.info, i, &cpuinfo, 1) )
-            {
-                ret = -EFAULT;
-                break;
-            }
+                goto out;
         }
 
         op->u.getcpuinfo.nr_cpus = i;
-        ret = 0;
-
-        if ( copy_to_guest(u_sysctl, op, 1) )
-            ret = -EFAULT;
+        ret = copy_to_guest(u_sysctl, op, 1) ? -EFAULT : 0;
     }
     break;
 
@@ -209,6 +204,7 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
         break;
     }
 
+ out:
     spin_unlock(&sysctl_lock);
 
     return ret;
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/include/asm-x86/domain.h      Tue Oct 02 11:31:55 2007 -0600
@@ -28,17 +28,21 @@ struct trap_bounce {
 #define MAPHASH_ENTRIES 8
 #define MAPHASH_HASHFN(pfn) ((pfn) & (MAPHASH_ENTRIES-1))
 #define MAPHASHENT_NOTINUSE ((u16)~0U)
-struct vcpu_maphash {
+struct mapcache_vcpu {
+    /* Shadow of mapcache_domain.epoch. */
+    unsigned int shadow_epoch;
+
+    /* Lock-free per-VCPU hash of recently-used mappings. */
     struct vcpu_maphash_entry {
         unsigned long mfn;
         uint16_t      idx;
         uint16_t      refcnt;
     } hash[MAPHASH_ENTRIES];
-} __cacheline_aligned;
+};
 
 #define MAPCACHE_ORDER   10
 #define MAPCACHE_ENTRIES (1 << MAPCACHE_ORDER)
-struct mapcache {
+struct mapcache_domain {
     /* The PTEs that provide the mappings, and a cursor into the array. */
     l1_pgentry_t *l1tab;
     unsigned int cursor;
@@ -47,27 +51,25 @@ struct mapcache {
     spinlock_t lock;
 
     /* Garbage mappings are flushed from TLBs in batches called 'epochs'. */
-    unsigned int epoch, shadow_epoch[MAX_VIRT_CPUS];
+    unsigned int epoch;
     u32 tlbflush_timestamp;
 
     /* Which mappings are in use, and which are garbage to reap next epoch? */
     unsigned long inuse[BITS_TO_LONGS(MAPCACHE_ENTRIES)];
     unsigned long garbage[BITS_TO_LONGS(MAPCACHE_ENTRIES)];
-
-    /* Lock-free per-VCPU hash of recently-used mappings. */
-    struct vcpu_maphash vcpu_maphash[MAX_VIRT_CPUS];
-};
-
-extern void mapcache_init(struct domain *);
+};
+
+void mapcache_domain_init(struct domain *);
+void mapcache_vcpu_init(struct vcpu *);
 
 /* x86/64: toggle guest between kernel and user modes. */
-extern void toggle_guest_mode(struct vcpu *);
+void toggle_guest_mode(struct vcpu *);
 
 /*
  * Initialise a hypercall-transfer page. The given pointer must be mapped
  * in Xen virtual address space (accesses are not validated or checked).
  */
-extern void hypercall_page_initialise(struct domain *d, void *);
+void hypercall_page_initialise(struct domain *d, void *);
 
 /************************************************/
 /*          shadow paging extension             */
@@ -204,7 +206,7 @@ struct arch_domain
 
 #ifdef CONFIG_X86_32
     /* map_domain_page() mapping cache. */
-    struct mapcache mapcache;
+    struct mapcache_domain mapcache;
 #endif
 
 #ifdef CONFIG_COMPAT
@@ -290,7 +292,7 @@ struct arch_vcpu
     struct trap_bounce trap_bounce;
 
     /* I/O-port access bitmap. */
-    XEN_GUEST_HANDLE(uint8_t) iobmp; /* Guest kernel virtual address of the 
bitmap. */
+    XEN_GUEST_HANDLE(uint8_t) iobmp; /* Guest kernel vaddr of the bitmap. */
     int iobmp_limit;  /* Number of ports represented in the bitmap.  */
     int iopl;         /* Current IOPL for this VCPU. */
 
@@ -327,6 +329,12 @@ struct arch_vcpu
 
     /* Guest-specified relocation of vcpu_info. */
     unsigned long vcpu_info_mfn;
+
+#ifdef CONFIG_X86_32
+    /* map_domain_page() mapping cache. */
+    struct mapcache_vcpu mapcache;
+#endif
+
 } __cacheline_aligned;
 
 /* Shorthands to improve code legibility. */
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/include/asm-x86/hvm/hvm.h     Tue Oct 02 11:31:55 2007 -0600
@@ -57,11 +57,26 @@ typedef struct segment_register {
 } __attribute__ ((packed)) segment_register_t;
 
 /* Interrupt acknowledgement sources. */
-enum hvm_intack {
-    hvm_intack_none,
-    hvm_intack_pic,
-    hvm_intack_lapic,
-    hvm_intack_nmi
+enum hvm_intsrc {
+    hvm_intsrc_none,
+    hvm_intsrc_pic,
+    hvm_intsrc_lapic,
+    hvm_intsrc_nmi
+};
+struct hvm_intack {
+    uint8_t source; /* enum hvm_intsrc */
+    uint8_t vector;
+};
+#define hvm_intack_none       ( (struct hvm_intack) { hvm_intsrc_none,  0 } )
+#define hvm_intack_pic(vec)   ( (struct hvm_intack) { hvm_intsrc_pic,   vec } )
+#define hvm_intack_lapic(vec) ( (struct hvm_intack) { hvm_intsrc_lapic, vec } )
+#define hvm_intack_nmi        ( (struct hvm_intack) { hvm_intsrc_nmi,   2 } )
+enum hvm_intblk {
+    hvm_intblk_none,      /* not blocked (deliverable) */
+    hvm_intblk_shadow,    /* MOV-SS or STI shadow */
+    hvm_intblk_rflags_ie, /* RFLAGS.IE == 0 */
+    hvm_intblk_tpr,       /* LAPIC TPR too high */
+    hvm_intblk_nmi_iret   /* NMI blocked until IRET */
 };
 
 /*
@@ -94,7 +109,7 @@ struct hvm_function_table {
      * 3) return the current guest segment descriptor base
      * 4) return the current guest segment descriptor
      */
-    int (*interrupts_enabled)(struct vcpu *v, enum hvm_intack);
+    enum hvm_intblk (*interrupt_blocked)(struct vcpu *v, struct hvm_intack);
     int (*guest_x86_mode)(struct vcpu *v);
     unsigned long (*get_segment_base)(struct vcpu *v, enum x86_segment seg);
     void (*get_segment_register)(struct vcpu *v, enum x86_segment seg,
@@ -177,11 +192,11 @@ u64 hvm_get_guest_time(struct vcpu *v);
 #define hvm_long_mode_enabled(v) (v,0)
 #endif
 
-static inline int
-hvm_interrupts_enabled(struct vcpu *v, enum hvm_intack type)
+static inline enum hvm_intblk
+hvm_interrupt_blocked(struct vcpu *v, struct hvm_intack intack)
 {
     ASSERT(v == current);
-    return hvm_funcs.interrupts_enabled(v, type);
+    return hvm_funcs.interrupt_blocked(v, intack);
 }
 
 static inline int
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/include/asm-x86/hvm/irq.h
--- a/xen/include/asm-x86/hvm/irq.h     Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/include/asm-x86/hvm/irq.h     Tue Oct 02 11:31:55 2007 -0600
@@ -29,7 +29,7 @@
 #include <asm/hvm/vioapic.h>
 #include <public/hvm/save.h>
 
-struct hvm_irq_mapping {
+struct hvm_irq_dpci_mapping {
     uint8_t valid;
     uint8_t device;
     uint8_t intx;
@@ -37,6 +37,14 @@ struct hvm_irq_mapping {
         uint8_t guest_gsi;
         uint8_t machine_gsi;
     };
+};
+
+struct hvm_irq_dpci {
+    /* Machine IRQ to guest device/intx mapping. */
+    struct hvm_irq_dpci_mapping mirq[NR_IRQS];
+    /* Guest IRQ to guest device/intx mapping. */
+    struct hvm_irq_dpci_mapping girq[NR_IRQS];
+    DECLARE_BITMAP(dirq_mask, NR_IRQS);
 };
 
 struct hvm_irq {
@@ -99,11 +107,7 @@ struct hvm_irq {
     /* Last VCPU that was delivered a LowestPrio interrupt. */
     u8 round_robin_prev_vcpu;
 
-    /* machine irq to guest device/intx mapping */
-    struct hvm_irq_mapping mirq[NR_IRQS];
-    /* guest irq to guest device/intx mapping */
-    struct hvm_irq_mapping girq[NR_IRQS];
-    DECLARE_BITMAP(dirq_mask, NR_IRQS);
+    struct hvm_irq_dpci *dpci;
 };
 
 #define hvm_pci_intx_gsi(dev, intx)  \
@@ -135,11 +139,11 @@ void hvm_set_callback_via(struct domain 
 void hvm_set_callback_via(struct domain *d, uint64_t via);
 
 /* Check/Acknowledge next pending interrupt. */
-enum hvm_intack hvm_vcpu_has_pending_irq(struct vcpu *v);
-int hvm_vcpu_ack_pending_irq(
-    struct vcpu *v, enum hvm_intack type, int *vector);
+struct hvm_intack hvm_vcpu_has_pending_irq(struct vcpu *v);
+struct hvm_intack hvm_vcpu_ack_pending_irq(struct vcpu *v,
+                                           struct hvm_intack intack);
 
-int get_isa_irq_vector(struct vcpu *vcpu, int irq, enum hvm_intack src);
+int get_isa_irq_vector(struct vcpu *vcpu, int irq, enum hvm_intsrc src);
 int is_isa_irq_masked(struct vcpu *v, int isa_irq);
 
 #endif /* __ASM_X86_HVM_IRQ_H__ */
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/include/asm-x86/hvm/vlapic.h
--- a/xen/include/asm-x86/hvm/vlapic.h  Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/include/asm-x86/hvm/vlapic.h  Tue Oct 02 11:31:55 2007 -0600
@@ -75,8 +75,8 @@ int vlapic_set_irq(struct vlapic *vlapic
 
 int vlapic_find_highest_irr(struct vlapic *vlapic);
 
-int vlapic_has_interrupt(struct vcpu *v);
-int cpu_get_apic_interrupt(struct vcpu *v);
+int vlapic_has_pending_irq(struct vcpu *v);
+int vlapic_ack_pending_irq(struct vcpu *v, int vector);
 
 int  vlapic_init(struct vcpu *v);
 void vlapic_destroy(struct vcpu *v);
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/include/asm-x86/hvm/vpic.h
--- a/xen/include/asm-x86/hvm/vpic.h    Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/include/asm-x86/hvm/vpic.h    Tue Oct 02 11:31:55 2007 -0600
@@ -32,7 +32,7 @@ void vpic_irq_positive_edge(struct domai
 void vpic_irq_positive_edge(struct domain *d, int irq);
 void vpic_irq_negative_edge(struct domain *d, int irq);
 void vpic_init(struct domain *d);
-int cpu_get_pic_interrupt(struct vcpu *v);
+int vpic_ack_pending_irq(struct vcpu *v);
 int is_periodic_irq(struct vcpu *v, int irq, int type);
 
 #endif  /* __ASM_X86_HVM_VPIC_H__ */  
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h     Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/include/asm-x86/hvm/vpt.h     Tue Oct 02 11:31:55 2007 -0600
@@ -120,7 +120,7 @@ void pt_freeze_time(struct vcpu *v);
 void pt_freeze_time(struct vcpu *v);
 void pt_thaw_time(struct vcpu *v);
 void pt_update_irq(struct vcpu *v);
-void pt_intr_post(struct vcpu *v, int vector, enum hvm_intack src);
+void pt_intr_post(struct vcpu *v, struct hvm_intack intack);
 void pt_reset(struct vcpu *v);
 void pt_migrate(struct vcpu *v);
 void create_periodic_time(
diff -r d6c09be8c5f5 -r 3165e43ce734 xen/include/public/platform.h
--- a/xen/include/public/platform.h     Tue Oct 02 10:07:35 2007 -0600
+++ b/xen/include/public/platform.h     Tue Oct 02 11:31:55 2007 -0600
@@ -164,7 +164,7 @@ typedef struct xenpf_enter_acpi_sleep xe
 typedef struct xenpf_enter_acpi_sleep xenpf_enter_acpi_sleep_t;
 DEFINE_XEN_GUEST_HANDLE(xenpf_enter_acpi_sleep_t);
 
-#define XENPF_change_freq       52
+#define XENPF_change_freq         52
 struct xenpf_change_freq {
     /* IN variables */
     uint32_t flags; /* Must be zero. */
@@ -173,6 +173,17 @@ struct xenpf_change_freq {
 };
 typedef struct xenpf_change_freq xenpf_change_freq_t;
 DEFINE_XEN_GUEST_HANDLE(xenpf_change_freq_t);
+
+#define XENPF_getidletime         53
+struct xenpf_getidletime {
+    /* IN variables. */
+    uint32_t max_cpus;
+    XEN_GUEST_HANDLE(uint64_t) idletime;
+    /* OUT variables. */
+    uint32_t nr_cpus;
+};
+typedef struct xenpf_getidletime xenpf_getidletime_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_getidletime_t);
 
 struct xen_platform_op {
     uint32_t cmd;
@@ -187,6 +198,7 @@ struct xen_platform_op {
         struct xenpf_firmware_info     firmware_info;
         struct xenpf_enter_acpi_sleep  enter_acpi_sleep;
         struct xenpf_change_freq       change_freq;
+        struct xenpf_getidletime       getidletime;
         uint8_t                        pad[128];
     } u;
 };

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

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