# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# 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@xxxxxxxxx>
Signed-off-by: Xiaohui Xin <xiaohui.xin@xxxxxxxxx>
---
xen/arch/x86/hvm/vmx/vmcs.c | 34 ++++++++++++++++++++++++++++++----
xen/include/asm-x86/hvm/vmx/vmcs.h | 9 +++++++++
2 files changed, 39 insertions(+), 4 deletions(-)
diff -r 9f9ba1a7cc92 -r d52921c18c3d xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c Thu Jan 22 11:17:48 2009 +0000
+++ b/xen/arch/x86/hvm/vmx/vmcs.c Thu Jan 22 11:21:43 2009 +0000
@@ -167,14 +167,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);
@@ -519,8 +520,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;
@@ -534,12 +533,18 @@ 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;
}
/* Do not enable Monitor Trap Flag unless start single step debug */
v->arch.hvm_vmx.exec_control &= ~CPU_BASED_MONITOR_TRAP_FLAG;
__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);
@@ -561,6 +566,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. */
@@ -690,6 +697,21 @@ static int construct_vmcs(struct vcpu *v
v->arch.hvm_vmx.vpid =
v->domain->arch.hvm_domain.vmx.vpid_base + v->vcpu_id;
__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);
@@ -989,6 +1011,8 @@ void vmcs_dump_vcpu(struct vcpu *v)
vmx_dump_sel("LDTR", GUEST_LDTR_SELECTOR);
vmx_dump_sel2("IDTR", GUEST_IDTR_LIMIT);
vmx_dump_sel("TR", GUEST_TR_SELECTOR);
+ 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);
@@ -1027,6 +1051,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",
diff -r 9f9ba1a7cc92 -r d52921c18c3d xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h Thu Jan 22 11:17:48 2009 +0000
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Thu Jan 22 11:21:43 2009 +0000
@@ -156,11 +156,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
@@ -189,6 +192,8 @@ extern bool_t cpu_has_vmx_ins_outs_instr
(vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VPID)
#define cpu_has_monitor_trap_flag \
(vmx_cpu_based_exec_control & CPU_BASED_MONITOR_TRAP_FLAG)
+#define cpu_has_vmx_pat \
+ (vmx_vmentry_control & VM_ENTRY_LOAD_GUEST_PAT)
/* GUEST_INTERRUPTIBILITY_INFO flags. */
#define VMX_INTR_SHADOW_STI 0x00000001
@@ -240,6 +245,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,
@@ -248,6 +255,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,
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|