WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] x86, hvm: Better handling of INVD/WBINVD

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86, hvm: Better handling of INVD/WBINVD on VMX and SVM.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 09 Nov 2007 04:21:25 -0800
Delivery-date: Fri, 09 Nov 2007 05:46:36 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86, hvm: Better handling of INVD/WBINVD on VMX and SVM., Xen patchbot-unstable <=