Zhai, Edwin
2007-Jan-19 16:38 UTC
[Xen-devel] [PATCH 2/4] HVM save/restore clean up: new hyper-call clean
[PATCH 2/4] HVM save/restore clean up: new hyper-call clean Signed-off-by: Zhai Edwin <edwin.zhai@intel.com> enable it for compat mode and move it to arch/x86/domctl.c diff -r f639b9f51709 tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Fri Jan 19 18:39:12 2007 +0800 +++ b/tools/libxc/xc_domain.c Fri Jan 19 18:47:13 2007 +0800 @@ -238,45 +238,47 @@ int xc_domain_getinfolist(int xc_handle, /* get info from hvm guest for save */ int xc_domain_hvm_getcontext(int xc_handle, uint32_t domid, - hvm_domain_context_t *hvm_ctxt) -{ - int rc; + uint8_t *ctxt_buf) +{ + int ret; DECLARE_DOMCTL; domctl.cmd = XEN_DOMCTL_gethvmcontext; domctl.domain = (domid_t)domid; - set_xen_guest_handle(domctl.u.hvmcontext.ctxt, hvm_ctxt); - - if ( (rc = mlock(hvm_ctxt, sizeof(*hvm_ctxt))) != 0 ) - return rc; - - rc = do_domctl(xc_handle, &domctl); - - safe_munlock(hvm_ctxt, sizeof(*hvm_ctxt)); - - return rc; + set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf); + + if ( (ret = lock_pages(ctxt_buf, HVM_CTXT_SIZE)) != 0 ) + return ret; + + ret = do_domctl(xc_handle, &domctl); + + unlock_pages(ctxt_buf, HVM_CTXT_SIZE); + + return (ret < 0 ? -1 : domctl.u.hvmcontext.size); } /* set info to hvm guest for restore */ int xc_domain_hvm_setcontext(int xc_handle, uint32_t domid, - hvm_domain_context_t *hvm_ctxt) -{ - int rc; + uint8_t *ctxt_buf, + uint32_t size) +{ + int ret; DECLARE_DOMCTL; domctl.cmd = XEN_DOMCTL_sethvmcontext; domctl.domain = domid; - set_xen_guest_handle(domctl.u.hvmcontext.ctxt, hvm_ctxt); - - if ( (rc = mlock(hvm_ctxt, sizeof(*hvm_ctxt))) != 0 ) - return rc; - - rc = do_domctl(xc_handle, &domctl); - - safe_munlock(hvm_ctxt, sizeof(*hvm_ctxt)); - - return rc; + domctl.u.hvmcontext.size = size; + set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf); + + if ( (ret = lock_pages(ctxt_buf, HVM_CTXT_SIZE)) != 0 ) + return ret; + + ret = do_domctl(xc_handle, &domctl); + + unlock_pages(ctxt_buf, HVM_CTXT_SIZE); + + return ret; } int xc_vcpu_getcontext(int xc_handle, diff -r f639b9f51709 tools/libxc/xc_hvm_restore.c --- a/tools/libxc/xc_hvm_restore.c Fri Jan 19 18:39:12 2007 +0800 +++ b/tools/libxc/xc_hvm_restore.c Fri Jan 19 18:56:55 2007 +0800 @@ -87,7 +87,7 @@ int xc_hvm_restore(int xc_handle, int io xc_dominfo_t info; unsigned int rc = 1, n, i; uint32_t rec_len, nr_vcpus; - hvm_domain_context_t hvm_ctxt; + uint8_t *hvm_buf = NULL; unsigned long long v_end, memsize; unsigned long shared_page_nr; @@ -127,8 +127,9 @@ int xc_hvm_restore(int xc_handle, int io p2m = malloc(max_pfn * sizeof(xen_pfn_t)); - - if (p2m == NULL) { + hvm_buf = malloc(HVM_CTXT_SIZE); + + if (p2m == NULL || hvm_buf == NULL) { ERROR("memory alloc failed"); errno = ENOMEM; goto out; @@ -304,18 +305,18 @@ int xc_hvm_restore(int xc_handle, int io ERROR("error read hvm context size!\n"); goto out; } - if (rec_len != sizeof(hvm_ctxt)) { - ERROR("hvm context size dismatch!\n"); - goto out; - } - - if (!read_exact(io_fd, &hvm_ctxt, sizeof(hvm_ctxt))) { - ERROR("error read hvm context!\n"); - goto out; - } - - if (( rc = xc_domain_hvm_setcontext(xc_handle, dom, &hvm_ctxt))) { - ERROR("error set hvm context!\n"); + if (rec_len >= HVM_CTXT_SIZE) { + ERROR("wrong hvm buffer size!\n"); + goto out; + } + + if (!read_exact(io_fd, hvm_buf, rec_len)) { + ERROR("error read hvm buffer!\n"); + goto out; + } + + if (( rc = xc_domain_hvm_setcontext(xc_handle, dom, hvm_buf, rec_len))) { + ERROR("error set hvm buffer!\n"); goto out; } @@ -353,6 +354,7 @@ int xc_hvm_restore(int xc_handle, int io if ( (rc != 0) && (dom != 0) ) xc_domain_destroy(xc_handle, dom); free(p2m); + free(hvm_buf); DPRINTF("Restore exit with rc=%d\n", rc); diff -r f639b9f51709 tools/libxc/xc_hvm_save.c --- a/tools/libxc/xc_hvm_save.c Fri Jan 19 18:39:12 2007 +0800 +++ b/tools/libxc/xc_hvm_save.c Fri Jan 19 23:56:28 2007 +0800 @@ -279,8 +279,8 @@ int xc_hvm_save(int xc_handle, int io_fd unsigned long *pfn_type = NULL; unsigned long *pfn_batch = NULL; - /* A copy of hvm domain context */ - hvm_domain_context_t hvm_ctxt; + /* A copy of hvm domain context buffer*/ + uint8_t *hvm_buf = NULL; /* Live mapping of shared info structure */ shared_info_t *live_shinfo = NULL; @@ -423,8 +423,12 @@ int xc_hvm_save(int xc_handle, int io_fd to_send = malloc(BITMAP_SIZE); to_skip = malloc(BITMAP_SIZE); - if (!to_send ||!to_skip) { - ERROR("Couldn''t allocate to_send array"); + page_array = (unsigned long *) malloc( sizeof(unsigned long) * max_pfn); + + hvm_buf = malloc(HVM_CTXT_SIZE); + + if (!to_send ||!to_skip ||!page_array ||!hvm_buf ) { + ERROR("Couldn''t allocate memory"); goto out; } @@ -444,11 +448,6 @@ int xc_hvm_save(int xc_handle, int io_fd analysis_phase(xc_handle, dom, max_pfn, to_skip, 0); /* get all the HVM domain pfns */ - if ( (page_array = (unsigned long *) malloc (sizeof(unsigned long) * max_pfn)) == NULL) { - ERROR("HVM:malloc fail!\n"); - goto out; - } - for ( i = 0; i < max_pfn; i++) page_array[i] = i; @@ -656,23 +655,27 @@ int xc_hvm_save(int xc_handle, int io_fd } /* save hvm hypervisor state including pic/pit/shpage */ - if (mlock(&hvm_ctxt, sizeof(hvm_ctxt))) { - ERROR("Unable to mlock ctxt"); - return 1; - } - - if (xc_domain_hvm_getcontext(xc_handle, dom, &hvm_ctxt)){ - ERROR("HVM:Could not get hvm context"); - goto out; - } - - rec_size = sizeof(hvm_ctxt); + if (lock_pages(hvm_buf, HVM_CTXT_SIZE)) { + ERROR("Unable to lock hvm buffer"); + goto out; + } + + if ( (rec_size = xc_domain_hvm_getcontext(xc_handle, dom, hvm_buf)) == -1){ + ERROR("HVM:Could not get hvm buffer"); + goto out; + } + + if ( rec_size >= HVM_CTXT_SIZE) { + ERROR("HVM:hvm buffer overflow"); + goto out; + } + if (!write_exact(io_fd, &rec_size, sizeof(uint32_t))) { - ERROR("error write hvm ctxt size"); - goto out; - } - - if ( !write_exact(io_fd, &hvm_ctxt, sizeof(hvm_ctxt)) ) { + ERROR("error write hvm buffer size"); + goto out; + } + + if ( !write_exact(io_fd, hvm_buf, rec_size) ) { ERROR("write HVM info failed!\n"); } @@ -716,6 +719,7 @@ int xc_hvm_save(int xc_handle, int io_fd } } + free(hvm_buf); free(page_array); free(pfn_type); diff -r f639b9f51709 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Fri Jan 19 18:39:12 2007 +0800 +++ b/tools/libxc/xenctrl.h Fri Jan 19 18:42:00 2007 +0800 @@ -322,7 +322,7 @@ int xc_domain_getinfolist(int xc_handle, */ int xc_domain_hvm_getcontext(int xc_handle, uint32_t domid, - hvm_domain_context_t *hvm_ctxt); + uint8_t *ctxt_buf); /** * This function will set the context for hvm domain @@ -334,7 +334,8 @@ int xc_domain_hvm_getcontext(int xc_hand */ int xc_domain_hvm_setcontext(int xc_handle, uint32_t domid, - hvm_domain_context_t *hvm_ctxt); + uint8_t *hvm_ctxt, + uint32_t size); /** * This function returns information about the execution context of a diff -r f639b9f51709 xen/arch/x86/domctl.c --- a/xen/arch/x86/domctl.c Fri Jan 19 18:39:12 2007 +0800 +++ b/xen/arch/x86/domctl.c Sat Jan 20 00:04:57 2007 +0800 @@ -260,6 +260,82 @@ _long arch_do_domctl( } break; + case XEN_DOMCTL_gethvmcontext: + { + struct hvm_domain_context *c; + struct domain *d; + struct vcpu *v; + + ret = -ESRCH; + if ( (d = find_domain_by_id(domctl->domain)) == NULL ) + break; + + ret = -ENOMEM; + if ( (c = xmalloc(struct hvm_domain_context) ) == NULL ) + goto gethvmcontext_out; + + v = d->vcpu[0]; + + ret = -ENODATA; + if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) ) + goto gethvmcontext_out; + + ret = 0; + if (arch_gethvm_ctxt(v, c) == -1) + ret = -EFAULT; + + if ( copy_to_xxx_offset(domctl->u.hvmcontext.buffer, 0, &c->data[0], HVM_CTXT_SIZE)) + ret = -EFAULT; + + domctl->u.hvmcontext.size = c->size; + + xfree(c); + + if ( copy_to_guest(u_domctl, domctl, 1) ) + ret = -EFAULT; + + gethvmcontext_out: + put_domain(d); + + } + break; + + case XEN_DOMCTL_sethvmcontext: + { + struct hvm_domain_context *c; + struct domain *d; + struct vcpu *v; + + ret = -ESRCH; + if ( (d = find_domain_by_id(domctl->domain)) == NULL ) + break; + + ret = -ENOMEM; + if ( (c = xmalloc(struct hvm_domain_context)) == NULL ) + goto sethvmcontext_out; + + v = d->vcpu[0]; + + ret = -EFAULT; + + if ( copy_from_xxx_offset(&c->data[0], domctl->u.hvmcontext.buffer, 0, HVM_CTXT_SIZE) ) { + ret = -EINVAL; + xfree(c); + break; + } + + c->size = domctl->u.hvmcontext.size; + + ret = arch_sethvm_ctxt(v, c); + + xfree(c); + + sethvmcontext_out: + put_domain(d); + + } + break; + case XEN_DOMCTL_hypercall_init: { struct domain *d = find_domain_by_id(domctl->domain); diff -r f639b9f51709 xen/common/domctl.c --- a/xen/common/domctl.c Fri Jan 19 18:39:12 2007 +0800 +++ b/xen/common/domctl.c Fri Jan 19 18:42:00 2007 +0800 @@ -215,39 +215,6 @@ ret_t do_domctl(XEN_GUEST_HANDLE(xen_dom } break; - case XEN_DOMCTL_sethvmcontext: - { - struct hvm_domain_context *c; - struct domain *d; - struct vcpu *v; - - ret = -ESRCH; - if ( (d = find_domain_by_id(op->domain)) == NULL ) - break; - - ret = -ENOMEM; - if ( (c = xmalloc(struct hvm_domain_context)) == NULL ) - goto sethvmcontext_out; - - v = d->vcpu[0]; - - ret = -EFAULT; - -#ifndef CONFIG_COMPAT - if ( copy_from_guest(c, op->u.hvmcontext.ctxt, 1) != 0 ) - goto sethvmcontext_out; - - ret = arch_sethvm_ctxt(v, c); -#endif - - xfree(c); - - sethvmcontext_out: - put_domain(d); - - } - break; - case XEN_DOMCTL_pausedomain: { struct domain *d = find_domain_by_id(op->domain); @@ -585,46 +552,6 @@ ret_t do_domctl(XEN_GUEST_HANDLE(xen_dom } break; - case XEN_DOMCTL_gethvmcontext: - { - struct hvm_domain_context *c; - struct domain *d; - struct vcpu *v; - - ret = -ESRCH; - if ( (d = find_domain_by_id(op->domain)) == NULL ) - break; - - ret = -ENOMEM; - if ( (c = xmalloc(struct hvm_domain_context)) == NULL ) - goto gethvmcontext_out; - - v = d->vcpu[0]; - - ret = -ENODATA; - if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) ) - goto gethvmcontext_out; - - ret = 0; - if (arch_gethvm_ctxt(v, c) == -1) - ret = -EFAULT; - -#ifndef CONFIG_COMPAT - if ( copy_to_guest(op->u.hvmcontext.ctxt, c, 1) ) - ret = -EFAULT; - - xfree(c); -#endif - - if ( copy_to_guest(u_domctl, op, 1) ) - ret = -EFAULT; - - gethvmcontext_out: - put_domain(d); - - } - break; - case XEN_DOMCTL_getvcpuinfo: { struct domain *d; diff -r f639b9f51709 xen/include/asm-x86/hvm/domain.h --- a/xen/include/asm-x86/hvm/domain.h Fri Jan 19 18:39:12 2007 +0800 +++ b/xen/include/asm-x86/hvm/domain.h Fri Jan 19 18:42:00 2007 +0800 @@ -26,6 +26,12 @@ #include <asm/hvm/vlapic.h> #include <asm/hvm/io.h> #include <public/hvm/params.h> + +typedef struct hvm_domain_context { + uint32_t cur; + uint32_t size; + uint8_t data[HVM_CTXT_SIZE]; +} hvm_domain_context_t; typedef void SaveStateHandler(hvm_domain_context_t *h, void *opaque); typedef int LoadStateHandler(hvm_domain_context_t *h, void *opaque, int version_id); @@ -58,8 +64,6 @@ struct hvm_domain { spinlock_t pbuf_lock; uint64_t params[HVM_NR_PARAMS]; - - struct hvm_domain_context *hvm_ctxt; HVMStateEntry *first_se; }; diff -r f639b9f51709 xen/include/public/domctl.h --- a/xen/include/public/domctl.h Fri Jan 19 18:39:12 2007 +0800 +++ b/xen/include/public/domctl.h Fri Jan 19 18:42:00 2007 +0800 @@ -387,18 +387,15 @@ typedef struct xen_domctl_settimeoffset typedef struct xen_domctl_settimeoffset xen_domctl_settimeoffset_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_settimeoffset_t); -#define HVM_CTXT_SIZE 6144 -typedef struct hvm_domain_context { - uint32_t cur; - uint32_t size; - uint8_t data[HVM_CTXT_SIZE]; -} hvm_domain_context_t; -DEFINE_XEN_GUEST_HANDLE(hvm_domain_context_t); +#define HVM_CTXT_SIZE 8192 #define XEN_DOMCTL_gethvmcontext 33 #define XEN_DOMCTL_sethvmcontext 34 typedef struct xen_domctl_hvmcontext { - XEN_GUEST_HANDLE(hvm_domain_context_t) ctxt; /* IN/OUT */ + /*IN/OUT variables*/ + uint32_t size; + /*IN/OUT variables*/ + XEN_GUEST_HANDLE(uint8_t) buffer; /* IN/OUT */ } xen_domctl_hvmcontext_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_t); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel