[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86, hvm: Better handling of INVD/WBINVD on VMX and SVM.
# HG changeset patch # User Keir Fraser <keir@xxxxxxxxxxxxx> # Date 1194609927 0 # Node ID fc8be8f3707bd1ffeab55efea5f9804fa570177e # Parent 1dcb24e6c4e42ecdb7f1944a431e68c4509757eb x86, hvm: Better handling of INVD/WBINVD on VMX and SVM. Also better handling of MONITOR/MWAIT on VMX. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/hvm/svm/emulate.c | 2 + xen/arch/x86/hvm/svm/svm.c | 35 +++++++++++++++++----------------- xen/arch/x86/hvm/svm/vmcb.c | 3 +- xen/arch/x86/hvm/vmx/vmcs.c | 1 xen/arch/x86/hvm/vmx/vmx.c | 14 +++++++++---- xen/include/asm-x86/hvm/svm/emulate.h | 1 xen/include/asm-x86/hvm/svm/vmcb.h | 10 ++++++++- xen/include/asm-x86/perfc_defn.h | 4 +-- 8 files changed, 45 insertions(+), 25 deletions(-) diff -r 1dcb24e6c4e4 -r fc8be8f3707b xen/arch/x86/hvm/svm/emulate.c --- a/xen/arch/x86/hvm/svm/emulate.c Thu Nov 08 18:15:36 2007 +0000 +++ b/xen/arch/x86/hvm/svm/emulate.c Fri Nov 09 12:05:27 2007 +0000 @@ -344,6 +344,7 @@ unsigned long svm_rip2pointer(struct vcp * Special case: Last byte, if zero, doesn't need to match. */ MAKE_INSTR(INVD, 2, 0x0f, 0x08); +MAKE_INSTR(WBINVD, 2, 0x0f, 0x09); MAKE_INSTR(CPUID, 2, 0x0f, 0xa2); MAKE_INSTR(RDMSR, 2, 0x0f, 0x32); MAKE_INSTR(WRMSR, 2, 0x0f, 0x30); @@ -378,6 +379,7 @@ static const u8 *opc_bytes[INSTR_MAX_COU static const u8 *opc_bytes[INSTR_MAX_COUNT] = { [INSTR_INVD] = OPCODE_INVD, + [INSTR_WBINVD] = OPCODE_WBINVD, [INSTR_CPUID] = OPCODE_CPUID, [INSTR_RDMSR] = OPCODE_RDMSR, [INSTR_WRMSR] = OPCODE_WRMSR, diff -r 1dcb24e6c4e4 -r fc8be8f3707b xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Thu Nov 08 18:15:36 2007 +0000 +++ b/xen/arch/x86/hvm/svm/svm.c Fri Nov 09 12:05:27 2007 +0000 @@ -1942,24 +1942,24 @@ static void svm_vmexit_do_hlt(struct vmc hvm_hlt(regs->eflags); } -static void svm_vmexit_do_invd(struct cpu_user_regs *regs) -{ +static void svm_vmexit_do_invalidate_cache(struct cpu_user_regs *regs) +{ + enum instruction_index list[] = { INSTR_INVD, INSTR_WBINVD }; + struct vcpu *curr = current; + struct vmcb_struct *vmcb = curr->arch.hvm_svm.vmcb; int inst_len; - - /* Invalidate the cache - we can't really do that safely - maybe we should - * WBINVD, but I think it's just fine to completely ignore it - we should - * have cache-snooping that solves it anyways. -- Mats P. - */ - - /* Tell the user that we did this - just in case someone runs some really - * weird operating system and wants to know why it's not working... - */ - gdprintk(XENLOG_WARNING, "INVD instruction intercepted - ignored\n"); - - inst_len = __get_instruction_length(current, INSTR_INVD, NULL); + + if ( !list_empty(&(domain_hvm_iommu(curr->domain)->pdev_list)) ) + { + vmcb->general2_intercepts &= ~GENERAL2_INTERCEPT_WBINVD; + wbinvd(); + } + + inst_len = __get_instruction_length_from_list( + curr, list, ARRAY_SIZE(list), NULL, NULL); __update_guest_eip(regs, inst_len); -} - +} + void svm_handle_invlpg(const short invlpga, struct cpu_user_regs *regs) { struct vcpu *v = current; @@ -2205,7 +2205,8 @@ asmlinkage void svm_vmexit_handler(struc break; case VMEXIT_INVD: - svm_vmexit_do_invd(regs); + case VMEXIT_WBINVD: + svm_vmexit_do_invalidate_cache(regs); break; case VMEXIT_TASK_SWITCH: { diff -r 1dcb24e6c4e4 -r fc8be8f3707b xen/arch/x86/hvm/svm/vmcb.c --- a/xen/arch/x86/hvm/svm/vmcb.c Thu Nov 08 18:15:36 2007 +0000 +++ b/xen/arch/x86/hvm/svm/vmcb.c Fri Nov 09 12:05:27 2007 +0000 @@ -127,7 +127,8 @@ static int construct_vmcb(struct vcpu *v GENERAL2_INTERCEPT_VMRUN | GENERAL2_INTERCEPT_VMMCALL | GENERAL2_INTERCEPT_VMLOAD | GENERAL2_INTERCEPT_VMSAVE | GENERAL2_INTERCEPT_STGI | GENERAL2_INTERCEPT_CLGI | - GENERAL2_INTERCEPT_SKINIT | GENERAL2_INTERCEPT_RDTSCP; + GENERAL2_INTERCEPT_SKINIT | GENERAL2_INTERCEPT_RDTSCP | + GENERAL2_INTERCEPT_WBINVD; /* Intercept all debug-register writes. */ vmcb->dr_intercepts = ~0u; diff -r 1dcb24e6c4e4 -r fc8be8f3707b xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Thu Nov 08 18:15:36 2007 +0000 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Fri Nov 09 12:05:27 2007 +0000 @@ -84,6 +84,7 @@ static void vmx_init_vmcs_config(void) min = (CPU_BASED_HLT_EXITING | CPU_BASED_INVLPG_EXITING | + CPU_BASED_MONITOR_EXITING | CPU_BASED_MWAIT_EXITING | CPU_BASED_MOV_DR_EXITING | CPU_BASED_ACTIVATE_IO_BITMAP | diff -r 1dcb24e6c4e4 -r fc8be8f3707b xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Thu Nov 08 18:15:36 2007 +0000 +++ b/xen/arch/x86/hvm/vmx/vmx.c Fri Nov 09 12:05:27 2007 +0000 @@ -2881,10 +2881,9 @@ asmlinkage void vmx_vmexit_handler(struc if ( vmx_do_msr_write(regs) ) __update_guest_eip(inst_len); break; + case EXIT_REASON_MWAIT_INSTRUCTION: case EXIT_REASON_MONITOR_INSTRUCTION: - case EXIT_REASON_PAUSE_INSTRUCTION: - goto exit_and_crash; case EXIT_REASON_VMCLEAR: case EXIT_REASON_VMLAUNCH: case EXIT_REASON_VMPTRLD: @@ -2894,8 +2893,6 @@ asmlinkage void vmx_vmexit_handler(struc case EXIT_REASON_VMWRITE: case EXIT_REASON_VMXOFF: case EXIT_REASON_VMXON: - /* Report invalid opcode exception when a VMX guest tries to execute - any of the VMX instructions */ vmx_inject_hw_exception(v, TRAP_invalid_op, VMX_DELIVER_NO_ERROR_CODE); break; @@ -2908,6 +2905,15 @@ asmlinkage void vmx_vmexit_handler(struc exit_qualification = __vmread(EXIT_QUALIFICATION); offset = exit_qualification & 0x0fffUL; handle_mmio(APIC_DEFAULT_PHYS_BASE | offset); + break; + } + + case EXIT_REASON_INVD: + { + inst_len = __get_instruction_length(); /* Safe: INVD */ + __update_guest_eip(inst_len); + if ( !list_empty(&(domain_hvm_iommu(v->domain)->pdev_list)) ) + wbinvd(); break; } diff -r 1dcb24e6c4e4 -r fc8be8f3707b xen/include/asm-x86/hvm/svm/emulate.h --- a/xen/include/asm-x86/hvm/svm/emulate.h Thu Nov 08 18:15:36 2007 +0000 +++ b/xen/include/asm-x86/hvm/svm/emulate.h Fri Nov 09 12:05:27 2007 +0000 @@ -43,6 +43,7 @@ typedef enum OPERATING_MODE_ { /* Enumerate some standard instructions that we support */ enum instruction_index { INSTR_INVD, + INSTR_WBINVD, INSTR_CPUID, INSTR_RDMSR, INSTR_WRMSR, diff -r 1dcb24e6c4e4 -r fc8be8f3707b xen/include/asm-x86/hvm/svm/vmcb.h --- a/xen/include/asm-x86/hvm/svm/vmcb.h Thu Nov 08 18:15:36 2007 +0000 +++ b/xen/include/asm-x86/hvm/svm/vmcb.h Fri Nov 09 12:05:27 2007 +0000 @@ -72,7 +72,11 @@ enum GenericIntercept2bits GENERAL2_INTERCEPT_CLGI = 1 << 5, GENERAL2_INTERCEPT_SKINIT = 1 << 6, GENERAL2_INTERCEPT_RDTSCP = 1 << 7, - GENERAL2_INTERCEPT_ICEBP = 1 << 8 + GENERAL2_INTERCEPT_ICEBP = 1 << 8, + GENERAL2_INTERCEPT_WBINVD = 1 << 9, + GENERAL2_INTERCEPT_MONITOR = 1 << 10, + GENERAL2_INTERCEPT_MWAIT = 1 << 11, + GENERAL2_INTERCEPT_MWAIT_CONDITIONAL = 1 << 12 }; @@ -291,6 +295,10 @@ enum VMEXIT_EXITCODE VMEXIT_SKINIT = 134, VMEXIT_RDTSCP = 135, VMEXIT_ICEBP = 136, + VMEXIT_WBINVD = 137, + VMEXIT_MONITOR = 138, + VMEXIT_MWAIT = 139, + VMEXIT_MWAIT_CONDITIONAL= 140, VMEXIT_NPF = 1024, /* nested paging fault */ VMEXIT_INVALID = -1 }; diff -r 1dcb24e6c4e4 -r fc8be8f3707b xen/include/asm-x86/perfc_defn.h --- a/xen/include/asm-x86/perfc_defn.h Thu Nov 08 18:15:36 2007 +0000 +++ b/xen/include/asm-x86/perfc_defn.h Fri Nov 09 12:05:27 2007 +0000 @@ -9,8 +9,8 @@ PERFCOUNTER_ARRAY(vmexits, PERFCOUNTER_ARRAY(vmexits, "vmexits", VMX_PERF_EXIT_REASON_SIZE) PERFCOUNTER_ARRAY(cause_vector, "cause vector", VMX_PERF_VECTOR_SIZE) -#define VMEXIT_NPF_PERFC 137 -#define SVM_PERF_EXIT_REASON_SIZE (1+137) +#define VMEXIT_NPF_PERFC 141 +#define SVM_PERF_EXIT_REASON_SIZE (1+141) PERFCOUNTER_ARRAY(svmexits, "SVMexits", SVM_PERF_EXIT_REASON_SIZE) PERFCOUNTER(seg_fixups, "segmentation fixups") _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |