From d86905b92af9a377ff9862de3aaa91a267fa8977 Mon Sep 17 00:00:00 2001 From: Jianyong Wu Date: Thu, 15 Jun 2023 11:41:59 +0800 Subject: [PATCH] arch: x86_64: Populate the APIC Id Program the APIC ID (CPUID leaf 0x1 EBX) with the CPU id. This resolves an issue where the EDKII firmware expects the APIC ID to vary per-CPU. Fixes: #5475 Signed-off-by: Jianyong Wu --- arch/src/x86_64/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/src/x86_64/mod.rs b/arch/src/x86_64/mod.rs index a7d97aabc..e02ecca11 100644 --- a/arch/src/x86_64/mod.rs +++ b/arch/src/x86_64/mod.rs @@ -775,6 +775,13 @@ pub fn configure_vcpu( CpuidPatch::set_cpuid_reg(&mut cpuid, 0xb, None, CpuidReg::EDX, u32::from(id)); CpuidPatch::set_cpuid_reg(&mut cpuid, 0x1f, None, CpuidReg::EDX, u32::from(id)); + // Set ApicId in cpuid for each vcpu + // SAFETY: get host cpuid when eax=1 + let mut cpu_ebx = unsafe { core::arch::x86_64::__cpuid(1) }.ebx; + cpu_ebx &= 0xffffff; + cpu_ebx |= (id as u32) << 24; + CpuidPatch::set_cpuid_reg(&mut cpuid, 0x1, None, CpuidReg::EBX, cpu_ebx); + // The TSC frequency CPUID leaf should not be included when running with HyperV emulation if !kvm_hyperv { if let Some(tsc_khz) = vcpu.tsc_khz().map_err(Error::GetTscFrequency)? {