hv: Add support for leaf 0xb emulation

ACRN does not support platforms that do not have x2APIC mode of LAPIC
in hardware. With this patch, x2APIC is exposed to guests by default.

Extended Topology Leaf 0xb in cpuid returns x2APIC ID and topology
information to OS. This patch adds support to return guest topology
and guest x2APIC ID. Number of SMT siblings is returned as 0.

Tracked-On: #1626
Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
Reviewed-by: Xu Anthony <anthony.xu@intel.com>
This commit is contained in:
Sainath Grandhi 2018-11-01 15:42:24 -07:00 committed by lijinxia
parent f3aa20a8ac
commit ff56b6f62d
2 changed files with 26 additions and 17 deletions

View File

@ -23,8 +23,6 @@ static uint64_t startup_paddr = 0UL;
/* physical cpu active bitmap, support up to 64 cpus */
uint64_t pcpu_active_bitmap = 0UL;
/* X2APIC mode is disabled by default. */
bool x2apic_enabled = false;
static bool skip_l1dfl_vmentry;
static uint64_t x86_arch_capabilities;

View File

@ -6,8 +6,6 @@
#include <hypervisor.h>
extern bool x2apic_enabled;
static inline struct vcpuid_entry *find_vcpuid_entry(const struct vcpu *vcpu,
uint32_t leaf_arg, uint32_t subleaf)
{
@ -337,13 +335,6 @@ void guest_cpuid(struct vcpu *vcpu,
*edx &= ~CPUID_EDX_MTRR;
#endif
/* Patching X2APIC, X2APIC mode is disabled by default. */
if (x2apic_enabled) {
*ecx |= CPUID_ECX_x2APIC;
} else {
*ecx &= ~CPUID_ECX_x2APIC;
}
/* mask pcid */
*ecx &= ~CPUID_ECX_PCID;
@ -369,13 +360,33 @@ void guest_cpuid(struct vcpu *vcpu,
case 0x0bU:
/* Patching X2APIC */
if (!x2apic_enabled) {
*eax = 0U;
*ebx = 0U;
*ecx = 0U;
*edx = 0U;
} else {
if (is_vm0(vcpu->vm)) {
cpuid_subleaf(leaf, subleaf, eax, ebx, ecx, edx);
} else {
*ecx = subleaf & 0xFFU;
*edx = vlapic_get_apicid(vcpu_vlapic(vcpu));
/* No HT emulation for UOS */
switch (subleaf) {
case 0U:
*eax = 0U;
*ebx = 1U;
*ecx |= (1U << 8U);
break;
case 1U:
if (vcpu->vm->hw.created_vcpus == 1U) {
*eax = 0U;
} else {
*eax = (uint32_t)fls32(vcpu->vm->hw.created_vcpus - 1U) + 1U;
}
*ebx = vcpu->vm->hw.created_vcpus;
*ecx |= (2U << 8U);
break;
default:
*eax = 0U;
*ebx = 0U;
*ecx |= (0U << 8U);
break;
}
}
break;