aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-04-12 14:13:04 +0100
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-04-12 14:13:04 +0100
commita01197aeb4b0e496b2e5ebdff2b1728970e3a351 (patch)
tree686e56d850b00c27182bc20c378189c2bd255d94
parent40bb2e5fead9f092ee6805c73e26d1c2fd54c40f (diff)
downloadxen-a01197aeb4b0e496b2e5ebdff2b1728970e3a351.tar.gz
xen-a01197aeb4b0e496b2e5ebdff2b1728970e3a351.tar.bz2
xen-a01197aeb4b0e496b2e5ebdff2b1728970e3a351.zip
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@xensource.com>
-rw-r--r--tools/libxc/xc_domain.c39
-rw-r--r--tools/libxc/xc_hvm_build.c41
-rw-r--r--tools/libxc/xc_resume.c61
-rw-r--r--tools/libxc/xenctrl.h3
-rw-r--r--tools/libxc/xenguest.h5
-rw-r--r--tools/python/xen/xend/image.py18
6 files changed, 109 insertions, 58 deletions
diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index 1b6962d54d..948aa34088 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -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,
@@ -657,6 +658,44 @@ int xc_domain_send_trigger(int xc_handle,
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;
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxc/xc_hvm_build.c b/tools/libxc/xc_hvm_build.c
index 751aa9cf7a..f9e37cb54b 100644
--- a/tools/libxc/xc_hvm_build.c
+++ b/tools/libxc/xc_hvm_build.c
@@ -29,47 +29,6 @@ typedef union
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)
{
struct e820entry *e820entry =
diff --git a/tools/libxc/xc_resume.c b/tools/libxc/xc_resume.c
index 3fb6d13adc..df48fa3dff 100644
--- a/tools/libxc/xc_resume.c
+++ b/tools/libxc/xc_resume.c
@@ -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 )
+ 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;
- ctxt.user_regs.eax = 1;
- if ( (rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt)) != 0 )
+
+ 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_handle, uint32_t domid)
* (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 --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
index 1073b8bcb5..f91dedbc4e 100644
--- a/tools/libxc/xenctrl.h
+++ b/tools/libxc/xenctrl.h
@@ -840,6 +840,9 @@ const char *xc_error_code_to_desc(int code);
*/
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 --git a/tools/libxc/xenguest.h b/tools/libxc/xenguest.h
index 189d48ed1f..be30cfe299 100644
--- a/tools/libxc/xenguest.h
+++ b/tools/libxc/xenguest.h
@@ -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 --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py
index a4e785d96a..d1ea10fe0c 100644
--- a/tools/python/xen/xend/image.py
+++ b/tools/python/xen/xend/image.py
@@ -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