[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] amd xsave: Enable XSAVE/XRSTOR for SVM guest
# HG changeset patch # User Keir Fraser <keir@xxxxxxx> # Date 1291746460 0 # Node ID 066c924ed467c7931e22d597eefc7ca89d782611 # Parent 98eb4a334b7723c3e515038feaddbd01cec45a3a amd xsave: Enable XSAVE/XRSTOR for SVM guest This patch creates a common interface hanlding xsetbv. Signed-off-by: Wei Huang <wei.huang2@xxxxxxx> --- xen/arch/x86/hvm/hvm.c | 25 +++++++++++++++++++++++++ xen/arch/x86/hvm/svm/emulate.c | 2 ++ xen/arch/x86/hvm/svm/svm.c | 7 +++++++ xen/arch/x86/hvm/vmx/vmx.c | 26 +------------------------- xen/include/asm-x86/hvm/support.h | 2 ++ xen/include/asm-x86/hvm/svm/emulate.h | 1 + xen/include/asm-x86/hvm/svm/vmcb.h | 1 + 7 files changed, 39 insertions(+), 25 deletions(-) diff -r 98eb4a334b77 -r 066c924ed467 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Tue Dec 07 18:26:38 2010 +0000 +++ b/xen/arch/x86/hvm/hvm.c Tue Dec 07 18:27:40 2010 +0000 @@ -1144,6 +1144,31 @@ bool_t hvm_hap_nested_page_fault(unsigne return 0; } +int hvm_handle_xsetbv(u64 new_bv) +{ + struct vcpu *v = current; + struct segment_register sreg; + + hvm_get_segment_register(v, x86_seg_ss, &sreg); + if ( sreg.attr.fields.dpl != 0 ) + goto err; + + if ( ((new_bv ^ xfeature_mask) & ~xfeature_mask) || !(new_bv & 1) ) + goto err; + + if ( (xfeature_mask & XSTATE_YMM & new_bv) && !(new_bv & XSTATE_SSE) ) + goto err; + + v->arch.xcr0 = new_bv; + v->arch.xcr0_accum |= new_bv; + set_xcr0(new_bv); + + return 0; +err: + hvm_inject_exception(TRAP_gp_fault, 0, 0); + return -1; +} + int hvm_set_efer(uint64_t value) { struct vcpu *v = current; diff -r 98eb4a334b77 -r 066c924ed467 xen/arch/x86/hvm/svm/emulate.c --- a/xen/arch/x86/hvm/svm/emulate.c Tue Dec 07 18:26:38 2010 +0000 +++ b/xen/arch/x86/hvm/svm/emulate.c Tue Dec 07 18:27:40 2010 +0000 @@ -101,6 +101,7 @@ MAKE_INSTR(INT3, 1, 0xcc); MAKE_INSTR(INT3, 1, 0xcc); MAKE_INSTR(RDTSC, 2, 0x0f, 0x31); MAKE_INSTR(PAUSE, 1, 0x90); +MAKE_INSTR(XSETBV, 3, 0x0f, 0x01, 0xd1); static const u8 *opc_bytes[INSTR_MAX_COUNT] = { @@ -114,6 +115,7 @@ static const u8 *opc_bytes[INSTR_MAX_COU [INSTR_INT3] = OPCODE_INT3, [INSTR_RDTSC] = OPCODE_RDTSC, [INSTR_PAUSE] = OPCODE_PAUSE, + [INSTR_XSETBV] = OPCODE_XSETBV, }; static int fetch(struct vcpu *v, u8 *buf, unsigned long addr, int len) diff -r 98eb4a334b77 -r 066c924ed467 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Tue Dec 07 18:26:38 2010 +0000 +++ b/xen/arch/x86/hvm/svm/svm.c Tue Dec 07 18:27:40 2010 +0000 @@ -1600,6 +1600,13 @@ asmlinkage void svm_vmexit_handler(struc hvm_inject_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE, 0); break; + case VMEXIT_XSETBV: + if ( (inst_len = __get_instruction_length(current, INSTR_XSETBV))==0 ) + break; + if ( hvm_handle_xsetbv((((u64)regs->edx) << 32) | regs->eax) == 0 ) + __update_guest_eip(regs, inst_len); + break; + case VMEXIT_NPF: perfc_incra(svmexits, VMEXIT_NPF_PERFC); regs->error_code = vmcb->exitinfo1; diff -r 98eb4a334b77 -r 066c924ed467 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Tue Dec 07 18:26:38 2010 +0000 +++ b/xen/arch/x86/hvm/vmx/vmx.c Tue Dec 07 18:27:40 2010 +0000 @@ -2194,30 +2194,6 @@ static int vmx_handle_eoi_write(void) return 0; } -static int vmx_handle_xsetbv(u64 new_bv) -{ - struct vcpu *v = current; - struct segment_register sreg; - - hvm_get_segment_register(v, x86_seg_ss, &sreg); - if ( sreg.attr.fields.dpl != 0 ) - goto err; - - if ( ((new_bv ^ xfeature_mask) & ~xfeature_mask) || !(new_bv & 1) ) - goto err; - - if ( (xfeature_mask & XSTATE_YMM & new_bv) && !(new_bv & XSTATE_SSE) ) - goto err; - - v->arch.xcr0 = new_bv; - v->arch.xcr0_accum |= new_bv; - set_xcr0(new_bv); - return 0; -err: - vmx_inject_hw_exception(TRAP_gp_fault, 0); - return -1; -} - asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs) { unsigned int exit_reason, idtv_info, intr_info = 0, vector = 0; @@ -2610,7 +2586,7 @@ asmlinkage void vmx_vmexit_handler(struc case EXIT_REASON_XSETBV: { u64 new_bv = (((u64)regs->edx) << 32) | regs->eax; - if ( vmx_handle_xsetbv(new_bv) == 0 ) + if ( hvm_handle_xsetbv(new_bv) == 0 ) update_guest_eip(); /* Safe: XSETBV */ break; } diff -r 98eb4a334b77 -r 066c924ed467 xen/include/asm-x86/hvm/support.h --- a/xen/include/asm-x86/hvm/support.h Tue Dec 07 18:26:38 2010 +0000 +++ b/xen/include/asm-x86/hvm/support.h Tue Dec 07 18:27:40 2010 +0000 @@ -128,6 +128,8 @@ void hvm_triple_fault(void); void hvm_rdtsc_intercept(struct cpu_user_regs *regs); +int hvm_handle_xsetbv(u64 new_bv); + /* These functions all return X86EMUL return codes. */ int hvm_set_efer(uint64_t value); int hvm_set_cr0(unsigned long value); diff -r 98eb4a334b77 -r 066c924ed467 xen/include/asm-x86/hvm/svm/emulate.h --- a/xen/include/asm-x86/hvm/svm/emulate.h Tue Dec 07 18:26:38 2010 +0000 +++ b/xen/include/asm-x86/hvm/svm/emulate.h Tue Dec 07 18:27:40 2010 +0000 @@ -32,6 +32,7 @@ enum instruction_index { INSTR_INT3, INSTR_RDTSC, INSTR_PAUSE, + INSTR_XSETBV, INSTR_MAX_COUNT /* Must be last - Number of instructions supported */ }; diff -r 98eb4a334b77 -r 066c924ed467 xen/include/asm-x86/hvm/svm/vmcb.h --- a/xen/include/asm-x86/hvm/svm/vmcb.h Tue Dec 07 18:26:38 2010 +0000 +++ b/xen/include/asm-x86/hvm/svm/vmcb.h Tue Dec 07 18:27:40 2010 +0000 @@ -299,6 +299,7 @@ enum VMEXIT_EXITCODE VMEXIT_MONITOR = 138, /* 0x8a */ VMEXIT_MWAIT = 139, /* 0x8b */ VMEXIT_MWAIT_CONDITIONAL= 140, /* 0x8c */ + VMEXIT_XSETBV = 141, /* 0x8d */ VMEXIT_NPF = 1024, /* 0x400, nested paging fault */ VMEXIT_INVALID = -1 }; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |