149 lines
5.7 KiB
Diff
149 lines
5.7 KiB
Diff
# HG changeset patch
|
|
# User Keir Fraser <keir.fraser@citrix.com>
|
|
# Date 1232623303 0
|
|
# Node ID d52921c18c3d0171bccb4651cca8412f2fff2dd9
|
|
# Parent 9f9ba1a7cc924fbc547e05ea21071becafe5e2c2
|
|
vmx: utilise the GUEST_PAT and HOST_PAT vmcs area
|
|
|
|
Signed-off-by: Xin Li <Xin.Li@intel.com>
|
|
Signed-off-by: Xiaohui Xin <xiaohui.xin@intel.com>
|
|
|
|
--- a/xen/arch/x86/hvm/vmx/vmcs.c
|
|
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
|
|
@@ -166,14 +166,15 @@ static void vmx_init_vmcs_config(void)
|
|
#endif
|
|
|
|
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);
|
|
|
|
- min = opt = 0;
|
|
+ min = 0;
|
|
+ opt = VM_ENTRY_LOAD_GUEST_PAT;
|
|
_vmx_vmentry_control = adjust_vmx_controls(
|
|
min, opt, MSR_IA32_VMX_ENTRY_CTLS);
|
|
|
|
@@ -518,8 +519,6 @@ static int 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;
|
|
@@ -533,9 +532,15 @@ static int 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);
|
|
@@ -557,6 +562,8 @@ static int construct_vmcs(struct vcpu *v
|
|
vmx_disable_intercept_for_msr(v, MSR_IA32_SYSENTER_CS);
|
|
vmx_disable_intercept_for_msr(v, MSR_IA32_SYSENTER_ESP);
|
|
vmx_disable_intercept_for_msr(v, MSR_IA32_SYSENTER_EIP);
|
|
+ if ( cpu_has_vmx_pat && paging_mode_hap(d) )
|
|
+ vmx_disable_intercept_for_msr(v, MSR_IA32_CR_PAT);
|
|
}
|
|
|
|
/* I/O access bitmap. */
|
|
@@ -688,6 +695,21 @@ static int construct_vmcs(struct vcpu *v
|
|
__vmwrite(VIRTUAL_PROCESSOR_ID, v->arch.hvm_vmx.vpid);
|
|
}
|
|
|
|
+ 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 */
|
|
@@ -968,6 +990,8 @@ void vmcs_dump_vcpu(struct vcpu *v)
|
|
vmx_dump_sel("LDTR", x86_seg_ldtr);
|
|
vmx_dump_sel("IDTR", x86_seg_idtr);
|
|
vmx_dump_sel("TR", x86_seg_tr);
|
|
+ printk("Guest PAT = 0x%08x%08x\n",
|
|
+ (uint32_t)vmr(GUEST_PAT_HIGH), (uint32_t)vmr(GUEST_PAT));
|
|
x = (unsigned long long)vmr(TSC_OFFSET_HIGH) << 32;
|
|
x |= (uint32_t)vmr(TSC_OFFSET);
|
|
printk("TSC Offset = %016llx\n", x);
|
|
@@ -1006,6 +1030,8 @@ void vmcs_dump_vcpu(struct vcpu *v)
|
|
(unsigned long long)vmr(HOST_SYSENTER_ESP),
|
|
(int)vmr(HOST_SYSENTER_CS),
|
|
(unsigned long long)vmr(HOST_SYSENTER_EIP));
|
|
+ printk("Host PAT = 0x%08x%08x\n",
|
|
+ (uint32_t)vmr(HOST_PAT_HIGH), (uint32_t)vmr(HOST_PAT));
|
|
|
|
printk("*** Control State ***\n");
|
|
printk("PinBased=%08x CPUBased=%08x SecondaryExec=%08x\n",
|
|
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
|
|
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
|
|
@@ -150,11 +150,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
|
|
@@ -181,6 +184,8 @@ extern bool_t cpu_has_vmx_ins_outs_instr
|
|
(vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT)
|
|
#define cpu_has_vmx_vpid \
|
|
(vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VPID)
|
|
+#define cpu_has_vmx_pat \
|
|
+ (vmx_vmentry_control & VM_ENTRY_LOAD_GUEST_PAT)
|
|
|
|
/* GUEST_INTERRUPTIBILITY_INFO flags. */
|
|
#define VMX_INTR_SHADOW_STI 0x00000001
|
|
@@ -232,6 +237,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,
|
|
@@ -240,6 +247,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,
|