ia64/xen-unstable
changeset 13542:dccdc3ee0efc
[HVM] Save/restore cleanups 02: VCPU
Save/restore vcpu state therough the streaming interface
Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
Save/restore vcpu state therough the streaming interface
Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
author | Tim Deegan <Tim.Deegan@xensource.com> |
---|---|
date | Sat Jan 20 11:17:39 2007 +0000 (2007-01-20) |
parents | 56228886421d |
children | 2457741f4ec3 |
files | xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/hvm/hvm.h xen/include/public/arch-x86/xen.h xen/include/public/hvm/save.h |
line diff
1.1 --- a/xen/arch/x86/hvm/hvm.c Sat Jan 20 11:17:38 2007 +0000 1.2 +++ b/xen/arch/x86/hvm/hvm.c Sat Jan 20 11:17:39 2007 +0000 1.3 @@ -174,6 +174,10 @@ int hvm_vcpu_initialise(struct vcpu *v) 1.4 { 1.5 int rc; 1.6 1.7 + hvm_register_savevm(v->domain, "xen_hvm_cpu", v->vcpu_id, 1, 1.8 + hvm_funcs.save_cpu_ctxt, hvm_funcs.load_cpu_ctxt, 1.9 + (void *)v); 1.10 + 1.11 if ( (rc = vlapic_init(v)) != 0 ) 1.12 return rc; 1.13
2.1 --- a/xen/arch/x86/hvm/vmx/vmx.c Sat Jan 20 11:17:38 2007 +0000 2.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c Sat Jan 20 11:17:39 2007 +0000 2.3 @@ -47,6 +47,7 @@ 2.4 #include <asm/hvm/vlapic.h> 2.5 #include <asm/x86_emulate.h> 2.6 #include <asm/hvm/vpt.h> 2.7 +#include <public/hvm/save.h> 2.8 2.9 static void vmx_ctxt_switch_from(struct vcpu *v); 2.10 static void vmx_ctxt_switch_to(struct vcpu *v); 2.11 @@ -364,7 +365,7 @@ static inline void __restore_debug_regis 2.12 } 2.13 2.14 static int __get_instruction_length(void); 2.15 -int vmx_vmcs_save(struct vcpu *v, struct vmcs_data *c) 2.16 +int vmx_vmcs_save(struct vcpu *v, struct hvm_hw_cpu *c) 2.17 { 2.18 unsigned long inst_len; 2.19 2.20 @@ -443,7 +444,7 @@ int vmx_vmcs_save(struct vcpu *v, struct 2.21 return 1; 2.22 } 2.23 2.24 -int vmx_vmcs_restore(struct vcpu *v, struct vmcs_data *c) 2.25 +int vmx_vmcs_restore(struct vcpu *v, struct hvm_hw_cpu *c) 2.26 { 2.27 unsigned long mfn, old_base_mfn; 2.28 2.29 @@ -590,9 +591,8 @@ static void dump_msr_state(struct vmx_ms 2.30 } 2.31 #endif 2.32 2.33 -void vmx_save_cpu_state(struct vcpu *v, struct hvmcpu_context *ctxt) 2.34 +void vmx_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data) 2.35 { 2.36 - struct vmcs_data *data = &ctxt->data; 2.37 struct vmx_msr_state *guest_state = &v->arch.hvm_vmx.msr_state; 2.38 unsigned long guest_flags = guest_state->flags; 2.39 int i = 0; 2.40 @@ -603,14 +603,15 @@ void vmx_save_cpu_state(struct vcpu *v, 2.41 data->flags = guest_flags; 2.42 for (i = 0; i < VMX_MSR_COUNT; i++) 2.43 data->msr_items[i] = guest_state->msrs[i]; 2.44 - 2.45 + 2.46 + data->tsc = hvm_get_guest_time(v); 2.47 + 2.48 dump_msr_state(guest_state); 2.49 } 2.50 2.51 -void vmx_load_cpu_state(struct vcpu *v, struct hvmcpu_context *ctxt) 2.52 +void vmx_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data) 2.53 { 2.54 int i = 0; 2.55 - struct vmcs_data *data = &ctxt->data; 2.56 struct vmx_msr_state *guest_state = &v->arch.hvm_vmx.msr_state; 2.57 2.58 /* restore msrs */ 2.59 @@ -625,35 +626,42 @@ void vmx_load_cpu_state(struct vcpu *v, 2.60 2.61 v->arch.hvm_vmx.vmxassist_enabled = data->vmxassist_enabled; 2.62 2.63 + hvm_set_guest_time(v, data->tsc); 2.64 + 2.65 dump_msr_state(guest_state); 2.66 } 2.67 2.68 -void vmx_save_vmcs_ctxt(struct vcpu *v, struct hvmcpu_context *ctxt) 2.69 + 2.70 +void vmx_save_vmcs_ctxt(hvm_domain_context_t *h, void *opaque) 2.71 { 2.72 - struct vmcs_data *data = &ctxt->data; 2.73 - 2.74 - vmx_save_cpu_state(v, ctxt); 2.75 - 2.76 + struct vcpu *v = opaque; 2.77 + struct hvm_hw_cpu ctxt; 2.78 + 2.79 + vmx_save_cpu_state(v, &ctxt); 2.80 vmx_vmcs_enter(v); 2.81 - 2.82 - vmx_vmcs_save(v, data); 2.83 - 2.84 + vmx_vmcs_save(v, &ctxt); 2.85 vmx_vmcs_exit(v); 2.86 2.87 + hvm_put_struct(h, &ctxt); 2.88 } 2.89 2.90 -void vmx_load_vmcs_ctxt(struct vcpu *v, struct hvmcpu_context *ctxt) 2.91 +int vmx_load_vmcs_ctxt(hvm_domain_context_t *h, void *opaque, int version) 2.92 { 2.93 - vmx_load_cpu_state(v, ctxt); 2.94 - 2.95 - if (vmx_vmcs_restore(v, &ctxt->data)) { 2.96 + struct vcpu *v = opaque; 2.97 + struct hvm_hw_cpu ctxt; 2.98 + 2.99 + if (version != 1) 2.100 + return -EINVAL; 2.101 + 2.102 + hvm_get_struct(h, &ctxt); 2.103 + vmx_load_cpu_state(v, &ctxt); 2.104 + if (vmx_vmcs_restore(v, &ctxt)) { 2.105 printk("vmx_vmcs restore failed!\n"); 2.106 domain_crash(v->domain); 2.107 + return -EINVAL; 2.108 } 2.109 2.110 - /* only load vmcs once */ 2.111 - ctxt->valid = 0; 2.112 - 2.113 + return 0; 2.114 } 2.115 2.116 /*
3.1 --- a/xen/include/asm-x86/hvm/hvm.h Sat Jan 20 11:17:38 2007 +0000 3.2 +++ b/xen/include/asm-x86/hvm/hvm.h Sat Jan 20 11:17:39 2007 +0000 3.3 @@ -22,6 +22,8 @@ 3.4 #define __ASM_X86_HVM_HVM_H__ 3.5 3.6 #include <asm/x86_emulate.h> 3.7 +#include <public/domctl.h> 3.8 +#include <public/hvm/save.h> 3.9 3.10 /* 3.11 * Attribute for segment selector. This is a copy of bit 40:47 & 52:55 of the 3.12 @@ -81,10 +83,8 @@ struct hvm_function_table { 3.13 struct vcpu *v, struct cpu_user_regs *r); 3.14 3.15 /* save and load hvm guest cpu context for save/restore */ 3.16 - void (*save_cpu_ctxt)( 3.17 - struct vcpu *v, struct hvmcpu_context *ctxt); 3.18 - void (*load_cpu_ctxt)( 3.19 - struct vcpu *v, struct hvmcpu_context *ctxt); 3.20 + void (*save_cpu_ctxt)(hvm_domain_context_t *h, void *opaque); 3.21 + int (*load_cpu_ctxt)(hvm_domain_context_t *h, void *opaque, int version); 3.22 3.23 /* 3.24 * Examine specifics of the guest state: 3.25 @@ -167,32 +167,6 @@ hvm_load_cpu_guest_regs(struct vcpu *v, 3.26 void hvm_set_guest_time(struct vcpu *v, u64 gtime); 3.27 u64 hvm_get_guest_time(struct vcpu *v); 3.28 3.29 -static inline void 3.30 -hvm_save_cpu_context( 3.31 - struct vcpu *v, struct hvmcpu_context *ctxt) 3.32 -{ 3.33 - hvm_funcs.save_cpu_ctxt(v, ctxt); 3.34 - 3.35 - /* save guest time */ 3.36 - ctxt->gtime = hvm_get_guest_time(v); 3.37 - 3.38 - /* set valid flag to recover whole vmcs when restore */ 3.39 - ctxt->valid = 0x55885588; 3.40 -} 3.41 - 3.42 -static inline void 3.43 -hvm_load_cpu_context( 3.44 - struct vcpu *v, struct hvmcpu_context *ctxt) 3.45 -{ 3.46 - if ( ctxt->valid != 0x55885588) 3.47 - return; 3.48 - 3.49 - hvm_funcs.load_cpu_ctxt(v, ctxt); 3.50 - 3.51 - /* restore guest time*/ 3.52 - hvm_set_guest_time(v, ctxt->gtime); 3.53 -} 3.54 - 3.55 static inline int 3.56 hvm_paging_enabled(struct vcpu *v) 3.57 {
4.1 --- a/xen/include/public/arch-x86/xen.h Sat Jan 20 11:17:38 2007 +0000 4.2 +++ b/xen/include/public/arch-x86/xen.h Sat Jan 20 11:17:39 2007 +0000 4.3 @@ -109,70 +109,6 @@ DEFINE_XEN_GUEST_HANDLE(trap_info_t); 4.4 typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */ 4.5 4.6 /* 4.7 - * World vmcs state 4.8 - */ 4.9 -struct vmcs_data { 4.10 - uint64_t eip; /* execution pointer */ 4.11 - uint64_t esp; /* stack pointer */ 4.12 - uint64_t eflags; /* flags register */ 4.13 - uint64_t cr0; 4.14 - uint64_t cr3; /* page table directory */ 4.15 - uint64_t cr4; 4.16 - uint32_t idtr_limit; /* idt */ 4.17 - uint64_t idtr_base; 4.18 - uint32_t gdtr_limit; /* gdt */ 4.19 - uint64_t gdtr_base; 4.20 - uint32_t cs_sel; /* cs selector */ 4.21 - uint32_t cs_limit; 4.22 - uint64_t cs_base; 4.23 - uint32_t cs_arbytes; 4.24 - uint32_t ds_sel; /* ds selector */ 4.25 - uint32_t ds_limit; 4.26 - uint64_t ds_base; 4.27 - uint32_t ds_arbytes; 4.28 - uint32_t es_sel; /* es selector */ 4.29 - uint32_t es_limit; 4.30 - uint64_t es_base; 4.31 - uint32_t es_arbytes; 4.32 - uint32_t ss_sel; /* ss selector */ 4.33 - uint32_t ss_limit; 4.34 - uint64_t ss_base; 4.35 - uint32_t ss_arbytes; 4.36 - uint32_t fs_sel; /* fs selector */ 4.37 - uint32_t fs_limit; 4.38 - uint64_t fs_base; 4.39 - uint32_t fs_arbytes; 4.40 - uint32_t gs_sel; /* gs selector */ 4.41 - uint32_t gs_limit; 4.42 - uint64_t gs_base; 4.43 - uint32_t gs_arbytes; 4.44 - uint32_t tr_sel; /* task selector */ 4.45 - uint32_t tr_limit; 4.46 - uint64_t tr_base; 4.47 - uint32_t tr_arbytes; 4.48 - uint32_t ldtr_sel; /* ldtr selector */ 4.49 - uint32_t ldtr_limit; 4.50 - uint64_t ldtr_base; 4.51 - uint32_t ldtr_arbytes; 4.52 - uint32_t sysenter_cs; 4.53 - uint64_t sysenter_esp; 4.54 - uint64_t sysenter_eip; 4.55 - /* msr for em64t */ 4.56 - uint64_t shadow_gs; 4.57 - uint64_t flags; 4.58 - /* same size as VMX_MSR_COUNT */ 4.59 - uint64_t msr_items[6]; 4.60 - uint64_t vmxassist_enabled; 4.61 -}; 4.62 -typedef struct vmcs_data vmcs_data_t; 4.63 - 4.64 -struct hvmcpu_context { 4.65 - uint32_t valid; 4.66 - struct vmcs_data data; 4.67 - uint64_t gtime; 4.68 -}; 4.69 - 4.70 -/* 4.71 * The following is all CPU context. Note that the fpu_ctxt block is filled 4.72 * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used. 4.73 */
5.1 --- a/xen/include/public/hvm/save.h Sat Jan 20 11:17:38 2007 +0000 5.2 +++ b/xen/include/public/hvm/save.h Sat Jan 20 11:17:39 2007 +0000 5.3 @@ -107,6 +107,9 @@ struct hvm_hw_cpu { 5.4 /* same size as VMX_MSR_COUNT */ 5.5 uint64_t msr_items[6]; 5.6 uint64_t vmxassist_enabled; 5.7 + 5.8 + /* guest's idea of what rdtsc() would return */ 5.9 + uint64_t tsc; 5.10 }; 5.11 5.12