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-3.1-testing] Merge with xen-unstable for 3.1.0-rc5.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-3.1-testing] Merge with xen-unstable for 3.1.0-rc5.
From: "Xen patchbot-3.1-testing" <patchbot-3.1-testing@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 02 May 2007 12:50:26 -0700
Delivery-date: Wed, 02 May 2007 13:07:33 -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 kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1178116030 -3600
# Node ID b5cfbc8f7d2c2d04d55b7361cc035d5e3b8efd99
# Parent  bf96999a2ffdbe0687b132d9a384311531366b39
# Parent  aeac9a7d97e0840a7c9a916c130c865b0b1ff6db
Merge with xen-unstable for 3.1.0-rc5.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c |    6 -
 linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c   |    6 -
 tools/console/daemon/io.c                          |   70 ++++++++++++++++++---
 tools/ioemu/keymaps/modifiers                      |    1 
 tools/ioemu/vnc_keysym.h                           |    1 
 tools/libxc/xc_domain_save.c                       |   13 +++
 tools/python/xen/xend/XendConfig.py                |   13 +--
 tools/python/xen/xend/XendDomain.py                |    2 
 tools/python/xen/xend/XendDomainInfo.py            |   12 ++-
 tools/python/xen/xend/XendPIF.py                   |    2 
 xen/Makefile                                       |    4 -
 xen/arch/ia64/xen/xensetup.c                       |    4 -
 xen/arch/powerpc/setup.c                           |    4 -
 xen/arch/x86/hvm/svm/svm.c                         |   61 +++++++++++++++++-
 xen/arch/x86/hvm/vmx/vmx.c                         |   66 +++++++++++++++++++
 xen/arch/x86/setup.c                               |    4 -
 xen/include/public/hvm/save.h                      |   14 ++++
 17 files changed, 243 insertions(+), 40 deletions(-)

diff -r bf96999a2ffd -r b5cfbc8f7d2c 
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Sun Apr 29 
09:39:33 2007 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Wed May 02 
15:27:10 2007 +0100
@@ -70,7 +70,7 @@ module_param(debug_lvl, int, 0644);
  */
 typedef struct {
        blkif_t       *blkif;
-       unsigned long  id;
+       u64            id;
        int            nr_pages;
        atomic_t       pendcnt;
        unsigned short operation;
@@ -107,7 +107,7 @@ static void dispatch_rw_block_io(blkif_t
 static void dispatch_rw_block_io(blkif_t *blkif,
                                 blkif_request_t *req,
                                 pending_req_t *pending_req);
-static void make_response(blkif_t *blkif, unsigned long id, 
+static void make_response(blkif_t *blkif, u64 id,
                          unsigned short op, int st);
 
 /******************************************************************
@@ -515,7 +515,7 @@ static void dispatch_rw_block_io(blkif_t
  */
 
 
-static void make_response(blkif_t *blkif, unsigned long id, 
+static void make_response(blkif_t *blkif, u64 id,
                          unsigned short op, int st)
 {
        blkif_response_t  resp;
diff -r bf96999a2ffd -r b5cfbc8f7d2c 
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c  Sun Apr 29 09:39:33 
2007 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c  Wed May 02 15:27:10 
2007 +0100
@@ -136,7 +136,7 @@ module_param(debug_lvl, int, 0644);
  */
 typedef struct {
        blkif_t       *blkif;
-       unsigned long  id;
+       u64            id;
        unsigned short mem_idx;
        int            nr_pages;
        atomic_t       pendcnt;
@@ -741,7 +741,7 @@ static void dispatch_rw_block_io(blkif_t
 static void dispatch_rw_block_io(blkif_t *blkif,
                                 blkif_request_t *req,
                                 pending_req_t *pending_req);
-static void make_response(blkif_t *blkif, unsigned long id, 
+static void make_response(blkif_t *blkif, u64 id,
                           unsigned short op, int st);
 
 /******************************************************************
@@ -1408,7 +1408,7 @@ static void dispatch_rw_block_io(blkif_t
  */
 
 
-static void make_response(blkif_t *blkif, unsigned long id, 
+static void make_response(blkif_t *blkif, u64 id,
                           unsigned short op, int st)
 {
        blkif_response_t  resp;
diff -r bf96999a2ffd -r b5cfbc8f7d2c tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Sun Apr 29 09:39:33 2007 +0100
+++ b/tools/console/daemon/io.c Wed May 02 15:27:10 2007 +0100
@@ -61,6 +61,8 @@ struct domain
        struct buffer buffer;
        struct domain *next;
        char *conspath;
+       char *serialpath;
+       int use_consolepath;
        int ring_ref;
        evtchn_port_t local_port;
        evtchn_port_t remote_port;
@@ -164,7 +166,20 @@ static int domain_create_tty(struct doma
                        tcsetattr(master, TCSAFLUSH, &term);
                }
 
-               success = asprintf(&path, "%s/limit", dom->conspath) != -1;
+               if (dom->use_consolepath) {
+                       success = asprintf(&path, "%s/limit", dom->conspath) !=
+                               -1;
+                       if (!success)
+                               goto out;
+                       data = xs_read(xs, XBT_NULL, path, &len);
+                       if (data) {
+                               dom->buffer.max_capacity = strtoul(data, 0, 0);
+                               free(data);
+                       }
+                       free(path);
+               }
+
+               success = asprintf(&path, "%s/limit", dom->serialpath) != -1;
                if (!success)
                        goto out;
                data = xs_read(xs, XBT_NULL, path, &len);
@@ -174,13 +189,25 @@ static int domain_create_tty(struct doma
                }
                free(path);
 
-               success = asprintf(&path, "%s/tty", dom->conspath) != -1;
+               success = asprintf(&path, "%s/tty", dom->serialpath) != -1;
                if (!success)
                        goto out;
                success = xs_write(xs, XBT_NULL, path, slave, strlen(slave));
                free(path);
                if (!success)
                        goto out;
+
+               if (dom->use_consolepath) {
+                       success = asprintf(&path, "%s/tty", dom->conspath) !=
+                               -1;
+                       if (!success)
+                               goto out;
+                       success = xs_write(xs, XBT_NULL, path, slave,
+                                          strlen(slave));
+                       free(path);
+                       if (!success)
+                               goto out;
+               }
 
                if (fcntl(master, F_SETFL, O_NONBLOCK) == -1)
                        goto out;
@@ -228,12 +255,20 @@ static int domain_create_ring(struct dom
 {
        int err, remote_port, ring_ref, rc;
 
-       err = xs_gather(xs, dom->conspath,
+       err = xs_gather(xs, dom->serialpath,
                        "ring-ref", "%u", &ring_ref,
                        "port", "%i", &remote_port,
                        NULL);
-       if (err)
-               goto out;
+       if (err) {
+               err = xs_gather(xs, dom->conspath,
+                               "ring-ref", "%u", &ring_ref,
+                               "port", "%i", &remote_port,
+                               NULL);
+               if (err)
+                       goto out;
+               dom->use_consolepath = 1;
+       } else
+               dom->use_consolepath = 0;
 
        if ((ring_ref == dom->ring_ref) && (remote_port == dom->remote_port))
                goto out;
@@ -301,10 +336,16 @@ static bool watch_domain(struct domain *
 
        sprintf(domid_str, "dom%u", dom->domid);
        if (watch) {
-               success = xs_watch(xs, dom->conspath, domid_str);
-               if (success)
-                       domain_create_ring(dom);
+               success = xs_watch(xs, dom->serialpath, domid_str);
+               if (success) {
+                       success = xs_watch(xs, dom->conspath, domid_str);
+                       if (success)
+                               domain_create_ring(dom);
+                       else
+                               xs_unwatch(xs, dom->serialpath, domid_str);
+               }
        } else {
+               success = xs_unwatch(xs, dom->serialpath, domid_str);
                success = xs_unwatch(xs, dom->conspath, domid_str);
        }
 
@@ -324,6 +365,15 @@ static struct domain *create_domain(int 
        }
 
        dom->domid = domid;
+
+       dom->serialpath = xs_get_domain_path(xs, dom->domid);
+       s = realloc(dom->serialpath, strlen(dom->serialpath) +
+                   strlen("/serial/0") + 1);
+       if (s == NULL)
+               goto out;
+       dom->serialpath = s;
+       strcat(dom->serialpath, "/serial/0");
+
        dom->conspath = xs_get_domain_path(xs, dom->domid);
        s = realloc(dom->conspath, strlen(dom->conspath) +
                    strlen("/console") + 1);
@@ -357,6 +407,7 @@ static struct domain *create_domain(int 
 
        return dom;
  out:
+       free(dom->serialpath);
        free(dom->conspath);
        free(dom);
        return NULL;
@@ -396,6 +447,9 @@ static void cleanup_domain(struct domain
 
        free(d->buffer.data);
        d->buffer.data = NULL;
+
+       free(d->serialpath);
+       d->serialpath = NULL;
 
        free(d->conspath);
        d->conspath = NULL;
diff -r bf96999a2ffd -r b5cfbc8f7d2c tools/ioemu/keymaps/modifiers
--- a/tools/ioemu/keymaps/modifiers     Sun Apr 29 09:39:33 2007 +0100
+++ b/tools/ioemu/keymaps/modifiers     Wed May 02 15:27:10 2007 +0100
@@ -3,6 +3,7 @@ Shift_L 0x2a
 
 Alt_R 0xb8
 Mode_switch 0xb8
+ISO_Level3_Switch 0xb8
 Alt_L 0x38
 
 Control_R 0x9d
diff -r bf96999a2ffd -r b5cfbc8f7d2c tools/ioemu/vnc_keysym.h
--- a/tools/ioemu/vnc_keysym.h  Sun Apr 29 09:39:33 2007 +0100
+++ b/tools/ioemu/vnc_keysym.h  Wed May 02 15:27:10 2007 +0100
@@ -215,6 +215,7 @@ static name2keysym_t name2keysym[]={
 {"Shift_R", 0xffe2},   /* XK_Shift_R */
 {"Super_L", 0xffeb},   /* XK_Super_L */
 {"Super_R", 0xffec},   /* XK_Super_R */
+{"ISO_Level3_Shift", 0xfe03}, /* XK_ISO_Level3_Shift */
 
     /* special keys */
 {"BackSpace", 0xff08}, /* XK_BackSpace */
diff -r bf96999a2ffd -r b5cfbc8f7d2c tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c      Sun Apr 29 09:39:33 2007 +0100
+++ b/tools/libxc/xc_domain_save.c      Wed May 02 15:27:10 2007 +0100
@@ -880,8 +880,17 @@ int xc_domain_save(int xc_handle, int io
                                XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY,
                                NULL, 0, NULL, 0, NULL) < 0 )
         {
-            ERROR("Couldn't enable shadow mode");
-            goto out;
+            /* log-dirty already enabled? There's no test op,
+               so attempt to disable then reenable it */
+            if ( !(xc_shadow_control(xc_handle, dom, XEN_DOMCTL_SHADOW_OP_OFF,
+                                     NULL, 0, NULL, 0, NULL) >= 0 &&
+                   xc_shadow_control(xc_handle, dom,
+                                     XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY,
+                                     NULL, 0, NULL, 0, NULL) >= 0) )
+            {
+                ERROR("Couldn't enable shadow mode");
+                goto out;
+            }
         }
 
         if ( hvm )
diff -r bf96999a2ffd -r b5cfbc8f7d2c tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Sun Apr 29 09:39:33 2007 +0100
+++ b/tools/python/xen/xend/XendConfig.py       Wed May 02 15:27:10 2007 +0100
@@ -988,19 +988,16 @@ class XendConfig(dict):
                 if param not in target:
                     target[param] = []
                 if dev_uuid not in target[param]:
-                    if dev_type == 'vbd' and not target[param]:
-                        # Compat hack -- this is the first disk, so mark it
-                        # bootable.
-                        dev_info['bootable'] = 1
+                    if dev_type == 'vbd':
+                        # Compat hack -- mark first disk bootable
+                        dev_info['bootable'] = int(not target[param])
                     target[param].append(dev_uuid)
             elif dev_type == 'tap':
                 if 'vbd_refs' not in target:
                     target['vbd_refs'] = []
                 if dev_uuid not in target['vbd_refs']:
-                    if not target['vbd_refs']:
-                        # Compat hack -- this is the first disk, so mark it
-                        # bootable.
-                        dev_info['bootable'] = 1
+                    # Compat hack -- mark first disk bootable
+                    dev_info['bootable'] = int(not target['vbd_refs'])
                     target['vbd_refs'].append(dev_uuid)
                     
             elif dev_type == 'vfb':
diff -r bf96999a2ffd -r b5cfbc8f7d2c tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Sun Apr 29 09:39:33 2007 +0100
+++ b/tools/python/xen/xend/XendDomain.py       Wed May 02 15:27:10 2007 +0100
@@ -1227,7 +1227,7 @@ class XendDomain:
         XendCheckpoint.save(sock.fileno(), dominfo, True, live, dst)
         sock.close()
 
-    def domain_save(self, domid, dst, checkpoint):
+    def domain_save(self, domid, dst, checkpoint=False):
         """Start saving a domain to file.
 
         @param domid: Domain ID or Name
diff -r bf96999a2ffd -r b5cfbc8f7d2c tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Sun Apr 29 09:39:33 2007 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py   Wed May 02 15:27:10 2007 +0100
@@ -885,7 +885,7 @@ class XendDomainInfo:
 
         # Check whether image definition has been updated
         image_sxp = self._readVm('image')
-        if image_sxp and image_sxp != self.info.image_sxpr():
+        if image_sxp and image_sxp != sxp.to_string(self.info.image_sxpr()):
             self.info.update_with_image_sxp(sxp.from_string(image_sxp))
             changed = True
 
@@ -1419,9 +1419,13 @@ class XendDomainInfo:
                 raise VmError("HVM guest support is unavailable: is VT/AMD-V "
                               "supported by your CPU and enabled in your "
                               "BIOS?")
-            # Hack to pre-reserve some memory for HVM setup.
-            # Needed because Xen allocates 1MB by default immediately.
-            balloon.free(2*1024) # 2MB should be plenty
+
+        # Hack to pre-reserve some memory for initial domain creation.
+        # There is an implicit memory overhead for any domain creation. This
+        # overhead is greater for some types of domain than others. For
+        # example, an x86 HVM domain will have a default shadow-pagetable
+        # allocation of 1MB. We free up 2MB here to be on the safe side.
+        balloon.free(2*1024) # 2MB should be plenty
 
         self.domid = xc.domain_create(
             domid = 0,
diff -r bf96999a2ffd -r b5cfbc8f7d2c tools/python/xen/xend/XendPIF.py
--- a/tools/python/xen/xend/XendPIF.py  Sun Apr 29 09:39:33 2007 +0100
+++ b/tools/python/xen/xend/XendPIF.py  Wed May 02 15:27:10 2007 +0100
@@ -306,7 +306,7 @@ class XendPIF(XendBase):
         # Figure out if this is a physical device
         if self.get_interface_name() == \
            self.get_device():
-            raise PIFIsPhysical(self.get_uuid())
+            raise PIFIsPhysical()
 
         self.unplug()
 
diff -r bf96999a2ffd -r b5cfbc8f7d2c xen/Makefile
--- a/xen/Makefile      Sun Apr 29 09:39:33 2007 +0100
+++ b/xen/Makefile      Wed May 02 15:27:10 2007 +0100
@@ -1,8 +1,8 @@
 # This is the correct place to edit the build version.
 # All other places this is stored (eg. compile.h) should be autogenerated.
 export XEN_VERSION       = 3
-export XEN_SUBVERSION    = 0
-export XEN_EXTRAVERSION ?= .5-rc4$(XEN_VENDORVERSION)
+export XEN_SUBVERSION    = 1
+export XEN_EXTRAVERSION ?= .0-rc5$(XEN_VENDORVERSION)
 export XEN_FULLVERSION   = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
 -include xen-version
 
diff -r bf96999a2ffd -r b5cfbc8f7d2c xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c      Sun Apr 29 09:39:33 2007 +0100
+++ b/xen/arch/ia64/xen/xensetup.c      Wed May 02 15:27:10 2007 +0100
@@ -551,8 +551,8 @@ printk("num_online_cpus=%d, max_cpus=%d\
 
 void arch_get_xen_caps(xen_capabilities_info_t *info)
 {
-    int major = xen_major_version();
-    int minor = xen_minor_version();
+    /* Interface name is always xen-3.0-* for Xen-3.x. */
+    int major = 3, minor = 0;
     char s[32];
 
     (*info)[0] = '\0';
diff -r bf96999a2ffd -r b5cfbc8f7d2c xen/arch/powerpc/setup.c
--- a/xen/arch/powerpc/setup.c  Sun Apr 29 09:39:33 2007 +0100
+++ b/xen/arch/powerpc/setup.c  Wed May 02 15:27:10 2007 +0100
@@ -448,8 +448,8 @@ extern void arch_get_xen_caps(xen_capabi
 extern void arch_get_xen_caps(xen_capabilities_info_t *info);
 void arch_get_xen_caps(xen_capabilities_info_t *info)
 {
-    int major = xen_major_version();
-    int minor = xen_minor_version();
+    /* Interface name is always xen-3.0-* for Xen-3.x. */
+    int major = 3, minor = 0;
     char s[32];
 
     (*info)[0] = '\0';
diff -r bf96999a2ffd -r b5cfbc8f7d2c xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Sun Apr 29 09:39:33 2007 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c        Wed May 02 15:27:10 2007 +0100
@@ -307,6 +307,41 @@ int svm_vmcb_save(struct vcpu *v, struct
     c->sysenter_esp = vmcb->sysenter_esp;
     c->sysenter_eip = vmcb->sysenter_eip;
 
+    /* Save any event/interrupt that was being injected when we last
+     * exited.  Although there are three(!) VMCB fields that can contain
+     * active events, we only need to save at most one: because the
+     * intr_assist logic never delivers an IRQ when any other event is
+     * active, we know that the only possible collision is if we inject
+     * a fault while exitintinfo contains a valid event (the delivery of
+     * which caused the last exit).  In that case replaying just the
+     * first event should cause the same behaviour when we restore. */
+    if ( vmcb->vintr.fields.irq 
+         && /* Check it's not a fake interrupt (see svm_intr_assist()) */
+         !(vmcb->general1_intercepts & GENERAL1_INTERCEPT_VINTR) )
+    {
+        c->pending_vector = vmcb->vintr.fields.vector;
+        c->pending_type = 0; /* External interrupt */
+        c->pending_error_valid = 0;
+        c->pending_reserved = 0;
+        c->pending_valid = 1;
+        c->error_code = 0;
+    }
+    else if ( vmcb->exitintinfo.fields.v )
+    {
+        c->pending_event = vmcb->exitintinfo.bytes & 0xffffffff;
+        c->error_code = vmcb->exitintinfo.fields.errorcode;
+    }
+    else if ( vmcb->eventinj.fields.v ) 
+    {
+        c->pending_event = vmcb->eventinj.bytes & 0xffffffff;
+        c->error_code = vmcb->eventinj.fields.errorcode;
+    }
+    else 
+    {
+        c->pending_event = 0;
+        c->error_code = 0;
+    }
+
     return 1;
 }
 
@@ -335,7 +370,7 @@ int svm_vmcb_restore(struct vcpu *v, str
 
     if ( !svm_paging_enabled(v) ) 
     {
-        printk("%s: paging not enabled.", __func__);
+        printk("%s: paging not enabled.\n", __func__);
         goto skip_cr3;
     }
 
@@ -436,11 +471,33 @@ int svm_vmcb_restore(struct vcpu *v, str
     vmcb->dr6 = c->dr6;
     vmcb->dr7 = c->dr7;
 
+    if ( c->pending_valid ) 
+    {
+        gdprintk(XENLOG_INFO, "Re-injecting 0x%"PRIx32", 0x%"PRIx32"\n",
+                 c->pending_event, c->error_code);
+
+        /* VMX uses a different type for #OF and #BP; fold into "Exception"  */
+        if ( c->pending_type == 6 ) 
+            c->pending_type = 3;
+        /* Sanity check */
+        if ( c->pending_type == 1 || c->pending_type > 4 
+             || c->pending_reserved != 0 )
+        {
+            gdprintk(XENLOG_ERR, "Invalid pending event 0x%"PRIx32"\n", 
+                     c->pending_event);
+            return -EINVAL;
+        }
+        /* Put this pending event in exitintinfo and svm_intr_assist()
+         * will reinject it when we return to the guest. */
+        vmcb->exitintinfo.bytes = c->pending_event;
+        vmcb->exitintinfo.fields.errorcode = c->error_code;
+    }
+
     paging_update_paging_modes(v);
     return 0;
  
  bad_cr3:
-    gdprintk(XENLOG_ERR, "Invalid CR3 value=0x%"PRIx64"", c->cr3);
+    gdprintk(XENLOG_ERR, "Invalid CR3 value=0x%"PRIx64"\n", c->cr3);
     return -EINVAL;
 }
 
diff -r bf96999a2ffd -r b5cfbc8f7d2c xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Sun Apr 29 09:39:33 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Wed May 02 15:27:10 2007 +0100
@@ -370,6 +370,8 @@ static inline void __restore_debug_regis
 
 int vmx_vmcs_save(struct vcpu *v, struct hvm_hw_cpu *c)
 {    
+    uint32_t ev;
+
     c->rip = __vmread(GUEST_RIP);
     c->rsp = __vmread(GUEST_RSP);
     c->rflags = __vmread(GUEST_RFLAGS);
@@ -435,6 +437,28 @@ int vmx_vmcs_save(struct vcpu *v, struct
     c->sysenter_cs = __vmread(GUEST_SYSENTER_CS);
     c->sysenter_esp = __vmread(GUEST_SYSENTER_ESP);
     c->sysenter_eip = __vmread(GUEST_SYSENTER_EIP);
+
+    /* Save any event/interrupt that was being injected when we last
+     * exited.  IDT_VECTORING_INFO_FIELD has priority, as anything in
+     * VM_ENTRY_INTR_INFO_FIELD is either a fault caused by the first
+     * event, which will happen the next time, or an interrupt, which we
+     * never inject when IDT_VECTORING_INFO_FIELD is valid.*/
+    if ( (ev = __vmread(IDT_VECTORING_INFO_FIELD)) & INTR_INFO_VALID_MASK ) 
+    {
+        c->pending_event = ev;
+        c->error_code = __vmread(IDT_VECTORING_ERROR_CODE);
+    }
+    else if ( (ev = __vmread(VM_ENTRY_INTR_INFO_FIELD)) 
+              & INTR_INFO_VALID_MASK ) 
+    {
+        c->pending_event = ev;
+        c->error_code = __vmread(VM_ENTRY_EXCEPTION_ERROR_CODE);
+    }
+    else 
+    {
+        c->pending_event = 0;
+        c->error_code = 0;
+    }
 
     return 1;
 }
@@ -563,6 +587,48 @@ int vmx_vmcs_restore(struct vcpu *v, str
     vmx_vmcs_exit(v);
 
     paging_update_paging_modes(v);
+
+    if ( c->pending_valid ) 
+    {
+        vmx_vmcs_enter(v);
+        gdprintk(XENLOG_INFO, "Re-injecting 0x%"PRIx32", 0x%"PRIx32"\n",
+                 c->pending_event, c->error_code);
+
+        /* SVM uses type 3 ("Exception") for #OF and #BP; VMX uses type 6 */
+        if ( c->pending_type == 3 
+             && (c->pending_vector == 3 || c->pending_vector == 4) ) 
+            c->pending_type = 6;
+
+        /* For software exceptions, we need to tell the hardware the 
+         * instruction length as well (hmmm). */
+        if ( c->pending_type > 4 ) 
+        {
+            int addrbytes, ilen; 
+            if ( (c->cs_arbytes & (1u<<13)) && (c->msr_efer & EFER_LMA) ) 
+                addrbytes = 8;
+            else if ( (c->cs_arbytes & (1u<<14)) ) 
+                addrbytes = 4;
+            else 
+                addrbytes = 2;
+            ilen = hvm_instruction_length(c->rip, addrbytes);
+            __vmwrite(VM_ENTRY_INSTRUCTION_LEN, ilen);
+        }
+
+        /* Sanity check */
+        if ( c->pending_type == 1 || c->pending_type > 6
+             || c->pending_reserved != 0 )
+        {
+            gdprintk(XENLOG_ERR, "Invalid pending event 0x%"PRIx32"\n", 
+                     c->pending_event);
+            return -EINVAL;
+        }
+        /* Re-inject the exception */
+        __vmwrite(VM_ENTRY_INTR_INFO_FIELD, c->pending_event);
+        __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, c->error_code);
+        v->arch.hvm_vmx.vector_injected = 1;
+        vmx_vmcs_exit(v);
+    }
+
     return 0;
 
  bad_cr3:
diff -r bf96999a2ffd -r b5cfbc8f7d2c xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Sun Apr 29 09:39:33 2007 +0100
+++ b/xen/arch/x86/setup.c      Wed May 02 15:27:10 2007 +0100
@@ -798,8 +798,8 @@ void __init __start_xen(multiboot_info_t
 
 void arch_get_xen_caps(xen_capabilities_info_t *info)
 {
-    int major = xen_major_version();
-    int minor = xen_minor_version();
+    /* Interface name is always xen-3.0-* for Xen-3.x. */
+    int major = 3, minor = 0;
     char s[32];
 
     (*info)[0] = '\0';
diff -r bf96999a2ffd -r b5cfbc8f7d2c xen/include/public/hvm/save.h
--- a/xen/include/public/hvm/save.h     Sun Apr 29 09:39:33 2007 +0100
+++ b/xen/include/public/hvm/save.h     Wed May 02 15:27:10 2007 +0100
@@ -182,6 +182,20 @@ struct hvm_hw_cpu {
 
     /* guest's idea of what rdtsc() would return */
     uint64_t tsc;
+
+    /* pending event, if any */
+    union {
+        uint32_t pending_event;
+        struct {
+            uint8_t  pending_vector:8;
+            uint8_t  pending_type:3;
+            uint8_t  pending_error_valid:1;
+            uint32_t pending_reserved:19;
+            uint8_t  pending_valid:1;
+        };
+    };
+    /* error code for pending event */
+    uint32_t error_code;
 };
 
 DECLARE_HVM_SAVE_TYPE(CPU, 2, struct hvm_hw_cpu);

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-3.1-testing] Merge with xen-unstable for 3.1.0-rc5., Xen patchbot-3.1-testing <=