Detect whether x2APIC on VMWare is usable without interrupt

redirection support.  Older versions of the hypervisor mis-interpret
the cpuid format in ioapic registers when x2APIC is turned on, but IR
is not used by the guest OS.

Based on:	Linux commit 4cca6ea04d31c22a7d0436949c072b27bde41f86
Tested by:	markj
Sponsored by:	The FreeBSD Foundation
MFC after:	2 months
This commit is contained in:
kib 2015-02-14 09:00:12 +00:00
parent f1a09d8d1a
commit 45b91c251b
2 changed files with 18 additions and 0 deletions

View File

@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/limits.h>
#include <sys/malloc.h>
#include <sys/smp.h>
#include <vm/vm.h>
@ -40,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <machine/intr_machdep.h>
#include <x86/apicvar.h>
#include <machine/md_var.h>
#include <x86/vmware.h>
#include <contrib/dev/acpica/include/acpi.h>
#include <contrib/dev/acpica/include/actables.h>
@ -130,6 +132,7 @@ madt_setup_local(void)
{
ACPI_TABLE_DMAR *dmartbl;
vm_paddr_t dmartbl_physaddr;
u_int p[4];
madt = pmap_mapbios(madt_physaddr, madt_length);
if ((cpu_feature2 & CPUID2_X2APIC) != 0) {
@ -146,6 +149,16 @@ madt_setup_local(void)
}
acpi_unmap_table(dmartbl);
}
if (vm_guest == VM_GUEST_VMWARE) {
vmware_hvcall(VMW_HVCMD_GETVCPU_INFO, p);
if ((p[0] & VMW_VCPUINFO_VCPU_RESERVED) != 0 ||
(p[0] & VMW_VCPUINFO_LEGACY_X2APIC) == 0) {
x2apic_mode = 0;
if (bootverbose)
printf(
"x2APIC available but disabled inside VMWare without intr redirection\n");
}
}
TUNABLE_INT_FETCH("hw.x2apic_enable", &x2apic_mode);
}

View File

@ -31,8 +31,13 @@
#define VMW_HVMAGIC 0x564d5868
#define VMW_HVPORT 0x5658
#define VMW_HVCMD_GETVERSION 10
#define VMW_HVCMD_GETHZ 45
#define VMW_HVCMD_GETVCPU_INFO 68
#define VMW_VCPUINFO_LEGACY_X2APIC (1 << 3)
#define VMW_VCPUINFO_VCPU_RESERVED (1 << 31)
static __inline void
vmware_hvcall(u_int cmd, u_int *p)