[PATCH] KVM: VMX: Add PAT support for EPT

Sheng Yang
2008-09-08T11:39:13Z

Signed-off-by: Sheng Yang <sheng.yang@intel.com>
---
arch/x86/kvm/vmx.c | 15 ++++++++++++---
arch/x86/kvm/vmx.h | 7 +++++++
2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 7f53fb7..b74b43f 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1173,12 +1173,13 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
#ifdef CONFIG_X86_64
min |= VM_EXIT_HOST_ADDR_SPACE_SIZE;
#endif
- opt = 0;
+ opt = VM_EXIT_LOAD_GUEST_PAT;
if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_EXIT_CTLS,
&_vmexit_control) < 0)
return -EIO;

- min = opt = 0;
+ min = 0;
+ opt = VM_ENTRY_SAVE_GUEST_PAT | VM_ENTRY_LOAD_HOST_PAT;
if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_ENTRY_CTLS,
&_vmentry_control) < 0)
return -EIO;
@@ -2107,8 +2108,9 @@ static int setup_msr_bitmap(struct page *msr_bitmap)
*/
static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
{
- u32 host_sysenter_cs;
+ u32 host_sysenter_cs, msr_low, msr_high;
u32 junk;
+ u64 host_pat;
unsigned long a;
struct descriptor_table dt;
int i;
@@ -2196,6 +2198,13 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
vmcs_writel(HOST_IA32_SYSENTER_ESP, a); /* 22.2.3 */
rdmsrl(MSR_IA32_SYSENTER_EIP, a);
vmcs_writel(HOST_IA32_SYSENTER_EIP, a); /* 22.2.3 */
+ if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_HOST_PAT) {
+ rdmsr(MSR_IA32_CR_PAT, msr_low, msr_high);
+ host_pat = msr_low | ((u64) msr_high << 32);
+ vmcs_write64(HOST_PAT, host_pat);
+ vmx_disable_intercept_for_msr(vmx->msr_bitmap,
+ MSR_IA32_CR_PAT);
+ }

for (i = 0; i < NR_VMX_MSR; ++i) {
u32 index = vmx_msr_index[i];
diff --git a/arch/x86/kvm/vmx.h b/arch/x86/kvm/vmx.h
index 0c22e5f..16b3cfb 100644
--- a/arch/x86/kvm/vmx.h
+++ b/arch/x86/kvm/vmx.h
@@ -62,11 +62,14 @@
#define PIN_BASED_VIRTUAL_NMIS 0x00000020

#define VM_EXIT_HOST_ADDR_SPACE_SIZE 0x00000200
+#define VM_EXIT_LOAD_GUEST_PAT 0x00004000
#define VM_EXIT_ACK_INTR_ON_EXIT 0x00008000

#define VM_ENTRY_IA32E_MODE 0x00000200
#define VM_ENTRY_SMM 0x00000400
#define VM_ENTRY_DEACT_DUAL_MONITOR 0x00000800
+#define VM_ENTRY_SAVE_GUEST_PAT 0x00040000
+#define VM_ENTRY_LOAD_HOST_PAT 0x00080000

/* VMCS Encodings */
enum vmcs_field {
@@ -112,6 +115,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,
@@ -120,6 +125,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,
--
1.5.4.5