ia64/xen-unstable

changeset 19073:d52921c18c3d

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>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jan 22 11:21:43 2009 +0000 (2009-01-22)
parents 9f9ba1a7cc92
children b10fd9f4fe38
files xen/arch/x86/hvm/vmx/vmcs.c xen/include/asm-x86/hvm/vmx/vmcs.h
line diff
     1.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Thu Jan 22 11:17:48 2009 +0000
     1.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Thu Jan 22 11:21:43 2009 +0000
     1.3 @@ -167,14 +167,15 @@ static void vmx_init_vmcs_config(void)
     1.4  #endif
     1.5  
     1.6      min = VM_EXIT_ACK_INTR_ON_EXIT;
     1.7 -    opt = 0;
     1.8 +    opt = VM_EXIT_SAVE_GUEST_PAT | VM_EXIT_LOAD_HOST_PAT;
     1.9  #ifdef __x86_64__
    1.10      min |= VM_EXIT_IA32E_MODE;
    1.11  #endif
    1.12      _vmx_vmexit_control = adjust_vmx_controls(
    1.13          min, opt, MSR_IA32_VMX_EXIT_CTLS);
    1.14  
    1.15 -    min = opt = 0;
    1.16 +    min = 0;
    1.17 +    opt = VM_ENTRY_LOAD_GUEST_PAT;
    1.18      _vmx_vmentry_control = adjust_vmx_controls(
    1.19          min, opt, MSR_IA32_VMX_ENTRY_CTLS);
    1.20  
    1.21 @@ -519,8 +520,6 @@ static int construct_vmcs(struct vcpu *v
    1.22  
    1.23      /* VMCS controls. */
    1.24      __vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_control);
    1.25 -    __vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control);
    1.26 -    __vmwrite(VM_ENTRY_CONTROLS, vmx_vmentry_control);
    1.27  
    1.28      v->arch.hvm_vmx.exec_control = vmx_cpu_based_exec_control;
    1.29      v->arch.hvm_vmx.secondary_exec_control = vmx_secondary_exec_control;
    1.30 @@ -534,12 +533,18 @@ static int construct_vmcs(struct vcpu *v
    1.31      else
    1.32      {
    1.33          v->arch.hvm_vmx.secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_EPT;
    1.34 +        vmx_vmexit_control &= ~(VM_EXIT_SAVE_GUEST_PAT |
    1.35 +                                VM_EXIT_LOAD_HOST_PAT);
    1.36 +        vmx_vmentry_control &= ~VM_ENTRY_LOAD_GUEST_PAT;
    1.37      }
    1.38  
    1.39      /* Do not enable Monitor Trap Flag unless start single step debug */
    1.40      v->arch.hvm_vmx.exec_control &= ~CPU_BASED_MONITOR_TRAP_FLAG;
    1.41  
    1.42      __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vmx.exec_control);
    1.43 +    __vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control);
    1.44 +    __vmwrite(VM_ENTRY_CONTROLS, vmx_vmentry_control);
    1.45 +
    1.46      if ( cpu_has_vmx_secondary_exec_control )
    1.47          __vmwrite(SECONDARY_VM_EXEC_CONTROL,
    1.48                    v->arch.hvm_vmx.secondary_exec_control);
    1.49 @@ -561,6 +566,8 @@ static int construct_vmcs(struct vcpu *v
    1.50          vmx_disable_intercept_for_msr(v, MSR_IA32_SYSENTER_CS);
    1.51          vmx_disable_intercept_for_msr(v, MSR_IA32_SYSENTER_ESP);
    1.52          vmx_disable_intercept_for_msr(v, MSR_IA32_SYSENTER_EIP);
    1.53 +        if ( cpu_has_vmx_pat && paging_mode_hap(d) )
    1.54 +            vmx_disable_intercept_for_msr(v, MSR_IA32_CR_PAT);
    1.55      }
    1.56  
    1.57      /* I/O access bitmap. */
    1.58 @@ -692,6 +699,21 @@ static int construct_vmcs(struct vcpu *v
    1.59          __vmwrite(VIRTUAL_PROCESSOR_ID, v->arch.hvm_vmx.vpid);
    1.60      }
    1.61  
    1.62 +    if ( cpu_has_vmx_pat && paging_mode_hap(d) )
    1.63 +    {
    1.64 +        u64 host_pat, guest_pat;
    1.65 +
    1.66 +        rdmsrl(MSR_IA32_CR_PAT, host_pat);
    1.67 +        guest_pat = 0x7040600070406ULL;
    1.68 +
    1.69 +        __vmwrite(HOST_PAT, host_pat);
    1.70 +        __vmwrite(GUEST_PAT, guest_pat);
    1.71 +#ifdef __i386__
    1.72 +        __vmwrite(HOST_PAT_HIGH, host_pat >> 32);
    1.73 +        __vmwrite(GUEST_PAT_HIGH, guest_pat >> 32);
    1.74 +#endif
    1.75 +    }
    1.76 +
    1.77      vmx_vmcs_exit(v);
    1.78  
    1.79      paging_update_paging_modes(v); /* will update HOST & GUEST_CR3 as reqd */
    1.80 @@ -989,6 +1011,8 @@ void vmcs_dump_vcpu(struct vcpu *v)
    1.81      vmx_dump_sel("LDTR", GUEST_LDTR_SELECTOR);
    1.82      vmx_dump_sel2("IDTR", GUEST_IDTR_LIMIT);
    1.83      vmx_dump_sel("TR", GUEST_TR_SELECTOR);
    1.84 +    printk("Guest PAT = 0x%08x%08x\n",
    1.85 +           (uint32_t)vmr(GUEST_PAT_HIGH), (uint32_t)vmr(GUEST_PAT));
    1.86      x  = (unsigned long long)vmr(TSC_OFFSET_HIGH) << 32;
    1.87      x |= (uint32_t)vmr(TSC_OFFSET);
    1.88      printk("TSC Offset = %016llx\n", x);
    1.89 @@ -1027,6 +1051,8 @@ void vmcs_dump_vcpu(struct vcpu *v)
    1.90             (unsigned long long)vmr(HOST_SYSENTER_ESP),
    1.91             (int)vmr(HOST_SYSENTER_CS),
    1.92             (unsigned long long)vmr(HOST_SYSENTER_EIP));
    1.93 +    printk("Host PAT = 0x%08x%08x\n",
    1.94 +           (uint32_t)vmr(HOST_PAT_HIGH), (uint32_t)vmr(HOST_PAT));
    1.95  
    1.96      printk("*** Control State ***\n");
    1.97      printk("PinBased=%08x CPUBased=%08x SecondaryExec=%08x\n",
     2.1 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h	Thu Jan 22 11:17:48 2009 +0000
     2.2 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h	Thu Jan 22 11:21:43 2009 +0000
     2.3 @@ -156,11 +156,14 @@ extern u32 vmx_pin_based_exec_control;
     2.4  
     2.5  #define VM_EXIT_IA32E_MODE              0x00000200
     2.6  #define VM_EXIT_ACK_INTR_ON_EXIT        0x00008000
     2.7 +#define VM_EXIT_SAVE_GUEST_PAT          0x00040000
     2.8 +#define VM_EXIT_LOAD_HOST_PAT           0x00080000
     2.9  extern u32 vmx_vmexit_control;
    2.10  
    2.11  #define VM_ENTRY_IA32E_MODE             0x00000200
    2.12  #define VM_ENTRY_SMM                    0x00000400
    2.13  #define VM_ENTRY_DEACT_DUAL_MONITOR     0x00000800
    2.14 +#define VM_ENTRY_LOAD_GUEST_PAT         0x00004000
    2.15  extern u32 vmx_vmentry_control;
    2.16  
    2.17  #define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001
    2.18 @@ -189,6 +192,8 @@ extern bool_t cpu_has_vmx_ins_outs_instr
    2.19      (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VPID)
    2.20  #define cpu_has_monitor_trap_flag \
    2.21      (vmx_cpu_based_exec_control & CPU_BASED_MONITOR_TRAP_FLAG)
    2.22 +#define cpu_has_vmx_pat \
    2.23 +    (vmx_vmentry_control & VM_ENTRY_LOAD_GUEST_PAT)
    2.24  
    2.25  /* GUEST_INTERRUPTIBILITY_INFO flags. */
    2.26  #define VMX_INTR_SHADOW_STI             0x00000001
    2.27 @@ -240,6 +245,8 @@ enum vmcs_field {
    2.28      VMCS_LINK_POINTER_HIGH          = 0x00002801,
    2.29      GUEST_IA32_DEBUGCTL             = 0x00002802,
    2.30      GUEST_IA32_DEBUGCTL_HIGH        = 0x00002803,
    2.31 +    GUEST_PAT                       = 0x00002804,
    2.32 +    GUEST_PAT_HIGH                  = 0x00002805,
    2.33      GUEST_PDPTR0                    = 0x0000280a,
    2.34      GUEST_PDPTR0_HIGH               = 0x0000280b,
    2.35      GUEST_PDPTR1                    = 0x0000280c,
    2.36 @@ -248,6 +255,8 @@ enum vmcs_field {
    2.37      GUEST_PDPTR2_HIGH               = 0x0000280f,
    2.38      GUEST_PDPTR3                    = 0x00002810,
    2.39      GUEST_PDPTR3_HIGH               = 0x00002811,
    2.40 +    HOST_PAT                        = 0x00002c00,
    2.41 +    HOST_PAT_HIGH                   = 0x00002c01,
    2.42      PIN_BASED_VM_EXEC_CONTROL       = 0x00004000,
    2.43      CPU_BASED_VM_EXEC_CONTROL       = 0x00004002,
    2.44      EXCEPTION_BITMAP                = 0x00004004,