# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1176383584 -3600
# Node ID a839e331f06f7b19ca601b277de9fcbedbeb4a77
# Parent 8f7f29f718a65e4a7a0f5d57f5cfc019a6f8cd93
HVM: First attempt at domain-resume on save-failure.
Not working yet as we are a bit too keen to kill the qemu-dm process,
before we know that the save has been successful.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
tools/libxc/xc_domain.c | 39 ++++++++++++++++++++++++
tools/libxc/xc_hvm_build.c | 41 -------------------------
tools/libxc/xc_resume.c | 65 +++++++++++++++++++++++++++++++++++++----
tools/libxc/xenctrl.h | 3 +
tools/libxc/xenguest.h | 5 ---
tools/python/xen/xend/image.py | 18 ++++++-----
6 files changed, 111 insertions(+), 60 deletions(-)
diff -r 8f7f29f718a6 -r a839e331f06f tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c Thu Apr 12 13:21:26 2007 +0100
+++ b/tools/libxc/xc_domain.c Thu Apr 12 14:13:04 2007 +0100
@@ -8,6 +8,7 @@
#include "xc_private.h"
#include <xen/memory.h>
+#include <xen/hvm/hvm_op.h>
int xc_domain_create(int xc_handle,
uint32_t ssidref,
@@ -655,6 +656,44 @@ int xc_domain_send_trigger(int xc_handle
domctl.u.sendtrigger.vcpu = vcpu;
return do_domctl(xc_handle, &domctl);
+}
+
+int xc_set_hvm_param(int handle, domid_t dom, int param, unsigned long value)
+{
+ DECLARE_HYPERCALL;
+ xen_hvm_param_t arg;
+ int rc;
+
+ hypercall.op = __HYPERVISOR_hvm_op;
+ hypercall.arg[0] = HVMOP_set_param;
+ hypercall.arg[1] = (unsigned long)&arg;
+ arg.domid = dom;
+ arg.index = param;
+ arg.value = value;
+ if ( lock_pages(&arg, sizeof(arg)) != 0 )
+ return -1;
+ rc = do_xen_hypercall(handle, &hypercall);
+ unlock_pages(&arg, sizeof(arg));
+ return rc;
+}
+
+int xc_get_hvm_param(int handle, domid_t dom, int param, unsigned long *value)
+{
+ DECLARE_HYPERCALL;
+ xen_hvm_param_t arg;
+ int rc;
+
+ hypercall.op = __HYPERVISOR_hvm_op;
+ hypercall.arg[0] = HVMOP_get_param;
+ hypercall.arg[1] = (unsigned long)&arg;
+ arg.domid = dom;
+ arg.index = param;
+ if ( lock_pages(&arg, sizeof(arg)) != 0 )
+ return -1;
+ rc = do_xen_hypercall(handle, &hypercall);
+ unlock_pages(&arg, sizeof(arg));
+ *value = arg.value;
+ return rc;
}
/*
diff -r 8f7f29f718a6 -r a839e331f06f tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c Thu Apr 12 13:21:26 2007 +0100
+++ b/tools/libxc/xc_hvm_build.c Thu Apr 12 14:13:04 2007 +0100
@@ -28,47 +28,6 @@ typedef union
vcpu_guest_context_x86_32_t c32;
vcpu_guest_context_t c;
} vcpu_guest_context_either_t;
-
-
-int xc_set_hvm_param(
- int handle, domid_t dom, int param, unsigned long value)
-{
- DECLARE_HYPERCALL;
- xen_hvm_param_t arg;
- int rc;
-
- hypercall.op = __HYPERVISOR_hvm_op;
- hypercall.arg[0] = HVMOP_set_param;
- hypercall.arg[1] = (unsigned long)&arg;
- arg.domid = dom;
- arg.index = param;
- arg.value = value;
- if ( lock_pages(&arg, sizeof(arg)) != 0 )
- return -1;
- rc = do_xen_hypercall(handle, &hypercall);
- unlock_pages(&arg, sizeof(arg));
- return rc;
-}
-
-int xc_get_hvm_param(
- int handle, domid_t dom, int param, unsigned long *value)
-{
- DECLARE_HYPERCALL;
- xen_hvm_param_t arg;
- int rc;
-
- hypercall.op = __HYPERVISOR_hvm_op;
- hypercall.arg[0] = HVMOP_get_param;
- hypercall.arg[1] = (unsigned long)&arg;
- arg.domid = dom;
- arg.index = param;
- if ( lock_pages(&arg, sizeof(arg)) != 0 )
- return -1;
- rc = do_xen_hypercall(handle, &hypercall);
- unlock_pages(&arg, sizeof(arg));
- *value = arg.value;
- return rc;
-}
static void build_e820map(void *e820_page, unsigned long long mem_size)
{
diff -r 8f7f29f718a6 -r a839e331f06f tools/libxc/xc_resume.c
--- a/tools/libxc/xc_resume.c Thu Apr 12 13:21:26 2007 +0100
+++ b/tools/libxc/xc_resume.c Thu Apr 12 14:13:04 2007 +0100
@@ -3,24 +3,71 @@
#include "xg_save_restore.h"
#if defined(__i386__) || defined(__x86_64__)
+
+#include <xen/foreign/x86_32.h>
+#include <xen/foreign/x86_64.h>
+#include <xen/hvm/params.h>
+
+/* 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 int modify_returncode(int xc_handle, uint32_t domid)
{
- vcpu_guest_context_t ctxt;
+ vcpu_guest_context_either_t ctxt;
+ xc_dominfo_t info;
+ xen_capabilities_info_t caps;
int rc;
- if ( (rc = xc_vcpu_getcontext(xc_handle, domid, 0, &ctxt)) != 0 )
- return rc;
- ctxt.user_regs.eax = 1;
- if ( (rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt)) != 0 )
+ if ( xc_domain_getinfo(xc_handle, domid, 1, &info) != 1 )
+ {
+ PERROR("Could not get domain info");
+ return -1;
+ }
+
+ /* HVM guests without PV drivers do not have a return code to modify. */
+ if ( info.hvm )
+ {
+ 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;
+ }
+
+ if ( (rc = xc_vcpu_getcontext(xc_handle, domid, 0, &ctxt.c)) != 0 )
+ return rc;
+
+ if ( !info.hvm )
+ ctxt.c.user_regs.eax = 1;
+ else if ( strstr(caps, "x86_64") )
+ ctxt.c64.user_regs.eax = 1;
+ else
+ ctxt.c32.user_regs.eax = 1;
+
+ if ( (rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt.c)) != 0 )
return rc;
return 0;
}
+
#else
+
static int modify_returncode(int xc_handle, uint32_t domid)
{
return 0;
-}
+
+}
+
#endif
static int xc_domain_resume_cooperative(int xc_handle, uint32_t domid)
@@ -65,6 +112,12 @@ static int xc_domain_resume_any(int xc_h
* (x86 only) Rewrite store_mfn and console_mfn back to MFN (from PFN).
*/
#if defined(__i386__) || defined(__x86_64__)
+ if ( info.hvm )
+ {
+ ERROR("Cannot resume uncooperative HVM guests");
+ return rc;
+ }
+
/* Map the shared info frame */
shinfo = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
PROT_READ, info.shared_info_frame);
diff -r 8f7f29f718a6 -r a839e331f06f tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Thu Apr 12 13:21:26 2007 +0100
+++ b/tools/libxc/xenctrl.h Thu Apr 12 14:13:04 2007 +0100
@@ -840,6 +840,9 @@ const char *xc_error_code_to_desc(int co
*/
xc_error_handler xc_set_error_handler(xc_error_handler handler);
+int xc_set_hvm_param(int handle, domid_t dom, int param, unsigned long value);
+int xc_get_hvm_param(int handle, domid_t dom, int param, unsigned long *value);
+
/* PowerPC specific. */
int xc_alloc_real_mode_area(int xc_handle,
uint32_t domid,
diff -r 8f7f29f718a6 -r a839e331f06f tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h Thu Apr 12 13:21:26 2007 +0100
+++ b/tools/libxc/xenguest.h Thu Apr 12 14:13:04 2007 +0100
@@ -136,11 +136,6 @@ int xc_hvm_build_mem(int xc_handle,
const char *image_buffer,
unsigned long image_size);
-int xc_set_hvm_param(
- int handle, domid_t dom, int param, unsigned long value);
-int xc_get_hvm_param(
- int handle, domid_t dom, int param, unsigned long *value);
-
/* PowerPC specific. */
int xc_prose_build(int xc_handle,
uint32_t domid,
diff -r 8f7f29f718a6 -r a839e331f06f tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Thu Apr 12 13:21:26 2007 +0100
+++ b/tools/python/xen/xend/image.py Thu Apr 12 14:13:04 2007 +0100
@@ -284,14 +284,16 @@ class HVMImageHandler(ImageHandler):
log.debug("acpi = %d", self.acpi)
log.debug("apic = %d", self.apic)
- return xc.hvm_build(domid = self.vm.getDomid(),
- image = self.kernel,
- store_evtchn = store_evtchn,
- memsize = mem_mb,
- vcpus = self.vm.getVCpuCount(),
- pae = self.pae,
- acpi = self.acpi,
- apic = self.apic)
+ rc = xc.hvm_build(domid = self.vm.getDomid(),
+ image = self.kernel,
+ store_evtchn = store_evtchn,
+ memsize = mem_mb,
+ vcpus = self.vm.getVCpuCount(),
+ pae = self.pae,
+ acpi = self.acpi,
+ apic = self.apic)
+ rc['notes'] = { 'SUSPEND_CANCEL': 1 }
+ return rc
# Return a list of cmd line args to the device models based on the
# xm config file
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|