vmx domain save/restore support
PATCH 1/1 vmx domain save/restore support
attached is the vmx domain save/restore patch. works well for different guest/host combination W/O breaking domu save/restore according to my test. pls. first apply xiaowei's qemu dm fix.
===know issue===
* shpage pfn *
HV look for shpage pfn in an e820 entry when init. but some
guest(win/em64t linux) will reuse this e820 ram, which cause losing shpage pfn when restore. so this entry is marked as "reserved" to avoid guest reuse (in this patch xc_hvm_build.c). we can change this if having good solution in future.
* 64bit host vmx restore python err *
when restore vmx guest on em64t host, i got a error "ERROR
(xmlrpclib2:167) int exceeds XML-RPC limits" W/O blocking restore. "xend restart" can be a work around.
* guest smp support *
i'm doing guest smp support including apic/vmcs save/restore now. so
turn on "apic" in config file may cause save/restore failure.
* guest save/restore across platform*
e.g save 32 guest on 64 host, then restore 32 guest on 32 host. we
can't support this because save/restore face different vcpu_context format on different host. need universal format for this.
=== test report ===
"+" stands for okay, "-" stands for fail
32b host:
+ 32/32
+ 32win/32
pae host:
+ 32/pae
+ pae/pae
+ 32win/pae
+ pae_win/pae
em64t host:
+ 32/64
+ pae/64
+ 64/64
+ 32win/64
+ pae_win/64
sometimes pae_win/64 are not stable:(
# HG changeset patch
# User Edwin Zhai <[email protected]>
# Node ID 2abb1c801ab72ee7e88b144871162fe2e47a0970 # Parent 98c3ddf83a59b0cbbdce63bb210adfd0d2ec1aea vmx save/restore support
tools/ioemu/hw/cirrus_vga.c +50 -0
@@ -3010,11 +3010,44 @@ static CPUWriteMemoryFunc *cirrus_mmio_w cirrus_mmio_writel, }; +void cirrus_stop_acc (CirrusVGAState *s) +{ +if (s->map_addr){ +int error; + s->map_addr =0 ; + error =unset_vram_mapping (s->cirrus_lfb_addr, + s->cirrus_lfb_end); +fprintf (stderr,"cirrus_stop_acc:unset_vram_mapping.\n" ); + +munmap (s->vram_ptr,VGA_RAM_SIZE ); + } +} + +void cirrus_restart_acc (CirrusVGAState *s) +{ +if (s->cirrus_lfb_addr && s->cirrus_lfb_end) { +void *vram_pointer, *old_vram; +fprintf (stderr,"cirrus_vga_load:re-enable vga acc.lfb_addr=0x%lx, lfb_end=0x%lx.\n" , + s->cirrus_lfb_addr, s->cirrus_lfb_end); + vram_pointer =set_vram_mapping (s->cirrus_lfb_addr ,s->cirrus_lfb_end); +if (!vram_pointer){ +fprintf (stderr,"cirrus_vga_load:NULL vram_pointer\n" ); + }else { + old_vram =vga_update_vram ((VGAState *)s, vram_pointer, +VGA_RAM_SIZE ); +qemu_free (old_vram); + s->map_addr = s->cirrus_lfb_addr; + s->map_end = s->cirrus_lfb_end; + } + } +} +/* load/save state */ static void cirrus_vga_save (QEMUFile *f,void *opaque) {CirrusVGAState *s = opaque; +uint8_t vga_acc;qemu_put_be32s (f, &s->latch);qemu_put_8s (f, &s->sr_index);
@@ -3049,11 +3082,20 @@ static void cirrus_vga_save(QEMUFile *f,qemu_put_be32s (f, &s->hw_cursor_y);/* XXX: we do not save the bitblt state - we assume we do not save the state when the blitter is active */ + + vga_acc = (!!s->map_addr); +qemu_put_8s (f, &vga_acc); +qemu_put_be64s (f, (uint64_t *)&s->cirrus_lfb_addr); +qemu_put_be64s (f, (uint64_t *)&s->cirrus_lfb_end); +qemu_put_buffer (f, s->vram_ptr,VGA_RAM_SIZE ); +if (vga_acc) +cirrus_stop_acc (s); }static int cirrus_vga_load (QEMUFile *f,void *opaque,int version_id) {CirrusVGAState *s = opaque; +uint8_t vga_acc =0 ;if (version_id !=1 )return -EINVAL ;
@@ -3091,6 +3133,14 @@ static int cirrus_vga_load(QEMUFile *f,qemu_get_be32s (f, &s->hw_cursor_x);qemu_get_be32s (f, &s->hw_cursor_y); + +qemu_get_8s (f, &vga_acc); +qemu_get_be64s (f, (uint64_t *)&s->cirrus_lfb_addr); +qemu_get_be64s (f, (uint64_t *)&s->cirrus_lfb_end); +qemu_get_buffer (f, s->vram_ptr,VGA_RAM_SIZE ); +if (vga_acc){ +cirrus_restart_acc (s); + }/* force refresh */ s->graphic_mode =-1 ;
tools/ioemu/target-i386-dm/helper2.c +14 -1
@@ -457,6 +457,7 @@ int main_loop(void) {extern int vm_running;extern int shutdown_requested; +extern int suspend_requested;CPUState *env = cpu_single_env;int evtchn_fd =xc_evtchn_fd (xce_handle);
@@ -472,6 +473,10 @@ int main_loop(void)qemu_system_reset (); reset_requested =0 ; } +if (suspend_requested) { +fprintf (logfile,"device model received suspend signal!\n" ); +break ; + } }/* Wait up to 10 msec. */
@@ -483,7 +488,15 @@ int main_loop(void) shared_page->vcpu_iodata[send_vcpu].dm_eport); } } -destroy_hvm_domain (); +if (!suspend_requested) +destroy_hvm_domain (); +else { +char qemu_file[20 ]; +sprintf (qemu_file,"/tmp/xen.qemu-dm.%d" , domid); +if (qemu_savevm (qemu_file) <0 ) +fprintf (stderr,"qemu save fail.\n" ); + } +return 0 ; }
tools/ioemu/vl.c +35 -0
@@ -3884,6 +3884,11 @@ int qemu_loadvm(const char *filename)qemu_fseek (f, cur_pos + record_len,SEEK_SET ); }fclose (f); + +/* del tmp file */ +if (unlink (filename) ==-1 ) +fprintf (stderr,"delete tmp qemu state file failed.\n" ); + ret =0 ; the_end:if (saved_vm_running)
@@ -4470,6 +4475,7 @@ static QEMUResetEntry *first_reset_entrystatic QEMUResetEntry *first_reset_entry;int reset_requested;int shutdown_requested; +int suspend_requested;static int powerdown_requested;void qemu_register_reset (QEMUResetHandler *func,void *opaque)
@@ -5242,6 +5248,14 @@ int set_mm_mapping(int xc_handle, uint32#endif return 0 ; +} + +void suspend (int sig) +{ +fprintf (logfile,"suspend sig handler called with requested=%d!\n" , suspend_requested); +if (sig !=SIGUSR1 ) +fprintf (logfile,"suspend signal dismatch, get sig=%d!\n" , sig); + suspend_requested =1 ; }int main (int argc,char **argv)
@@ -6010,6 +6024,27 @@ int main(int argc, char **argv)vm_start (); } } + +/* register signal for the suspend request when save */ + { +struct sigaction act; +sigset_t set; + act.sa_handler = suspend; + act.sa_flags =SA_RESTART ; +sigemptyset (&act.sa_mask); + +if (sigaction (SIGUSR1 , &act,0 ) ==-1 ) +fprintf (stderr,"sigaction fail!\n" ); + +/* control panel mask some signals when spawn qemu, need unmask here*/ +sigemptyset (&set); +sigaddset (&set,SIGUSR1 ); +sigaddset (&set,SIGTERM ); +if (sigprocmask (SIG_UNBLOCK , &set,NULL ) ==-1 ) +fprintf (stderr,"unblock signal fail!\n" ); + + } +main_loop ();quit_timers ();return 0 ;
tools/libxc/Makefile +1 -1
@@ -33,7 +33,7 @@ GUEST_SRCS-$(CONFIG_X86) += xc_linux_bui GUEST_SRCS-$(CONFIG_X86) += xc_linux_build.c GUEST_SRCS-$(CONFIG_IA64) += xc_ia64_stubs.c xc_linux_build.c GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c -GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c +GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c xc_hvm_restore.c xc_hvm_save.c CFLAGS += -Werror CFLAGS += -fno-strict-aliasing
tools/libxc/xc_domain.c +44 -0
50 lines not on this page · raw message
tools/libxc/xc_hvm_build.c +2 -2
@@ -60,11 +60,11 @@ static unsigned char build_e820map(void/* XXX: Doesn't work for > 4GB yet */ e820entry[nr_map].addr =0x0 ; - e820entry[nr_map].size =0x9F800 ; + e820entry[nr_map].size =0x90000 ; e820entry[nr_map].type =E820_RAM ; nr_map++; - e820entry[nr_map].addr =0x9F800 ; + e820entry[nr_map].addr =0x90000 ; e820entry[nr_map].size =0x800 ; e820entry[nr_map].type =E820_RESERVED ; nr_map++;
tools/libxc/xc_linux_save.c +1 -10
@@ -261,15 +261,6 @@ static int ratewrite(int io_fd, void *bu#endif -static inline ssize_t write_exact (int fd,void *buf,size_t count) -{ -if (write (fd, buf, count) != count) -return 0 ; -return 1 ; -} - - -static int print_stats (int xc_handle,uint32_t domid,int pages_sent,xc_shadow_control_stats_t *stats,int print) {
@@ -358,7 +349,7 @@ static int analysis_phase(int xc_handle, } -static int suspend_and_state (int (*suspend)(int ),int xc_handle,int io_fd, +int suspend_and_state (int (*suspend)(int ),int xc_handle,int io_fd,int dom,xc_dominfo_t *info,vcpu_guest_context_t *ctxt) {
tools/libxc/xenctrl.h +24 -0
@@ -286,6 +286,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. *
tools/libxc/xenguest.h +19 -0
@@ -11,6 +11,7 @@#define XCFLAGS_LIVE 1#define XCFLAGS_DEBUG 2 +#define XCFLAGS_HVM 4/**
@@ -25,6 +26,13 @@ int xc_linux_save(int xc_handle, int io_ uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */, int (*suspend)(int domid)); +/** +* This function will save a hvm domain running unmodified guest. +* @return 0 on success, -1 on failure +*/ +int xc_hvm_save (int xc_handle,int io_fd,uint32_t dom,uint32_t max_iters, +uint32_t max_factor,uint32_t flags/* XCFLAGS_xxx */ , +int (*suspend)(int domid));/** * This function will restore a saved domain running Linux.
@@ -41,6 +49,17 @@ int xc_linux_restore(int xc_handle, int unsigned long nr_pfns, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, unsigned long *console_mfn); + +/** +* This function will restore a saved hvm domain running unmodified guest. +* +* @parm store_mfn pass mem size & returned with the mfn of the store page +* @return 0 on success, -1 on failure +*/ +int xc_hvm_restore (int xc_handle,int io_fd,uint32_t dom, +unsigned long nr_pfns,unsigned int store_evtchn, +unsigned long *store_mfn,unsigned int console_evtchn, +unsigned long *console_mfn);/** * This function will create a domain for a paravirtualized Linux
tools/libxc/xg_save_restore.h +10 -0
@@ -65,6 +65,16 @@ static int get_platform_info(int xc_handreturn 1 ; } +static inline ssize_t write_exact (int fd,void *buf,size_t count) +{ +if (write (fd, buf, count) != count) +return 0 ; +return 1 ; +} + +extern int suspend_and_state (int (*suspend)(int ),int xc_handle,int io_fd, +int dom,xc_dominfo_t *info, +vcpu_guest_context_t *ctxt);/* ** Save/restore deal with the mfn_to_pfn (M2P) and pfn_to_mfn (P2M) tables.
tools/python/xen/lowlevel/xc/xc.c +22 -0
@@ -132,6 +132,20 @@ static PyObject *pyxc_domain_destroy(XcOstatic PyObject *pyxc_domain_destroy (XcObject *self,PyObject *args) {return dom_op (self, args, xc_domain_destroy); +} + +static PyObject *pyxc_domain_shutdown (XcObject *self,PyObject *args) +{ +uint32_t dom, reason; + +if (!PyArg_ParseTuple (args,"ii" , &dom, &reason)) +return NULL ; + +if (xc_domain_shutdown (self->xc_handle, dom, reason) !=0 ) +return PyErr_SetFromErrno (xc_error); + +Py_INCREF (zero); +return zero; }
@@ -966,6 +980,14 @@ static PyMethodDef pyxc_methods[] = {METH_VARARGS ,"\n" "Destroy a domain.\n" " dom [int]: Identifier of domain to be destroyed.\n\n" + "Returns: [int] 0 on success; -1 on error.\n" }, + + { "domain_shutdown", + (PyCFunction )pyxc_domain_shutdown, +METH_VARARGS ,"\n" +"Shutdown a domain.\n" +" dom [int, 0]: Domain identifier to use.\n" +" reason [int, 0]: Reason for shutdown.\n" "Returns: [int] 0 on success; -1 on error.\n" }, { "vcpu_setaffinity",
tools/python/xen/xend/XendCheckpoint.py +58 -6
116 lines not on this page · raw message
tools/python/xen/xend/XendDomainInfo.py +18 -1
@@ -668,6 +668,13 @@ class XendDomainInfo: self.console_mfn = console_mfn self.introduceDomain() + if self.info['image'][0] == 'hvm': + self.image = image.create(self, + self.info['image'], + self.info['device']) + if self.image: + log.debug("createDevicemodel for hvm domain restore") + self.image.createDeviceModel(True) self.storeDomDetails() self.registerWatches() self.refreshShutdown()
@@ -945,6 +952,13 @@ class XendDomainInfo: raise XendError('Invalid reason: %s' % reason) self.storeDom("control/shutdown", reason) + ## shutdown hypercall for hvm domain desides xenstore write + if self.info['image'][0] == 'hvm': + for code in shutdown_reasons.keys(): + if shutdown_reasons[code] == reason: + break + xc.domain_shutdown(self.domid, code) + ## private:
@@ -1417,8 +1431,11 @@ class XendDomainInfo: ## private: - def release_devices(self): + def release_devices(self, suspend = False): """Release all domain's devices. Nothrow guarantee.""" + if suspend and self.image: + self.image.destroy(suspend) + return while True: t = xstransact("%s/device" % self.dompath)
tools/python/xen/xend/image.py +10 -4
@@ -157,7 +157,7 @@ class ImageHandler: """Build the domain. Define in subclass.""" raise NotImplementedError() - def createDeviceModel(self): + def createDeviceModel(self, restore = False): """Create device model for the domain (define in subclass if needed).""" pass
@@ -331,7 +331,7 @@ class HVMImageHandler(ImageHandler): ret = ret + ['-vnc', '%d' % vncdisplay, '-k', 'en-us'] return ret - def createDeviceModel(self): + def createDeviceModel(self, restore = False): if self.pid: return # Execute device model.
@@ -340,6 +340,8 @@ class HVMImageHandler(ImageHandler): args = args + ([ "-d", "%d" % self.vm.getDomid(), "-m", "%s" % (self.vm.getMemoryTarget() / 1024)]) args = args + self.dmargs + if restore: + args = args + ([ "-loadvm", "/tmp/xen.qemu-dm.%d" % self.vm.getDomid() ]) env = dict(os.environ) if self.display: env['DISPLAY'] = self.display
@@ -351,12 +353,16 @@ class HVMImageHandler(ImageHandler): self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env) log.info("device model pid: %d", self.pid) - def destroy(self): + def destroy(self, suspend = False): self.unregister_shutdown_watch(); import signal if not self.pid: return - os.kill(self.pid, signal.SIGKILL) + sig = signal.SIGKILL + if suspend: + log.info("use sigusr1 to signal qemu %d", self.pid) + sig = signal.SIGUSR1 + os.kill(self.pid, sig) os.waitpid(self.pid, 0) self.pid = 0
tools/xcutils/xc_restore.c +13 -4
@@ -18,12 +18,13 @@ main(int argc, char **argv) main(int argc, char **argv) {unsigned int xc_fd, io_fd, domid, nr_pfns, store_evtchn, console_evtchn; +unsigned int hvm;int ret;unsigned long store_mfn, console_mfn; -if (argc !=7 ) +if (argc !=8 )errx (1 , -"usage: %s xcfd iofd domid nr_pfns store_evtchn console_evtchn" , +"usage: %s xcfd iofd domid nr_pfns store_evtchn console_evtchn is_hvm" , argv[0 ]); xc_fd =atoi (argv[1 ]);
@@ -32,9 +33,17 @@ main(int argc, char **argv) nr_pfns =atoi (argv[4 ]); store_evtchn =atoi (argv[5 ]); console_evtchn =atoi (argv[6 ]); + hvm =atoi (argv[7 ]); - ret =xc_linux_restore (xc_fd, io_fd, domid, nr_pfns, store_evtchn, - &store_mfn, console_evtchn, &console_mfn); +if (hvm) { +/* pass the memsize to xc_hvm_restore to find the store_mfn */ + store_mfn = hvm; + ret =xc_hvm_restore (xc_fd, io_fd, domid, nr_pfns, store_evtchn, + &store_mfn, console_evtchn, &console_mfn); + }else + ret =xc_linux_restore (xc_fd, io_fd, domid, nr_pfns, store_evtchn, + &store_mfn, console_evtchn, &console_mfn); +if (ret ==0 ) {printf ("store-mfn %li\n" , store_mfn);printf ("console-mfn %li\n" , console_mfn);
tools/xcutils/xc_save.c +4 -1
@@ -47,5 +47,8 @@ main(int argc, char **argv) max_f =atoi (argv[5 ]); flags =atoi (argv[6 ]); -return xc_linux_save (xc_fd, io_fd, domid, maxit, max_f, flags, &suspend); +if (flags &XCFLAGS_HVM ) +return xc_hvm_save (xc_fd, io_fd, domid, maxit, max_f, flags, &suspend); +else +return xc_linux_save (xc_fd, io_fd, domid, maxit, max_f, flags, &suspend); }
xen/arch/x86/dom0_ops.c +20 -0
@@ -454,6 +454,7 @@ void arch_getdomaininfo_ctxt(if (hvm_guest (v) ) {hvm_store_cpu_guest_regs (v, &c->user_regs, c->ctrlreg); +hvm_save_cpu_context (v, &c->hvmcpu_ctxt); }else {
@@ -473,6 +474,25 @@ void arch_getdomaininfo_ctxt( c->ctrlreg[3 ] =xen_pfn_to_cr3 (pagetable_get_pfn (v->arch.guest_table)); c->vm_assist = v->domain->vm_assist; +} + +void arch_gethvm_ctxt ( +struct vcpu *v,struct hvm_domain_context *c) +{ +if ( !hvm_guest (v) ) +return ; + +hvm_save (v, c); + +} + +void arch_sethvm_ctxt ( +struct vcpu *v,struct hvm_domain_context *c) +{ +if ( !hvm_guest (v) ) +return ; + +hvm_load (v, c); }/*
xen/arch/x86/hvm/hvm.c +12 -0
@@ -182,6 +182,8 @@ static void hvm_get_info(struct domain *unmap_domain_page (p); } +extern void arch_sethvm_ctxt ( +struct vcpu *,struct hvm_domain_context *);void hvm_setup_platform (struct domain * d) {struct hvm_domain *platform;
@@ -211,6 +213,16 @@ void hvm_setup_platform(struct domain* dinit_timer (&platform->pl_time.periodic_tm.timer, pt_timer_fn, v, v->processor);pit_init (v, cpu_khz); + +/* restore hvm context including pic/pit/shpage */ +shpage_init (get_sp (d)); + +if (platform->hvm_ctxt) { +arch_sethvm_ctxt (current, platform->hvm_ctxt); +xfree (platform->hvm_ctxt); + platform->hvm_ctxt =NULL ; + } + }void pic_irq_request (void *data,int level)
xen/arch/x86/hvm/i8254.c +138 -0
150 lines not on this page · raw message
xen/arch/x86/hvm/i8259.c +79 -0
91 lines not on this page · raw message
xen/arch/x86/hvm/intercept.c +262 -0
274 lines not on this page · raw message
xen/arch/x86/hvm/svm/svm.c +8 -0
@@ -763,6 +763,7 @@ static void svm_relinquish_guest_resourc {extern void destroy_vmcb (struct arch_svm_struct *);/* XXX */ struct vcpu *v; +HVMStateEntry *se, *dse; for_each_vcpu ( d, v ) {
@@ -780,6 +781,13 @@ static void svm_relinquish_guest_resourc }kill_timer (&d->arch.hvm_domain.pl_time.periodic_tm.timer); + + 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(
xen/arch/x86/hvm/vmx/vmcs.c +1 -0
@@ -572,6 +572,7 @@ void arch_vmx_do_launch(struct vcpu *v) }vmx_do_launch (v); +hvm_load_cpu_context (v, &v->arch.guest_context.hvmcpu_ctxt);reset_stack_and_jump (vmx_asm_do_vmentry); }
xen/arch/x86/hvm/vmx/vmx.c +342 -0
366 lines not on this page · raw message
xen/common/dom0_ops.c +73 -0
85 lines not on this page · raw message
xen/include/asm-x86/hvm/domain.h +16 -0
@@ -30,6 +30,20 @@#define HVM_PBUF_SIZE 80 +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 int nr_vcpus;
@@ -48,6 +62,8 @@ struct hvm_domain {int pbuf_index;char pbuf[HVM_PBUF_SIZE ]; +struct hvm_domain_context *hvm_ctxt; + HVMStateEntry *first_se; };#endif /* __ASM_X86_HVM_DOMAIN_H__ */
xen/include/asm-x86/hvm/hvm.h +21 -0
@@ -47,6 +47,13 @@ struct hvm_function_table { struct vcpu *v, struct cpu_user_regs *r, unsigned long *crs);void (*load_cpu_guest_regs)(struct vcpu *v,struct cpu_user_regs *r); + +/* save and load hvm guest cpu context for save/restore */ +void (*save_cpu_ctxt)( +struct vcpu *v,struct hvmcpu_context *ctxt); +void (*load_cpu_ctxt)( +struct vcpu *v,struct hvmcpu_context *ctxt); +/* * Examine specifics of the guest state: * 1) determine whether the guest is in real or vm8086 mode,
@@ -103,6 +110,20 @@ hvm_load_cpu_guest_regs(struct vcpu *v, hvm_funcs.load_cpu_guest_regs (v, r); } +static inline void +hvm_save_cpu_context ( +struct vcpu *v,struct hvmcpu_context *ctxt) +{ + hvm_funcs.save_cpu_ctxt (v, ctxt); +} + +static inline void +hvm_load_cpu_context ( +struct vcpu *v,struct hvmcpu_context *ctxt) +{ + hvm_funcs.load_cpu_ctxt (v, ctxt); +} +static inline int hvm_realmode (struct vcpu *v) {
xen/include/asm-x86/hvm/support.h +124 -0
136 lines not on this page · raw message
xen/include/public/arch-x86_32.h +8 -0
@@ -142,6 +142,13 @@ DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t)DEFINE_XEN_GUEST_HANDLE (cpu_user_regs_t);typedef uint64_t tsc_timestamp_t ;/* RDTSC timestamp */ + +#include "vmcs_data.h" + +struct hvmcpu_context { +uint32_t valid; +struct vmcs_data data; +};/* * The following is all CPU context. Note that the fpu_ctxt block is filled
@@ -174,6 +181,7 @@ struct vcpu_guest_context {unsigned long failsafe_callback_cs;/* CS:EIP of failsafe callback */ unsigned long failsafe_callback_eip;unsigned long vm_assist;/* VMASST_TYPE_* bitmap */ +struct hvmcpu_context hvmcpu_ctxt;/* whole vmcs region */ };typedef struct vcpu_guest_context vcpu_guest_context_t ;DEFINE_XEN_GUEST_HANDLE (vcpu_guest_context_t);
xen/include/public/arch-x86_64.h +8 -0
@@ -212,6 +212,13 @@ DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t)#undef __DECL_REGtypedef uint64_t tsc_timestamp_t ;/* RDTSC timestamp */ + +#include "vmcs_data.h" + +struct hvmcpu_context { +uint32_t valid; +struct vmcs_data data; +};/* * The following is all CPU context. Note that the fpu_ctxt block is filled
@@ -249,6 +256,7 @@ struct vcpu_guest_context {uint64_t fs_base;uint64_t gs_base_kernel;uint64_t gs_base_user; +struct hvmcpu_context hvmcpu_ctxt;/* whole vmcs region */ };typedef struct vcpu_guest_context vcpu_guest_context_t ;DEFINE_XEN_GUEST_HANDLE (vcpu_guest_context_t);
xen/include/public/dom0_ops.h +27 -0
@@ -535,6 +535,31 @@ struct dom0_settimeoffset { };typedef struct dom0_settimeoffset dom0_settimeoffset_t ;DEFINE_XEN_GUEST_HANDLE (dom0_settimeoffset_t); + +#define HVM_CTXT_SIZE 4096 +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 DOM0_GETHVMCONTEXT 51 +typedef struct dom0_gethvmcontext { +/* IN variables. */ +domid_t domain;/* domain to be affected */ +/* OUT variables. */ +XEN_GUEST_HANDLE (hvm_domain_context_t) hvm_ctxt; +}dom0_gethvmcontext_t ; +DEFINE_XEN_GUEST_HANDLE (dom0_gethvmcontext_t); + +#define DOM0_SETHVMCONTEXT 52 +typedef struct dom0_sethvmcontext { +/* IN variables. */ +domid_t domain;/* domain to be affected */ +/* OUT variables. */ +XEN_GUEST_HANDLE (hvm_domain_context_t) hvm_ctxt; +}dom0_sethvmcontext_t ; +DEFINE_XEN_GUEST_HANDLE (dom0_sethvmcontext_t);struct dom0_op {uint32_t cmd;
@@ -579,6 +604,8 @@ struct dom0_op {struct dom0_hypercall_init hypercall_init;struct dom0_domain_setup domain_setup;struct dom0_settimeoffset settimeoffset; +struct dom0_gethvmcontext gethvmcontext; +struct dom0_sethvmcontext sethvmcontext;uint8_t pad[128 ]; } u; };
tools/libxc/xc_hvm_restore.c new file +264 -0
264 lines not on this page · raw message
tools/libxc/xc_hvm_save.c new file +207 -0
207 lines not on this page · raw message
xen/include/public/vmcs_data.h new file +68 -0
68 lines not on this page · raw message
# HG changeset patch
# User Edwin Zhai <[email protected]>
# Node ID 98c3ddf83a59b0cbbdce63bb210adfd0d2ec1aea # Parent ecb8ff1fcf1fc24561c8bd272a58828592d90806 cirrus&rtl8139 coexist issue fix
tools/ioemu/target-i386-dm/exec-dm.c +1 -1
@@ -382,7 +382,7 @@ int iomem_index(target_phys_addr_t addr) start = mmio[i].start; end = mmio[i].start + mmio[i].size; -if ((addr >= start) && (addr <= end)){ +if ((addr >= start) && (addr < end)){return (mmio[i].io_index >>IO_MEM_SHIFT ) & (IO_MEM_NB_ENTRIES -1 ); } }
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel