[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] X86: implement PCID/INVPCID for hvm



# HG changeset patch
# User Liu, Jinsong <jinsong.liu@xxxxxxxxx>
# Date 1322738646 -3600
# Node ID 20c1c0ff9677999a096ab8525e661738d6653484
# Parent  d9cb04ed55398ea4043c85573460afaf023aa1e9
X86: implement PCID/INVPCID for hvm

This patch handle PCID/INVPCID for hvm:

For hap hvm, we enable PCID/INVPCID, since no need to intercept
INVPCID, and we just set INVPCID non-root behavior as running natively;

For shadow hvm, we disable PCID/INVPCID, otherwise we need to emulate
INVPCID at vmm by setting INVPCID non-root behavior as vmexit.

Signed-off-by: Liu, Jinsong <jinsong.liu@xxxxxxxxx>
Committed-by: Jan Beulich <jbeulich@xxxxxxxx>
---


diff -r d9cb04ed5539 -r 20c1c0ff9677 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Thu Dec 01 12:22:43 2011 +0100
+++ b/xen/arch/x86/hvm/hvm.c    Thu Dec 01 12:24:06 2011 +0100
@@ -1582,6 +1582,13 @@
     }
     else if ( !(value & X86_CR0_PG) && (old_value & X86_CR0_PG) )
     {
+        if ( hvm_pcid_enabled(v) )
+        {
+            HVM_DBG_LOG(DBG_LEVEL_1, "Guest attempts to clear CR0.PG "
+                        "while CR4.PCIDE=1");
+            goto gpf;
+        }
+
         /* When CR0.PG is cleared, LMA is cleared immediately. */
         if ( hvm_long_mode_enabled(v) )
         {
@@ -1700,12 +1707,27 @@
     }
 
     old_cr = v->arch.hvm_vcpu.guest_cr[4];
+
+    if ( (value & X86_CR4_PCIDE) && !(old_cr & X86_CR4_PCIDE) &&
+         (!hvm_long_mode_enabled(v) ||
+          (v->arch.hvm_vcpu.guest_cr[3] & 0xfff)) )
+    {
+        HVM_DBG_LOG(DBG_LEVEL_1, "Guest attempts to change CR4.PCIDE from "
+                    "0 to 1 while either EFER.LMA=0 or CR3[11:0]!=000H");
+        goto gpf;
+    }
+
     v->arch.hvm_vcpu.guest_cr[4] = value;
     hvm_update_guest_cr(v, 4);
 
-    /* Modifying CR4.{PSE,PAE,PGE,SMEP} invalidates all TLB entries. */
-    if ( (old_cr ^ value) & (X86_CR4_PSE | X86_CR4_PGE |
-                             X86_CR4_PAE | X86_CR4_SMEP) ) {
+    /*
+     * Modifying CR4.{PSE,PAE,PGE,SMEP}, or clearing CR4.PCIDE
+     * invalidate all TLB entries.
+     */
+    if ( ((old_cr ^ value) &
+          (X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE | X86_CR4_SMEP)) ||
+         (!(value & X86_CR4_PCIDE) && (old_cr & X86_CR4_PCIDE)) )
+    {
         if ( !nestedhvm_vmswitch_in_progress(v) && 
nestedhvm_vcpu_in_guestmode(v) )
             paging_update_nestedmode(v);
         else
@@ -2465,6 +2487,10 @@
             *ecx |= (v->arch.hvm_vcpu.guest_cr[4] & X86_CR4_OSXSAVE) ?
                      cpufeat_mask(X86_FEATURE_OSXSAVE) : 0;
 
+        /* Don't expose PCID to non-hap hvm. */
+        if ( !hap_enabled(d) )
+            *ecx &= ~cpufeat_mask(X86_FEATURE_PCID);
+
         /* Only provide PSE36 when guest runs in 32bit PAE or in long mode */
         if ( !(hvm_pae_enabled(v) || hvm_long_mode_enabled(v)) )
             *edx &= ~cpufeat_mask(X86_FEATURE_PSE36);
@@ -2472,6 +2498,10 @@
     case 0x7:
         if ( (count == 0) && !cpu_has_smep )
             *ebx &= ~cpufeat_mask(X86_FEATURE_SMEP);
+
+        /* Don't expose INVPCID to non-hap hvm. */
+        if ( (count == 0) && !hap_enabled(d) )
+            *ebx &= ~cpufeat_mask(X86_FEATURE_INVPCID);
         break;
     case 0xb:
         /* Fix the x2APIC identifier. */
diff -r d9cb04ed5539 -r 20c1c0ff9677 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Thu Dec 01 12:22:43 2011 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Thu Dec 01 12:24:06 2011 +0100
@@ -184,7 +184,8 @@
                SECONDARY_EXEC_WBINVD_EXITING |
                SECONDARY_EXEC_ENABLE_EPT |
                SECONDARY_EXEC_ENABLE_RDTSCP |
-               SECONDARY_EXEC_PAUSE_LOOP_EXITING);
+               SECONDARY_EXEC_PAUSE_LOOP_EXITING |
+               SECONDARY_EXEC_ENABLE_INVPCID);
         if ( opt_vpid_enabled )
             opt |= SECONDARY_EXEC_ENABLE_VPID;
         if ( opt_unrestricted_guest_enabled )
@@ -732,7 +733,8 @@
     {
         v->arch.hvm_vmx.secondary_exec_control &= 
             ~(SECONDARY_EXEC_ENABLE_EPT | 
-              SECONDARY_EXEC_UNRESTRICTED_GUEST);
+              SECONDARY_EXEC_UNRESTRICTED_GUEST |
+              SECONDARY_EXEC_ENABLE_INVPCID);
         vmexit_ctl &= ~(VM_EXIT_SAVE_GUEST_PAT |
                         VM_EXIT_LOAD_HOST_PAT);
         vmentry_ctl &= ~VM_ENTRY_LOAD_GUEST_PAT;
diff -r d9cb04ed5539 -r 20c1c0ff9677 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Thu Dec 01 12:22:43 2011 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Thu Dec 01 12:24:06 2011 +0100
@@ -1007,7 +1007,7 @@
     if ( !hvm_pae_enabled(v) || (v->arch.hvm_vcpu.guest_efer & EFER_LMA) )
         return;
 
-    if ( cr3 & 0x1fUL )
+    if ( (cr3 & 0x1fUL) && !hvm_pcid_enabled(v) )
         goto crash;
 
     mfn = mfn_x(get_gfn(v->domain, cr3 >> PAGE_SHIFT, &p2mt));
@@ -2704,6 +2704,7 @@
     case EXIT_REASON_ACCESS_GDTR_OR_IDTR:
     case EXIT_REASON_ACCESS_LDTR_OR_TR:
     case EXIT_REASON_VMX_PREEMPTION_TIMER_EXPIRED:
+    case EXIT_REASON_INVPCID:
     /* fall through */
     default:
     exit_and_crash:
diff -r d9cb04ed5539 -r 20c1c0ff9677 xen/include/asm-x86/cpufeature.h
--- a/xen/include/asm-x86/cpufeature.h  Thu Dec 01 12:22:43 2011 +0100
+++ b/xen/include/asm-x86/cpufeature.h  Thu Dec 01 12:24:06 2011 +0100
@@ -224,6 +224,8 @@
 
 #define cpu_has_x2apic          boot_cpu_has(X86_FEATURE_X2APIC)
 
+#define cpu_has_pcid            boot_cpu_has(X86_FEATURE_PCID)
+
 #define cpu_has_xsave           boot_cpu_has(X86_FEATURE_XSAVE)
 #define cpu_has_avx             boot_cpu_has(X86_FEATURE_AVX)
 #define cpu_has_lwp             boot_cpu_has(X86_FEATURE_LWP)
diff -r d9cb04ed5539 -r 20c1c0ff9677 xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Thu Dec 01 12:22:43 2011 +0100
+++ b/xen/include/asm-x86/hvm/hvm.h     Thu Dec 01 12:24:06 2011 +0100
@@ -212,6 +212,8 @@
     (!!((v)->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PG))
 #define hvm_wp_enabled(v) \
     (!!((v)->arch.hvm_vcpu.guest_cr[0] & X86_CR0_WP))
+#define hvm_pcid_enabled(v) \
+    (!!((v)->arch.hvm_vcpu.guest_cr[4] & X86_CR4_PCIDE))
 #define hvm_pae_enabled(v) \
     (hvm_paging_enabled(v) && ((v)->arch.hvm_vcpu.guest_cr[4] & X86_CR4_PAE))
 #define hvm_smep_enabled(v) \
@@ -334,6 +336,7 @@
         (cpu_has_fsgsbase ? X86_CR4_FSGSBASE : 0) |     \
         ((nestedhvm_enabled((_v)->domain) && cpu_has_vmx)\
                       ? X86_CR4_VMXE : 0)  |             \
+        (cpu_has_pcid ? X86_CR4_PCIDE : 0) |             \
         (xsave_enabled(_v) ? X86_CR4_OSXSAVE : 0))))
 
 /* These exceptions must always be intercepted. */
diff -r d9cb04ed5539 -r 20c1c0ff9677 xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Thu Dec 01 12:22:43 2011 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Thu Dec 01 12:24:06 2011 +0100
@@ -184,6 +184,7 @@
 #define SECONDARY_EXEC_WBINVD_EXITING           0x00000040
 #define SECONDARY_EXEC_UNRESTRICTED_GUEST       0x00000080
 #define SECONDARY_EXEC_PAUSE_LOOP_EXITING       0x00000400
+#define SECONDARY_EXEC_ENABLE_INVPCID           0x00001000
 extern u32 vmx_secondary_exec_control;
 
 extern bool_t cpu_has_vmx_ins_outs_instr_info;
diff -r d9cb04ed5539 -r 20c1c0ff9677 xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Thu Dec 01 12:22:43 2011 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Thu Dec 01 12:24:06 2011 +0100
@@ -129,6 +129,7 @@
 #define EXIT_REASON_INVVPID             53
 #define EXIT_REASON_WBINVD              54
 #define EXIT_REASON_XSETBV              55
+#define EXIT_REASON_INVPCID             58
 
 /*
  * Interruption-information format
diff -r d9cb04ed5539 -r 20c1c0ff9677 xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h   Thu Dec 01 12:22:43 2011 +0100
+++ b/xen/include/asm-x86/processor.h   Thu Dec 01 12:24:06 2011 +0100
@@ -84,6 +84,7 @@
 #define X86_CR4_VMXE           0x2000  /* enable VMX */
 #define X86_CR4_SMXE           0x4000  /* enable SMX */
 #define X86_CR4_FSGSBASE       0x10000 /* enable {rd,wr}{fs,gs}base */
+#define X86_CR4_PCIDE          0x20000 /* enable PCID */
 #define X86_CR4_OSXSAVE        0x40000 /* enable XSAVE/XRSTOR */
 #define X86_CR4_SMEP           0x100000/* enable SMEP */
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.