From 79eb86a5b9466cee19bc4e47429385a7244cdc4f Mon Sep 17 00:00:00 2001 From: Zhuocheng Ding Date: Mon, 6 Dec 2021 14:52:03 +0800 Subject: [PATCH] x86: Expose hybrid CPU info to Guest At present, when set host-cpu-topology option, the Guest still can't get the hybrid information. Now, for ADL, the hybrid related info is needed. These info include the hybrid part flag (bit 15) in leaf 7 of CPUID, the core type and native model id in leaf 1A of CPUID. BUG=None TEST=cargo build TEST=Check the CPUID dump of Guest and Host Change-Id: Icc03bc50160fdffc221e992d90225e7ed8081e8d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3314867 Reviewed-by: David Stevens Tested-by: kokoro Reviewed-by: Daniel Verkamp Commit-Queue: Daniel Verkamp --- x86_64/src/cpuid.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) 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;