[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC v12 15/21] pvh: Set up more PV stuff in set_info_guest
Allow the guest to set up a few more things when bringing up a vcpu. This includes cr3 and gs_base. Also set up wallclock, and only initialize a vcpu once. Signed-off-by: George Dunlap <george.dunlap@xxxxxxxxxxxxx> Signed-off-by: Mukesh Rathor <mukesh.rathor@xxxxxxxxxx> CC: Jan Beulich <jan.beulich@xxxxxxxx> CC: Tim Deegan <tim@xxxxxxx> CC: Keir Fraser <keir@xxxxxxx> --- xen/arch/x86/domain.c | 27 ++++++++++++++++++++++++++- xen/arch/x86/hvm/vmx/vmx.c | 34 ++++++++++++++++++++++++++++++++++ xen/include/asm-x86/hvm/hvm.h | 8 ++++++++ xen/include/asm-x86/hvm/vmx/vmx.h | 2 ++ xen/include/public/arch-x86/xen.h | 4 ++++ 5 files changed, 74 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 02a6479..d046790 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -737,7 +737,31 @@ int arch_set_info_guest( if ( has_hvm_container_vcpu(v) ) { hvm_set_info_guest(v); - goto out; + + if ( is_hvm_vcpu(v) || v->is_initialised ) + goto out; + + /* PVH */ + if ( c.nat->ctrlreg[1] ) + return -EINVAL; + + ASSERT(!compat); + + cr3_gfn = xen_cr3_to_pfn(c.nat->ctrlreg[3]); + cr3_page = get_page_from_gfn(d, cr3_gfn, NULL, P2M_ALLOC); + + v->arch.cr3 = page_to_maddr(cr3_page); + v->arch.hvm_vcpu.guest_cr[3] = c.nat->ctrlreg[3]; + + if ( paging_mode_enabled(d) ) + paging_update_paging_modes(v); + + update_cr3(v); + + if ( (rc = pvh_vcpu_boot_set_info(v, c.nat)) != 0 ) + return rc; + + goto pvh_skip_pv_stuff; } init_int80_direct_trap(v); @@ -947,6 +971,7 @@ int arch_set_info_guest( update_cr3(v); + pvh_skip_pv_stuff: if ( v->vcpu_id == 0 ) update_domain_wallclock_time(d); diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index c2156af..b3f933a 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -122,6 +122,39 @@ static int vmx_vcpu_initialise(struct vcpu *v) return 0; } +/* + * Set vmcs fields during boot of a vcpu. Called from arch_set_info_guest. + * + * Boot vcpu call is from tools via: + * do_domctl -> XEN_DOMCTL_setvcpucontext -> arch_set_info_guest + * + * Secondary vcpu's are brought up by the guest itself via: + * do_vcpu_op -> VCPUOP_initialise -> arch_set_info_guest + * (In case of linux, the call comes from cpu_initialize_context()). + * + * Note, PVH save/restore is expected to happen the HVM way, ie, + * do_domctl -> XEN_DOMCTL_sethvmcontext -> hvm_load/save + * and not get here. + * + * PVH 32bitfixme: this function needs to be modified for 32bit guest. + */ +int vmx_pvh_vcpu_boot_set_info(struct vcpu *v, + struct vcpu_guest_context *ctxtp) +{ + if ( ctxtp->ldt_base || ctxtp->ldt_ents || + ctxtp->user_regs.cs || ctxtp->user_regs.ss || ctxtp->user_regs.es || + ctxtp->user_regs.ds || ctxtp->user_regs.fs || ctxtp->user_regs.gs || + *ctxtp->gdt_frames || ctxtp->gdt_ents || + ctxtp->fs_base || ctxtp->gs_base_user ) + return -EINVAL; + + vmx_vmcs_enter(v); + __vmwrite(GUEST_GS_BASE, ctxtp->gs_base_kernel); + vmx_vmcs_exit(v); + + return 0; +} + static void vmx_vcpu_destroy(struct vcpu *v) { vmx_destroy_vmcs(v); @@ -1606,6 +1639,7 @@ static struct hvm_function_table __initdata vmx_function_table = { .handle_eoi = vmx_handle_eoi, .nhvm_hap_walk_L1_p2m = nvmx_hap_walk_L1_p2m, .read_selector = vmx_read_selector, + .pvh_vcpu_boot_set_info = vmx_pvh_vcpu_boot_set_info, }; const struct hvm_function_table * __init start_vmx(void) diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h index 401fa4c..d81a744 100644 --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -194,6 +194,8 @@ struct hvm_function_table { uint8_t *p2m_acc, bool_t access_r, bool_t access_w, bool_t access_x); u16 (*read_selector)(struct vcpu *v, enum x86_segment seg); + int (*pvh_vcpu_boot_set_info)(struct vcpu *v, + struct vcpu_guest_context *ctxtp); }; extern struct hvm_function_table hvm_funcs; @@ -327,6 +329,12 @@ static inline unsigned long hvm_get_shadow_gs_base(struct vcpu *v) return hvm_funcs.get_shadow_gs_base(v); } +static inline int pvh_vcpu_boot_set_info(struct vcpu *v, + struct vcpu_guest_context *ctxtp) +{ + return hvm_funcs.pvh_vcpu_boot_set_info(v, ctxtp); +} + #define is_viridian_domain(_d) \ (is_hvm_domain(_d) && ((_d)->arch.hvm_domain.params[HVM_PARAM_VIRIDIAN])) diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h index c33b9f9..623e4ce 100644 --- a/xen/include/asm-x86/hvm/vmx/vmx.h +++ b/xen/include/asm-x86/hvm/vmx/vmx.h @@ -458,6 +458,8 @@ void ept_walk_table(struct domain *d, unsigned long gfn); void setup_ept_dump(void); void update_guest_eip(void); +int vmx_pvh_vcpu_boot_set_info(struct vcpu *v, + struct vcpu_guest_context *ctxtp); int alloc_p2m_hap_data(struct p2m_domain *p2m); void free_p2m_hap_data(struct p2m_domain *p2m); diff --git a/xen/include/public/arch-x86/xen.h b/xen/include/public/arch-x86/xen.h index b7f6a51..4f12f50 100644 --- a/xen/include/public/arch-x86/xen.h +++ b/xen/include/public/arch-x86/xen.h @@ -150,6 +150,10 @@ typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */ /* * The following is all CPU context. Note that the fpu_ctxt block is filled * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used. + * + * PVH 64bit: In the vcpu boot path, for vmcs context, only gs_base_kernel + * is honored. Other fields like gdt, ldt, and selectors must be + * zeroed. See vmx_pvh_vcpu_boot_set_info. */ struct vcpu_guest_context { /* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */ -- 1.7.9.5 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |