# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1184107062 -3600
# Node ID 25a42f826a630f2e9ff19a73005051ae2e92b96c
# Parent 1315b0901deaedcc375e1ec3cb97a67d7c1804be
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@xxxxxxxxxxxxx>
---
xen/arch/x86/hvm/vlapic.c | 9 ++++++++-
xen/arch/x86/hvm/vmx/vmcs.c | 15 ++++++++++-----
xen/arch/x86/hvm/vmx/vmx.c | 6 +-----
3 files changed, 19 insertions(+), 11 deletions(-)
diff -r 1315b0901dea -r 25a42f826a63 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Tue Jul 10 15:45:44 2007 +0100
+++ b/xen/arch/x86/hvm/vlapic.c Tue Jul 10 23:37:42 2007 +0100
@@ -915,10 +915,17 @@ int vlapic_init(struct vcpu *v)
int vlapic_init(struct vcpu *v)
{
struct vlapic *vlapic = vcpu_vlapic(v);
+ unsigned int memflags = 0;
HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "%d", v->vcpu_id);
- vlapic->regs_page = alloc_domheap_page(NULL);
+#ifdef __i386__
+ /* 32-bit VMX may be limited to 32-bit physical addresses. */
+ if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
+ memflags = MEMF_bits(32);
+#endif
+
+ vlapic->regs_page = alloc_domheap_pages(NULL, 0, memflags);
if ( vlapic->regs_page == NULL )
{
dprintk(XENLOG_ERR, "alloc vlapic regs error: %d/%d\n",
diff -r 1315b0901dea -r 25a42f826a63 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c Tue Jul 10 15:45:44 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c Tue Jul 10 23:37:42 2007 +0100
@@ -151,6 +151,14 @@ void vmx_init_vmcs_config(void)
/* IA-32 SDM Vol 3B: VMCS size is never greater than 4kB. */
BUG_ON((vmx_msr_high & 0x1fff) > PAGE_SIZE);
+
+#ifdef __x86_64__
+ /* IA-32 SDM Vol 3B: 64-bit CPUs always have VMX_BASIC_MSR[48]==0. */
+ BUG_ON(vmx_msr_high & (1u<<16));
+#endif
+
+ /* Require Write-Back (WB) memory type for VMCS accesses. */
+ BUG_ON(((vmx_msr_high >> 18) & 15) == 6);
}
static struct vmcs_struct *vmx_alloc_vmcs(void)
@@ -422,11 +430,8 @@ static void construct_vmcs(struct vcpu *
if ( cpu_has_vmx_tpr_shadow )
{
- paddr_t virt_page_ma = page_to_maddr(vcpu_vlapic(v)->regs_page);
- __vmwrite(VIRTUAL_APIC_PAGE_ADDR, virt_page_ma);
-#if defined (CONFIG_X86_PAE)
- __vmwrite(VIRTUAL_APIC_PAGE_ADDR_HIGH, virt_page_ma >> 32);
-#endif
+ __vmwrite(VIRTUAL_APIC_PAGE_ADDR,
+ page_to_maddr(vcpu_vlapic(v)->regs_page));
__vmwrite(TPR_THRESHOLD, 0);
}
diff -r 1315b0901dea -r 25a42f826a63 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Tue Jul 10 15:45:44 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c Tue Jul 10 23:37:42 2007 +0100
@@ -2718,7 +2718,7 @@ static void vmx_free_vlapic_mapping(stru
static void vmx_install_vlapic_mapping(struct vcpu *v)
{
- paddr_t virt_page_ma, apic_page_ma;
+ unsigned long virt_page_ma, apic_page_ma;
if ( !cpu_has_vmx_virtualize_apic_accesses )
return;
@@ -2730,10 +2730,6 @@ static void vmx_install_vlapic_mapping(s
vmx_vmcs_enter(v);
__vmwrite(VIRTUAL_APIC_PAGE_ADDR, virt_page_ma);
__vmwrite(APIC_ACCESS_ADDR, apic_page_ma);
-#if defined (CONFIG_X86_PAE)
- __vmwrite(VIRTUAL_APIC_PAGE_ADDR_HIGH, virt_page_ma >> 32);
- __vmwrite(APIC_ACCESS_ADDR_HIGH, apic_page_ma >> 32);
-#endif
vmx_vmcs_exit(v);
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|