diff --git a/arch/src/x86_64/mod.rs b/arch/src/x86_64/mod.rs index b90095ef7..08641af17 100644 --- a/arch/src/x86_64/mod.rs +++ b/arch/src/x86_64/mod.rs @@ -830,10 +830,6 @@ pub fn configure_vcpu( CpuidPatch::set_cpuid_reg(&mut cpuid, 0x8000_001e, Some(0), CpuidReg::EAX, x2apic_id); } - if let Some(t) = topology { - update_cpuid_topology(&mut cpuid, t.0, t.1, t.2, cpu_vendor, 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; @@ -841,6 +837,10 @@ pub fn configure_vcpu( cpu_ebx |= x2apic_id << 24; CpuidPatch::set_cpuid_reg(&mut cpuid, 0x1, None, CpuidReg::EBX, cpu_ebx); + if let Some(t) = topology { + update_cpuid_topology(&mut cpuid, t.0, t.1, t.2, cpu_vendor, id); + } + // 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)? { @@ -1277,6 +1277,15 @@ fn update_cpuid_topology( let core_width = (8 - (cores_per_die - 1).leading_zeros()) + thread_width; let die_width = (8 - (dies_per_package - 1).leading_zeros()) + core_width; + let mut cpu_ebx = CpuidPatch::get_cpuid_reg(cpuid, 0x1, None, CpuidReg::EBX).unwrap_or(0); + cpu_ebx |= ((dies_per_package as u32) * (cores_per_die as u32) * (threads_per_core as u32)) + & 0xff << 16; + CpuidPatch::set_cpuid_reg(cpuid, 0x1, None, CpuidReg::EBX, cpu_ebx); + + let mut cpu_edx = CpuidPatch::get_cpuid_reg(cpuid, 0x1, None, CpuidReg::EDX).unwrap_or(0); + cpu_edx |= 1 << 28; + CpuidPatch::set_cpuid_reg(cpuid, 0x1, None, CpuidReg::EDX, cpu_edx); + // CPU Topology leaf 0xb CpuidPatch::set_cpuid_reg(cpuid, 0xb, Some(0), CpuidReg::EAX, thread_width); CpuidPatch::set_cpuid_reg(