Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 4555

kernel-2.6.18-194.11.1.el5.src.rpm

From: ddugger@redhat.com <ddugger@redhat.com>
Date: Tue, 21 Apr 2009 13:01:24 -0600
Subject: [xen] utilise the GUEST_PAT and HOST_PAT vmcs area
Message-id: 200904211901.n3LJ1OM0028384@sobek.n0ano.com
O-Subject: [RHEL5.4 PATCH 2/6 V2] BZ496873: Utilise the GUEST_PAT and HOST_PAT vmcs area for EPT and VT-d enabled both.
Bugzilla: 496873
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
RH-Acked-by: Chris Lalancette <clalance@redhat.com>
RH-Acked-by: Rik van Riel <riel@redhat.com>
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
RH-Acked-by: Justin M. Forbes <jforbes@redhat.com>

The trunk includes "disable_intercept_for_msr(MSR_IA32_CR_PAT)"
is different from xen-unstable, since the whole
disable_intercept_for_msr() is substitute with
vmx_disable_intercept_from_msr() and related much to the msr_bitmap.
And at start_vmx() time, the paging mode may not be intialised yet,
so we use vmx_function_table.hap_supported to indicate if the EPT
mode is enabled or not.

Upstream Status: Accepted (CS 19072)

Signed-off-by: Xiaohui Xin <xiaohui.xin@intel.com>
Signed-off-by: Gerd Hoffman <kraxel@redhat.com>
Signed-off-by: Don Dugger <donald.d.dugger@intel.com>

Yet Another Resend - resolve the conflicting BZs between the Subject line
(correct) and the message body (incorrect).

diff --git a/arch/x86/hvm/vmx/vmcs.c b/arch/x86/hvm/vmx/vmcs.c
index 8a119d4..015e2be 100644
--- a/arch/x86/hvm/vmx/vmcs.c
+++ b/arch/x86/hvm/vmx/vmcs.c
@@ -140,14 +140,15 @@ void vmx_init_vmcs_config(void)
     }
 
     min = VM_EXIT_ACK_INTR_ON_EXIT;
-    opt = 0;
+    opt = VM_EXIT_SAVE_GUEST_PAT | VM_EXIT_LOAD_HOST_PAT;
 #ifdef __x86_64__
     min |= VM_EXIT_IA32E_MODE;
 #endif
     _vmx_vmexit_control = adjust_vmx_controls(
         min, opt, MSR_IA32_VMX_EXIT_CTLS_MSR);
 
-    min = opt = 0;
+    min = 0;
+    opt = VM_ENTRY_LOAD_GUEST_PAT;
     _vmx_vmentry_control = adjust_vmx_controls(
         min, opt, MSR_IA32_VMX_ENTRY_CTLS_MSR);
 
@@ -362,8 +363,6 @@ static void construct_vmcs(struct vcpu *v)
 
     /* VMCS controls. */
     __vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_control);
-    __vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control);
-    __vmwrite(VM_ENTRY_CONTROLS, vmx_vmentry_control);
 
     v->arch.hvm_vmx.exec_control = vmx_cpu_based_exec_control;
     v->arch.hvm_vmx.secondary_exec_control = vmx_secondary_exec_control;
@@ -377,9 +376,15 @@ static void construct_vmcs(struct vcpu *v)
     else
     {
         v->arch.hvm_vmx.secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_EPT;
+        vmx_vmexit_control &= ~(VM_EXIT_SAVE_GUEST_PAT |
+                                VM_EXIT_LOAD_HOST_PAT);
+        vmx_vmentry_control &= ~VM_ENTRY_LOAD_GUEST_PAT;
     }
 
     __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vmx.exec_control);
+    __vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control);
+    __vmwrite(VM_ENTRY_CONTROLS, vmx_vmentry_control);
+
     if ( cpu_has_vmx_secondary_exec_control )
         __vmwrite(SECONDARY_VM_EXEC_CONTROL,
           v->arch.hvm_vmx.secondary_exec_control);
@@ -568,6 +573,21 @@ static void construct_vmcs(struct vcpu *v)
     __vmwrite(GUEST_TR_BASE, 0);
     __vmwrite(GUEST_TR_LIMIT, 0xff);
 
+    if ( cpu_has_vmx_pat && paging_mode_hap(d) )
+    {
+        u64 host_pat, guest_pat;
+
+        rdmsrl(MSR_IA32_CR_PAT, host_pat);
+        guest_pat = 0x7040600070406ULL;
+
+        __vmwrite(HOST_PAT, host_pat);
+        __vmwrite(GUEST_PAT, guest_pat);
+#ifdef __i386__
+        __vmwrite(HOST_PAT_HIGH, host_pat >> 32);
+        __vmwrite(GUEST_PAT_HIGH, guest_pat >> 32);
+#endif
+    }
+
     vmx_vmcs_exit(v);
 
     paging_update_paging_modes(v); /* will update HOST & GUEST_CR3 as reqd */
@@ -714,6 +734,10 @@ void vmcs_dump_vcpu(void)
     print_section("Natural 64-bit Host-State Fields", 0x6c00, 0x6c16, 2);
     printk("secondary exec control = 0x%08x\n",
       (uint32_t)__vmread(SECONDARY_VM_EXEC_CONTROL));
+    printk("Guest PAT = 0x%08x%08x\n",
+           (uint32_t)__vmread(GUEST_PAT_HIGH), (uint32_t)__vmread(GUEST_PAT));
+    printk("Host PAT = 0x%08x%08x\n",
+           (uint32_t)__vmread(HOST_PAT_HIGH), (uint32_t)__vmread(HOST_PAT));
     printk("EPT pointer = 0x%08x%08x\n",
       (uint32_t)__vmread(EPT_POINTER_HIGH), (uint32_t)__vmread(EPT_POINTER));
     printk("virtual processor ID = 0x%04x\n",
diff --git a/arch/x86/hvm/vmx/vmx.c b/arch/x86/hvm/vmx/vmx.c
index 51ec1f8..13a4462 100644
--- a/arch/x86/hvm/vmx/vmx.c
+++ b/arch/x86/hvm/vmx/vmx.c
@@ -1471,6 +1471,9 @@ int start_vmx(void)
         disable_intercept_for_msr(MSR_IA32_SYSENTER_CS);
         disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP);
         disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP);
+        if ( cpu_has_vmx_pat && 
+                    vmx_function_table.hap_supported )
+            disable_intercept_for_msr(MSR_IA32_CR_PAT);
     }
 
     return 1;
diff --git a/include/asm-x86/hvm/vmx/vmcs.h b/include/asm-x86/hvm/vmx/vmcs.h
index ade7a5a..029c7a9 100644
--- a/include/asm-x86/hvm/vmx/vmcs.h
+++ b/include/asm-x86/hvm/vmx/vmcs.h
@@ -139,11 +139,14 @@ extern u32 vmx_pin_based_exec_control;
 
 #define VM_EXIT_IA32E_MODE              0x00000200
 #define VM_EXIT_ACK_INTR_ON_EXIT        0x00008000
+#define VM_EXIT_SAVE_GUEST_PAT          0x00040000
+#define VM_EXIT_LOAD_HOST_PAT           0x00080000
 extern u32 vmx_vmexit_control;
 
 #define VM_ENTRY_IA32E_MODE             0x00000200
 #define VM_ENTRY_SMM                    0x00000400
 #define VM_ENTRY_DEACT_DUAL_MONITOR     0x00000800
+#define VM_ENTRY_LOAD_GUEST_PAT         0x00004000
 extern u32 vmx_vmentry_control;
 
 #define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001
@@ -165,7 +168,8 @@ extern u32 vmx_secondary_exec_control;
     (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS)
 #define cpu_has_vmx_ept \
     (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT)
-
+#define cpu_has_vmx_pat \
+    (vmx_vmentry_control & VM_ENTRY_LOAD_GUEST_PAT)
 #define cpu_has_vmx_vpid \
     (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VPID)
 
@@ -221,6 +225,8 @@ enum vmcs_field {
     VMCS_LINK_POINTER_HIGH          = 0x00002801,
     GUEST_IA32_DEBUGCTL             = 0x00002802,
     GUEST_IA32_DEBUGCTL_HIGH        = 0x00002803,
+    GUEST_PAT                       = 0x00002804,
+    GUEST_PAT_HIGH                  = 0x00002805,
     GUEST_PDPTR0                    = 0x0000280a,
     GUEST_PDPTR0_HIGH               = 0x0000280b,
     GUEST_PDPTR1                    = 0x0000280c,
@@ -229,6 +235,8 @@ enum vmcs_field {
     GUEST_PDPTR2_HIGH               = 0x0000280f,
     GUEST_PDPTR3                    = 0x00002810,
     GUEST_PDPTR3_HIGH               = 0x00002811,
+    HOST_PAT                        = 0x00002c00,
+    HOST_PAT_HIGH                   = 0x00002c01,
     PIN_BASED_VM_EXEC_CONTROL       = 0x00004000,
     CPU_BASED_VM_EXEC_CONTROL       = 0x00004002,
     EXCEPTION_BITMAP                = 0x00004004,