diff --git a/x86_64/src/cpuid.rs b/x86_64/src/cpuid.rs index 18f1e50089..428e901d2a 100644 --- a/x86_64/src/cpuid.rs +++ b/x86_64/src/cpuid.rs @@ -35,6 +35,7 @@ const ECX_TOPO_TYPE_SHIFT: u32 = 8; // Topology Level type. const ECX_TOPO_SMT_TYPE: u32 = 1; // SMT type. const ECX_TOPO_CORE_TYPE: u32 = 2; // CORE type. const EAX_CPU_CORES_SHIFT: u32 = 26; // Index of cpu cores in the same physical package. +const EDX_HYBRID_CPU_SHIFT: u32 = 15; // Hybrid. The processor is identified as a hybrid part. fn filter_cpuid( vcpu_id: usize, @@ -110,6 +111,26 @@ fn filter_cpuid( // Clear X86 EPB feature. No frequency selection in the hypervisor. entry.ecx &= !(1 << ECX_EPB_SHIFT); } + 7 => { + if host_cpu_topology && entry.index == 0 { + // Safe because we pass 7 and 0 for this call and the host supports the + // `cpuid` instruction + let result = unsafe { __cpuid_count(entry.function, entry.index) }; + entry.edx |= result.edx & (1 << EDX_HYBRID_CPU_SHIFT); + } + } + 0x1A => { + // Hybrid information leaf. + if host_cpu_topology { + // Safe because we pass 0x1A for this call and the host supports the + // `cpuid` instruction + let result = unsafe { __cpuid(entry.function) }; + entry.eax = result.eax; + entry.ebx = result.ebx; + entry.ecx = result.ecx; + entry.edx = result.edx; + } + } 0xB | 0x1F => { if host_cpu_topology { continue;