HVM save restore: new hyper-call
PATCH 2/8 HVM save restore: new hyper-call
[PATCH 2/8] HVM save restore: new hyper-call
add a pair of hyper-call for hvm guest context
tools/libxc/xc_domain.c +44 -0
@@ -233,6 +233,50 @@ int xc_domain_getinfolist(int xc_handle,unlock_pages (info, max_domains*sizeof (xc_domaininfo_t));return ret; +} + +/* 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; +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 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; +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; } int xc_vcpu_getcontext(int xc_handle,
tools/libxc/xenctrl.h +24 -0
@@ -313,6 +313,30 @@ int xc_domain_getinfolist(int xc_handle, xc_domaininfo_t *info);/** +* This function returns information about the context of a hvm domain +* @parm xc_handle a handle to an open hypervisor interface +* @parm domid the domain to get information from +* @parm hvm_ctxt a pointer to a structure to store the execution context of the +* hvm domain +* @return 0 on success, -1 on failure +*/ +int xc_domain_hvm_getcontext (int xc_handle, +uint32_t domid, +hvm_domain_context_t *hvm_ctxt); + +/** +* This function will set the context for hvm domain +* +* @parm xc_handle a handle to an open hypervisor interface +* @parm domid the domain to set the hvm domain context for +* @parm hvm_ctxt pointer to the the hvm context with the values to set +* @return 0 on success, -1 on failure +*/ +int xc_domain_hvm_setcontext (int xc_handle, +uint32_t domid, +hvm_domain_context_t *hvm_ctxt); + +/** * This function returns information about the execution context of a * particular vcpu of a domain. *
xen/arch/x86/hvm/hvm.c +8 -0
@@ -149,11 +149,19 @@ int hvm_domain_initialise(struct domainvoid hvm_domain_destroy (struct domain *d) { +HVMStateEntry *se, *dse;pit_deinit (d);rtc_deinit (d);pmtimer_deinit (d);hpet_deinit (d); + se = d->arch.hvm_domain.first_se; +while (se) { + dse = se; + se = se->next; +xfree (dse); + } +if ( d->arch.hvm_domain.shared_page_va )unmap_domain_page_global ( (void *)d->arch.hvm_domain.shared_page_va);
xen/arch/x86/hvm/intercept.c +231 -0
243 lines not on this page · raw message
xen/common/domctl.c +73 -0
85 lines not on this page · raw message
xen/include/asm-x86/hvm/domain.h +17 -0
@@ -27,6 +27,20 @@#include <asm/hvm/io.h> #include <public/hvm/params.h> +typedef void SaveStateHandler (hvm_domain_context_t *h,void *opaque); +typedef int LoadStateHandler (hvm_domain_context_t *h,void *opaque,int version_id); + +#define HVM_SE_IDSTR_LEN 32 +typedef struct HVMStateEntry { +char idstr[HVM_SE_IDSTR_LEN ]; +int instance_id; +int version_id; +SaveStateHandler *save_state; +LoadStateHandler *load_state; +void *opaque; +struct HVMStateEntry *next; +}HVMStateEntry ; +struct hvm_domain {unsigned long shared_page_va;unsigned long buffered_io_va;
@@ -44,6 +58,9 @@ struct hvm_domain {spinlock_t pbuf_lock;uint64_t params[HVM_NR_PARAMS ]; + +struct hvm_domain_context *hvm_ctxt; + HVMStateEntry *first_se; };#endif /* __ASM_X86_HVM_DOMAIN_H__ */
xen/include/asm-x86/hvm/support.h +125 -0
131 lines not on this page · raw message
xen/include/public/domctl.h +16 -0
@@ -386,6 +386,21 @@ 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 XEN_DOMCTL_gethvmcontext 33 +#define XEN_DOMCTL_sethvmcontext 34 +typedef struct xen_domctl_hvmcontext { +XEN_GUEST_HANDLE (hvm_domain_context_t) ctxt;/* IN/OUT */ +}xen_domctl_hvmcontext_t ; +DEFINE_XEN_GUEST_HANDLE (xen_domctl_hvmcontext_t);#define XEN_DOMCTL_real_mode_area 26struct xen_domctl_real_mode_area {
@@ -423,6 +438,7 @@ struct xen_domctl {struct xen_domctl_arch_setup arch_setup;struct xen_domctl_settimeoffset settimeoffset;struct xen_domctl_real_mode_area real_mode_area; +struct xen_domctl_hvmcontext hvmcontext;uint8_t pad[128 ]; } u; };
Quoted 48 lines · Edwin
[PATCH 2/8] HVM save restore: new hyper-call
Signed-off-by Zhai Edwin <[email protected]>add a pair of hyper-call for hvm guest context
diff -r
7a38592d0cc9tools/libxc/xc_domain.ctools/libxc/xc_domain.c +35
-0@@ -233,6 +233,50 @@ int xc_domain_getinfolist(int xc_handle,unlock_pages (info, max_domains*sizeof (xc_domaininfo_t));return ret; +} + +/* 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; +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 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; +DECLARE_DOMCTL ; + + domctl.cmd = XEN_DOMCTL_sethvmcontext; + domctl.domain = domid; +set_xen_guest_handle (domctl.u.hvmcontext.ctxt, hvm_ctxt);
tools/libxc/xc_domain.c int xc_domain_getinfolist(int xc_handle, · line 280
Quoted 10 lines
tools/libxc/xc_domain.c +9
-0+ +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; }
Perhaps these should be lock_pages instead of calling mlock() directly?
Regards,
Anthony Liguori
Quoted 598 lines
tools/libxc/xc_domain.c +0
-0int xc_vcpu_getcontext(int xc_handle,diff -r
7a38592d0cc9tools/libxc/xenctrl.htools/libxc/xenctrl.h +24
-0@@ -313,6 +313,30 @@ int xc_domain_getinfolist(int xc_handle, xc_domaininfo_t *info);/** +* This function returns information about the context of a hvm domain +* @parm xc_handle a handle to an open hypervisor interface +* @parm domid the domain to get information from +* @parm hvm_ctxt a pointer to a structure to store the execution context of the +* hvm domain +* @return 0 on success, -1 on failure +*/ +int xc_domain_hvm_getcontext (int xc_handle, +uint32_t domid, +hvm_domain_context_t *hvm_ctxt); + +/** +* This function will set the context for hvm domain +* +* @parm xc_handle a handle to an open hypervisor interface +* @parm domid the domain to set the hvm domain context for +* @parm hvm_ctxt pointer to the the hvm context with the values to set +* @return 0 on success, -1 on failure +*/ +int xc_domain_hvm_setcontext (int xc_handle, +uint32_t domid, +hvm_domain_context_t *hvm_ctxt); + +/** * This function returns information about the execution context of a * particular vcpu of a domain. * diff -r
7a38592d0cc9xen/arch/x86/hvm/hvm.cxen/arch/x86/hvm/hvm.c +8
-0@@ -149,11 +149,19 @@ int hvm_domain_initialise(struct domainvoid hvm_domain_destroy (struct domain *d) { +HVMStateEntry *se, *dse;pit_deinit (d);rtc_deinit (d);pmtimer_deinit (d);hpet_deinit (d); + se = d->arch.hvm_domain.first_se; +while (se) { + dse = se; + se = se->next; +xfree (dse); + } +if ( d->arch.hvm_domain.shared_page_va )unmap_domain_page_global ( (void *)d->arch.hvm_domain.shared_page_va);diff -r
7a38592d0cc9xen/arch/x86/hvm/intercept.cxen/arch/x86/hvm/intercept.c +231
-0@@ -29,6 +29,8 @@#include <asm/current.h> #include <io_ports.h> #include <xen/event.h> +#include <xen/compile.h> +#include <public/version.h> extern struct hvm_mmio_handler hpet_mmio_handler;@@ -155,6 +157,235 @@ static inline void hvm_mmio_access(struc } } +/* save/restore support */ +#define HVM_FILE_MAGIC 0x54381286 +#define HVM_FILE_VERSION 0x00000001 + +int hvm_register_savevm (struct domain *d, +const char *idstr, +int instance_id, +int version_id, +SaveStateHandler *save_state, +LoadStateHandler *load_state, +void *opaque) +{ +HVMStateEntry *se, **pse; + + if ( (se = xmalloc(struct HVMStateEntry)) == NULL ){ +printk ("allocat hvmstate entry fail.\n" ); +return -1 ; + } + +strncpy (se->idstr, idstr,HVM_SE_IDSTR_LEN ); + + se->instance_id = instance_id; + se->version_id = version_id; + se->save_state = save_state; + se->load_state = load_state; + se->opaque = opaque; + se->next =NULL ; + +/* add at the end of list */ + pse = &d->arch.hvm_domain.first_se; +while (*pse !=NULL ) + pse = &(*pse)->next; + *pse = se; +return 0 ; +} + +int hvm_save (struct vcpu *v,hvm_domain_context_t *h) +{ +uint32_t len, len_pos, cur_pos; +uint32_t eax, ebx, ecx, edx; +HVMStateEntry *se; +char *chgset; + +if (!is_hvm_vcpu (v)) { +printk ("hvm_save only for hvm guest!\n" ); +return -1 ; + } + +memset (h,0 ,sizeof (hvm_domain_context_t)); +hvm_put_32u (h,HVM_FILE_MAGIC ); +hvm_put_32u (h,HVM_FILE_VERSION ); + +/* save xen changeset */ + chgset =strrchr (XEN_CHANGESET ,' ' ) +1 ; + + len =strlen (chgset); +hvm_put_8u (h, len); +hvm_put_buffer (h, chgset, len); + +/* save cpuid */ +cpuid (1 , &eax, &ebx, &ecx, &edx); +hvm_put_32u (h, eax); + +for (se = v->domain->arch.hvm_domain.first_se; se !=NULL ; se = se->next) { +/* ID string */ + len =strnlen (se->idstr,HVM_SE_IDSTR_LEN ); +hvm_put_8u (h, len); +hvm_put_buffer (h, se->idstr, len); + +hvm_put_32u (h, se->instance_id); +hvm_put_32u (h, se->version_id); + +/* record size */ + len_pos =hvm_ctxt_tell (h); +hvm_put_32u (h,0 ); + + se->save_state (h, se->opaque); + + cur_pos =hvm_ctxt_tell (h); + len = cur_pos - len_pos -4 ; +hvm_ctxt_seek (h, len_pos); +hvm_put_32u (h, len); +hvm_ctxt_seek (h, cur_pos); + + } + + h->size =hvm_ctxt_tell (h); +hvm_ctxt_seek (h,0 ); + +if (h->size >=HVM_CTXT_SIZE ) { +printk ("hvm_domain_context overflow when hvm_save! need %" PRId32" bytes for use.\n" , h->size); +return -1 ; + } + +return 0 ; + +} + +static HVMStateEntry *find_se (struct domain *d,const char *idstr,int instance_id) +{ +HVMStateEntry *se; + +for (se = d->arch.hvm_domain.first_se; se !=NULL ; se = se->next) { +if (!strncmp (se->idstr, idstr,HVM_SE_IDSTR_LEN ) && + instance_id == se->instance_id){ +return se; + } + } +return NULL ; +} + +int hvm_load (struct vcpu *v,hvm_domain_context_t *h) +{ +uint32_t len, rec_len, rec_pos, magic, instance_id, version_id; +uint32_t eax, ebx, ecx, edx; +HVMStateEntry *se; +char idstr[HVM_SE_IDSTR_LEN ]; +xen_changeset_info_t chgset; +char *cur_chgset; +int ret; + +if (!is_hvm_vcpu (v)) { +printk ("hvm_load only for hvm guest!\n" ); +return -1 ; + } + +if (h->size >=HVM_CTXT_SIZE ) { +printk ("hvm_load fail! seems hvm_domain_context overflow when hvm_save! need %" PRId32" bytes.\n" , h->size); +return -1 ; + } + +hvm_ctxt_seek (h,0 ); + + magic =hvm_get_32u (h); +if (magic !=HVM_FILE_MAGIC ) { +printk ("HVM restore magic dismatch!\n" ); +return -1 ; + } + + magic =hvm_get_32u (h); +if (magic !=HVM_FILE_VERSION ) { +printk ("HVM restore version dismatch!\n" ); +return -1 ; + } + +/* check xen change set */ + cur_chgset =strrchr (XEN_CHANGESET ,' ' ) +1 ; + + len =hvm_get_8u (h); +if (len >20 ) {/*typical length is 18 -- "revision number:changeset id" */ +printk ("wrong change set length %d when hvm restore!\n" , len); +return -1 ; + } + +hvm_get_buffer (h, chgset, len); + chgset[len] ='\0' ; +if (strncmp (cur_chgset, chgset, len +1 )) +printk ("warnings: try to restore hvm guest(%s) on a different changeset %s.\n" , + chgset, cur_chgset); + +/* check cpuid */ +cpuid (1 , &eax, &ebx, &ecx, &edx); + ebx =hvm_get_32u (h); +/*TODO: need difine how big difference is acceptable */ +if (ebx != eax) +printk ("warnings: try to restore hvm guest(0x%" PRIx32") " +"on a different type processor(0x%" PRIx32").\n" , + ebx, + eax); + +while (1 ) { +if (hvm_ctxt_end (h)) { +break ; + } + +/* ID string */ + len =hvm_get_8u (h); +if (len >HVM_SE_IDSTR_LEN ) { +printk ("wrong HVM save entry idstr len %d!" , len); +return -1 ; + } + +hvm_get_buffer (h, idstr, len); + idstr[len] ='\0' ; + + instance_id =hvm_get_32u (h); + version_id =hvm_get_32u (h); + + rec_len =hvm_get_32u (h); + rec_pos =hvm_ctxt_tell (h); + + se =find_se (v->domain, idstr, instance_id); +if (se ==NULL ) { +printk ("warnings: hvm load can't find device %s's instance %d!\n" , + idstr, instance_id); + }else { + ret = se->load_state (h, se->opaque, version_id); +if (ret <0 ) +printk ("warnings: loading state fail for device %s instance %d!\n" , + idstr, instance_id); + } + + +/* make sure to jump end of record */ +if (hvm_ctxt_tell (h) - rec_pos != rec_len) { +printk ("wrong hvm record size, maybe some dismatch between save&restore handler!\n" ); + } +hvm_ctxt_seek (h, rec_pos + rec_len); + } + +return 0 ; +} + +int arch_gethvm_ctxt ( +struct vcpu *v,struct hvm_domain_context *c) +{ +if ( !is_hvm_vcpu (v) ) +return -1 ; + +return hvm_save (v, c); + +} + +int arch_sethvm_ctxt ( +struct vcpu *v,struct hvm_domain_context *c) +{ +return hvm_load (v, c); +} +int hvm_buffered_io_intercept (ioreq_t *p) {struct vcpu *v = current;diff -r
7a38592d0cc9xen/common/domctl.cxen/common/domctl.c +73
-0@@ -215,6 +215,39 @@ 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);@@ -552,6 +585,46 @@ 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
7a38592d0cc9xen/include/asm-x86/hvm/domain.hxen/include/asm-x86/hvm/domain.h +17
-0@@ -27,6 +27,20 @@#include <asm/hvm/io.h> #include <public/hvm/params.h> +typedef void SaveStateHandler (hvm_domain_context_t *h,void *opaque); +typedef int LoadStateHandler (hvm_domain_context_t *h,void *opaque,int version_id); + +#define HVM_SE_IDSTR_LEN 32 +typedef struct HVMStateEntry { +char idstr[HVM_SE_IDSTR_LEN ]; +int instance_id; +int version_id; +SaveStateHandler *save_state; +LoadStateHandler *load_state; +void *opaque; +struct HVMStateEntry *next; +}HVMStateEntry ; +struct hvm_domain {unsigned long shared_page_va;unsigned long buffered_io_va;@@ -44,6 +58,9 @@ struct hvm_domain {spinlock_t pbuf_lock;uint64_t params[HVM_NR_PARAMS ]; + +struct hvm_domain_context *hvm_ctxt; + HVMStateEntry *first_se; };#endif /* __ASM_X86_HVM_DOMAIN_H__ */ diff -r
7a38592d0cc9xen/include/asm-x86/hvm/support.hxen/include/asm-x86/hvm/support.h +125
-0@@ -121,6 +121,131 @@ extern unsigned int opt_hvm_debug_level;#define TRACE_VMEXIT (index, value) \ current->arch.hvm_vcpu.hvm_trace_values[index] = (value) +/* save/restore support */ + +//#define HVM_DEBUG_SUSPEND + +extern int hvm_register_savevm (struct domain *d, +const char *idstr, +int instance_id, +int version_id, +SaveStateHandler *save_state, +LoadStateHandler *load_state, +void *opaque); + +static inline void hvm_ctxt_seek (hvm_domain_context_t *h,unsigned int pos) +{ + h->cur = pos; +} + +static inline uint32_t hvm_ctxt_tell (hvm_domain_context_t *h) +{ +return h->cur; +} + +static inline int hvm_ctxt_end (hvm_domain_context_t *h) +{ +return (h->cur >= h->size || h->cur >=HVM_CTXT_SIZE ); +} + +static inline void hvm_put_byte (hvm_domain_context_t *h,unsigned int i) +{ +if (h->cur >=HVM_CTXT_SIZE ) { + h->cur++; +return ; + } + h->data[h->cur++] = (char )i; +} + +static inline void hvm_put_8u (hvm_domain_context_t *h,uint8_t b) +{ +hvm_put_byte (h, b); +} + +static inline void hvm_put_16u (hvm_domain_context_t *h,uint16_t b) +{ +hvm_put_8u (h, b >>8 ); +hvm_put_8u (h, b); +} + +static inline void hvm_put_32u (hvm_domain_context_t *h,uint32_t b) +{ +hvm_put_16u (h, b >>16 ); +hvm_put_16u (h, b); +} + +static inline void hvm_put_64u (hvm_domain_context_t *h,uint64_t b) +{ +hvm_put_32u (h, b >>32 ); +hvm_put_32u (h, b); +} + +static inline void hvm_put_buffer (hvm_domain_context_t *h,const char *buf,int len) +{ +memcpy (&h->data[h->cur], buf, len); + h->cur += len; +} + + +static inline char hvm_get_byte (hvm_domain_context_t *h) +{ +if (h->cur >=HVM_CTXT_SIZE ) { +printk ("hvm_get_byte overflow.\n" ); +return -1 ; + } + +if (h->cur >= h->size) { +printk ("hvm_get_byte exceed data area.\n" ); +return -1 ; + } + +return h->data[h->cur++]; +} + +static inline uint8_t hvm_get_8u (hvm_domain_context_t *h) +{ +return hvm_get_byte (h); +} + +static inline uint16_t hvm_get_16u (hvm_domain_context_t *h) +{ +uint16_t v; + v =hvm_get_8u (h) <<8 ; + v |=hvm_get_8u (h); + +return v; +} + +static inline uint32_t hvm_get_32u (hvm_domain_context_t *h) +{ +uint32_t v; + v =hvm_get_16u (h) <<16 ; + v |=hvm_get_16u (h); + +return v; +} + +static inline uint64_t hvm_get_64u (hvm_domain_context_t *h) +{ +uint64_t v; + v = (uint64_t )hvm_get_32u (h) <<32 ; + v |=hvm_get_32u (h); + +return v; +} + +static inline void hvm_get_buffer (hvm_domain_context_t *h,char *buf,int len) +{ +memcpy (buf, &h->data[h->cur], len); + h->cur += len; +} + +extern int hvm_save (struct vcpu *,hvm_domain_context_t *h); +extern int hvm_load (struct vcpu *,hvm_domain_context_t *h); + +extern int arch_sethvm_ctxt (struct vcpu *v,struct hvm_domain_context *c); +extern int arch_gethvm_ctxt (struct vcpu *v,struct hvm_domain_context *c); +extern int hvm_enabled;int hvm_copy_to_guest_phys (paddr_t paddr,void *buf,int size);diff -r
7a38592d0cc9xen/include/public/domctl.hxen/include/public/domctl.h +16
-0@@ -386,6 +386,21 @@ 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 XEN_DOMCTL_gethvmcontext 33 +#define XEN_DOMCTL_sethvmcontext 34 +typedef struct xen_domctl_hvmcontext { +XEN_GUEST_HANDLE (hvm_domain_context_t) ctxt;/* IN/OUT */ +}xen_domctl_hvmcontext_t ; +DEFINE_XEN_GUEST_HANDLE (xen_domctl_hvmcontext_t);#define XEN_DOMCTL_real_mode_area 26struct xen_domctl_real_mode_area {@@ -423,6 +438,7 @@ struct xen_domctl {struct xen_domctl_arch_setup arch_setup;struct xen_domctl_settimeoffset settimeoffset;struct xen_domctl_real_mode_area real_mode_area; +struct xen_domctl_hvmcontext hvmcontext;uint8_t pad[128 ]; } u; };
Quoted 17 lines · Anthony Liguori
Quoted 16 lines · Edwin
(quoted diff) +16
-0+ +/* 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; + 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; +
Quoted 8 lines
Quoted 6 lines
(quoted diff) +5
-0+ rc = do_domctl(xc_handle, &domctl); + + safe_munlock(hvm_ctxt, sizeof(*hvm_ctxt)); + + return rc;}
Perhaps these should be
lock_pagesinstead of callingmlock()directly?
yes, you are right. i forgot to refresh old patch when rebase. attached minor fix is okay.
thanks,
Quoted 5 lines
Regards,
Anthony Liguori
Signature · 2 lines
best rgds, edwin
tools/libxc/xc_domain.c +4 -4
@@ -247,12 +247,12 @@ int xc_domain_hvm_getcontext(int xc_hand domctl.domain = (domid_t )domid;set_xen_guest_handle (domctl.u.hvmcontext.ctxt, hvm_ctxt); -if ( (rc =mlock (hvm_ctxt,sizeof (*hvm_ctxt))) !=0 ) +if ( (rc =lock_pages (hvm_ctxt,sizeof (*hvm_ctxt))) !=0 )return rc; rc =do_domctl (xc_handle, &domctl); -safe_munlock (hvm_ctxt,sizeof (*hvm_ctxt)); +unlock_pages (hvm_ctxt,sizeof (*hvm_ctxt));return rc; }
@@ -269,12 +269,12 @@ int xc_domain_hvm_setcontext(int xc_hand domctl.domain = domid;set_xen_guest_handle (domctl.u.hvmcontext.ctxt, hvm_ctxt); -if ( (rc =mlock (hvm_ctxt,sizeof (*hvm_ctxt))) !=0 ) +if ( (rc =lock_pages (hvm_ctxt,sizeof (*hvm_ctxt))) !=0 )return rc; rc =do_domctl (xc_handle, &domctl); -safe_munlock (hvm_ctxt,sizeof (*hvm_ctxt)); +unlock_pages (hvm_ctxt,sizeof (*hvm_ctxt));return rc; }
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel