From eb4dd90532b0d0bcda69c8bdb83e7c6be07e2451 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Thu, 30 May 2024 13:39:38 +0100 Subject: [PATCH] arch: x86_64: Avoid calling cpuid for setting LAPIC ID Rather than calling cpuid and then updating the APIC ID field - use the existing common CPUID data which already includes CPUID data for eax=1 (aka function = 1). This removes the need to call cpuid per vCPU thread created. This has a positive impact on boot time with multiple vCPUs as the cpuid instruction is serialising. Fixes: #5646 Signed-off-by: Rob Bradford --- arch/src/x86_64/mod.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/arch/src/x86_64/mod.rs b/arch/src/x86_64/mod.rs index 16dc2eb46..afbb25b68 100644 --- a/arch/src/x86_64/mod.rs +++ b/arch/src/x86_64/mod.rs @@ -820,12 +820,17 @@ pub fn configure_vcpu( CpuidPatch::set_cpuid_reg(&mut cpuid, 0x8000_001e, Some(0), CpuidReg::EAX, x2apic_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 |= x2apic_id << 24; - CpuidPatch::set_cpuid_reg(&mut cpuid, 0x1, None, CpuidReg::EBX, cpu_ebx); + // Set ApicId in cpuid for each vcpu - found in cpuid ebx when eax = 1 + let mut apic_id_patched = false; + for entry in &mut cpuid { + if entry.function == 1 { + entry.ebx &= 0xffffff; + entry.ebx |= x2apic_id << 24; + apic_id_patched = true; + break; + } + } + assert!(apic_id_patched); if let Some(t) = topology { update_cpuid_topology(&mut cpuid, t.0, t.1, t.2, cpu_vendor, id);