# 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
|