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

[Xen-changelog] [xen-unstable] xc_resume: fix modify_returncode when host width != guest width



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1257373921 0
# Node ID 23b43708aad602ce5c24222ef4321c6c65078187
# Parent  ba19b6a208cd7788fe228bb4043c5a1650ccb5ae
xc_resume: fix modify_returncode when host width != guest width

Also improve checking in xc_domain_resume_any().

Signed-off-by: Brendan Cully <brendan@xxxxxxxxx>
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 tools/libxc/xc_resume.c |   56 +++++++++++++++++++++++++++++++++---------------
 1 files changed, 39 insertions(+), 17 deletions(-)

diff -r ba19b6a208cd -r 23b43708aad6 tools/libxc/xc_resume.c
--- a/tools/libxc/xc_resume.c   Wed Nov 04 18:14:02 2009 +0000
+++ b/tools/libxc/xc_resume.c   Wed Nov 04 22:32:01 2009 +0000
@@ -8,15 +8,25 @@
 #include <xen/foreign/x86_64.h>
 #include <xen/hvm/params.h>
 
-/* Don't yet support cross-address-size uncooperative resume */
-#define guest_width (sizeof (unsigned long))
+static int pv_guest_width(int xc_handle, uint32_t domid)
+{
+    DECLARE_DOMCTL;
+    domctl.domain = domid;
+    domctl.cmd = XEN_DOMCTL_get_address_size;
+    if ( xc_domctl(xc_handle, &domctl) != 0 )
+    {
+        PERROR("Could not get guest address size");
+        return -1;
+    }
+    return domctl.u.address_size.size / 8;
+}
 
 static int modify_returncode(int xc_handle, uint32_t domid)
 {
     vcpu_guest_context_any_t ctxt;
     xc_dominfo_t info;
     xen_capabilities_info_t caps;
-    int rc;
+    int rc, guest_width;
 
     if ( xc_domain_getinfo(xc_handle, domid, 1, &info) != 1 )
     {
@@ -24,30 +34,34 @@ static int modify_returncode(int xc_hand
         return -1;
     }
 
-    /* HVM guests without PV drivers do not have a return code to modify. */
     if ( info.hvm )
     {
+        /* HVM guests without PV drivers have no return code to modify. */
         unsigned long irq = 0;
         xc_get_hvm_param(xc_handle, domid, HVM_PARAM_CALLBACK_IRQ, &irq);
         if ( !irq )
             return 0;
-    }
-
-    if ( xc_version(xc_handle, XENVER_capabilities, &caps) != 0 )
-    {
-        PERROR("Could not get Xen capabilities\n");
-        return -1;
+
+        /* HVM guests have host address width. */
+        if ( xc_version(xc_handle, XENVER_capabilities, &caps) != 0 )
+        {
+            PERROR("Could not get Xen capabilities\n");
+            return -1;
+        }
+        guest_width = strstr(caps, "x86_64") ? 8 : 4;
+    }
+    else
+    {
+        /* Probe PV guest address width. */
+        guest_width = pv_guest_width(xc_handle, domid);
+        if ( guest_width < 0 )
+            return -1;
     }
 
     if ( (rc = xc_vcpu_getcontext(xc_handle, domid, 0, &ctxt)) != 0 )
         return rc;
 
-    if ( !info.hvm )
-        ctxt.c.user_regs.eax = 1;
-    else if ( strstr(caps, "x86_64") )
-        ctxt.x64.user_regs.eax = 1;
-    else
-        ctxt.x32.user_regs.eax = 1;
+    SET_FIELD(&ctxt, user_regs.eax, 1);
 
     if ( (rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt)) != 0 )
         return rc;
@@ -88,6 +102,7 @@ static int xc_domain_resume_any(int xc_h
     xc_dominfo_t info;
     int i, rc = -1;
 #if defined(__i386__) || defined(__x86_64__)
+    int guest_width;
     unsigned long mfn, p2m_size = 0;
     vcpu_guest_context_any_t ctxt;
     start_info_t *start_info;
@@ -110,6 +125,13 @@ static int xc_domain_resume_any(int xc_h
     if ( info.hvm )
     {
         ERROR("Cannot resume uncooperative HVM guests");
+        return rc;
+    }
+
+    guest_width = pv_guest_width(xc_handle, domid);
+    if ( guest_width != sizeof(long) )
+    {
+        ERROR("Cannot resume uncooperative cross-address-size guests");
         return rc;
     }
 
@@ -167,7 +189,7 @@ static int xc_domain_resume_any(int xc_h
         goto out;
     }
 
-    mfn = ctxt.c.user_regs.edx;
+    mfn = GET_FIELD(&ctxt, user_regs.edx);
 
     start_info = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
                                       PROT_READ | PROT_WRITE, mfn);

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


 


Rackspace

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