From a01197aeb4b0e496b2e5ebdff2b1728970e3a351 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Thu, 12 Apr 2007 14:13:04 +0100 Subject: 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 --- tools/libxc/xc_domain.c | 39 +++++++++++++++++++++++++++ tools/libxc/xc_hvm_build.c | 41 ---------------------------- tools/libxc/xc_resume.c | 61 +++++++++++++++++++++++++++++++++++++++--- tools/libxc/xenctrl.h | 3 +++ tools/libxc/xenguest.h | 5 ---- tools/python/xen/xend/image.py | 18 +++++++------ 6 files changed, 109 insertions(+), 58 deletions(-) (limited to 'tools') 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 +#include 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 +#include +#include + +/* 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 -- cgit v1.2.3