ia64/xen-unstable

changeset 15572:25a42f826a63

vmx: Never use physical addresses above 4GB for VMCS state on i386.

Thsi requires special allocation of the vlapic regs page, but does let
us get rid of some top-half writes to a few VMCS fields.

Assert a few more facts about the VMX_BASIC_MSR.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Tue Jul 10 23:37:42 2007 +0100 (2007-07-10)
parents 1315b0901dea
children ff51ff907f8c
files xen/arch/x86/hvm/vlapic.c xen/arch/x86/hvm/vmx/vmcs.c xen/arch/x86/hvm/vmx/vmx.c
line diff
     1.1 --- a/xen/arch/x86/hvm/vlapic.c	Tue Jul 10 15:45:44 2007 +0100
     1.2 +++ b/xen/arch/x86/hvm/vlapic.c	Tue Jul 10 23:37:42 2007 +0100
     1.3 @@ -915,10 +915,17 @@ HVM_REGISTER_SAVE_RESTORE(LAPIC_REGS, la
     1.4  int vlapic_init(struct vcpu *v)
     1.5  {
     1.6      struct vlapic *vlapic = vcpu_vlapic(v);
     1.7 +    unsigned int memflags = 0;
     1.8  
     1.9      HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "%d", v->vcpu_id);
    1.10  
    1.11 -    vlapic->regs_page = alloc_domheap_page(NULL);
    1.12 +#ifdef __i386__
    1.13 +    /* 32-bit VMX may be limited to 32-bit physical addresses. */
    1.14 +    if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
    1.15 +        memflags = MEMF_bits(32);
    1.16 +#endif
    1.17 +
    1.18 +    vlapic->regs_page = alloc_domheap_pages(NULL, 0, memflags);
    1.19      if ( vlapic->regs_page == NULL )
    1.20      {
    1.21          dprintk(XENLOG_ERR, "alloc vlapic regs error: %d/%d\n",
     2.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Tue Jul 10 15:45:44 2007 +0100
     2.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Tue Jul 10 23:37:42 2007 +0100
     2.3 @@ -151,6 +151,14 @@ void vmx_init_vmcs_config(void)
     2.4  
     2.5      /* IA-32 SDM Vol 3B: VMCS size is never greater than 4kB. */
     2.6      BUG_ON((vmx_msr_high & 0x1fff) > PAGE_SIZE);
     2.7 +
     2.8 +#ifdef __x86_64__
     2.9 +    /* IA-32 SDM Vol 3B: 64-bit CPUs always have VMX_BASIC_MSR[48]==0. */
    2.10 +    BUG_ON(vmx_msr_high & (1u<<16));
    2.11 +#endif
    2.12 +
    2.13 +    /* Require Write-Back (WB) memory type for VMCS accesses. */
    2.14 +    BUG_ON(((vmx_msr_high >> 18) & 15) == 6);
    2.15  }
    2.16  
    2.17  static struct vmcs_struct *vmx_alloc_vmcs(void)
    2.18 @@ -422,11 +430,8 @@ static void construct_vmcs(struct vcpu *
    2.19  
    2.20      if ( cpu_has_vmx_tpr_shadow )
    2.21      {
    2.22 -        paddr_t virt_page_ma = page_to_maddr(vcpu_vlapic(v)->regs_page);
    2.23 -        __vmwrite(VIRTUAL_APIC_PAGE_ADDR, virt_page_ma);
    2.24 -#if defined (CONFIG_X86_PAE)
    2.25 -        __vmwrite(VIRTUAL_APIC_PAGE_ADDR_HIGH, virt_page_ma >> 32);
    2.26 -#endif
    2.27 +        __vmwrite(VIRTUAL_APIC_PAGE_ADDR,
    2.28 +                  page_to_maddr(vcpu_vlapic(v)->regs_page));
    2.29          __vmwrite(TPR_THRESHOLD, 0);
    2.30      }
    2.31  
     3.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Tue Jul 10 15:45:44 2007 +0100
     3.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Tue Jul 10 23:37:42 2007 +0100
     3.3 @@ -2718,7 +2718,7 @@ static void vmx_free_vlapic_mapping(stru
     3.4  
     3.5  static void vmx_install_vlapic_mapping(struct vcpu *v)
     3.6  {
     3.7 -    paddr_t virt_page_ma, apic_page_ma;
     3.8 +    unsigned long virt_page_ma, apic_page_ma;
     3.9  
    3.10      if ( !cpu_has_vmx_virtualize_apic_accesses )
    3.11          return;
    3.12 @@ -2730,10 +2730,6 @@ static void vmx_install_vlapic_mapping(s
    3.13      vmx_vmcs_enter(v);
    3.14      __vmwrite(VIRTUAL_APIC_PAGE_ADDR, virt_page_ma);
    3.15      __vmwrite(APIC_ACCESS_ADDR, apic_page_ma);
    3.16 -#if defined (CONFIG_X86_PAE)
    3.17 -    __vmwrite(VIRTUAL_APIC_PAGE_ADDR_HIGH, virt_page_ma >> 32);
    3.18 -    __vmwrite(APIC_ACCESS_ADDR_HIGH, apic_page_ma >> 32);
    3.19 -#endif
    3.20      vmx_vmcs_exit(v);
    3.21  }
    3.22