aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhao Liu <zhao1.liu@intel.com>2025-07-11 18:21:35 +0800
committerPaolo Bonzini <pbonzini@redhat.com>2025-07-12 15:28:21 +0200
commit63dc9f52f63475f61404a7f5a010aa352ead8763 (patch)
tree7160c1296828b3fd6defa2e9469dd265d7d31ab3
parent3275a379c8ff0862550910a97e8c0c9b056643cd (diff)
downloadqemu-63dc9f52f63475f61404a7f5a010aa352ead8763.zip
qemu-63dc9f52f63475f61404a7f5a010aa352ead8763.tar.gz
qemu-63dc9f52f63475f61404a7f5a010aa352ead8763.tar.bz2
i386/cpu: Fix CPUID[0x80000006] for Intel CPU
Per SDM, Intel supports CPUID[0x80000006]. But only L2 information is encoded in ECX (note that L2 associativity field encodings rules consistent with AMD are used), all other fields are reserved. Therefore, make the following changes to CPUID[0x80000006]: * Check the vendor in CPUID[0x80000006] and just encode L2 to ECX for Intel. * Drop the lines_per_tag assertion, since AMD supports this field but Intel doesn't. And this field can be easily checked via cpuid tool in Guest. * Apply the encoding change of Intel for Zhaoxin as well [1]. This fix also resolves the FIXME of legacy_l2_cache_amd: /*FIXME: CPUID leaf 0x80000006 is inconsistent with leaves 2 & 4 */ In addition, per AMD's APM, update the comment of CPUID[0x80000006]. [1]: https://lore.kernel.org/qemu-devel/c522ebb5-04d5-49c6-9ad8-d755b8998988@zhaoxin.com/ Tested-by: Yi Lai <yi1.lai@intel.com> Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250711102143.1622339-11-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--target/i386/cpu.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 8a97272..6a0e859 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -531,16 +531,15 @@ static void encode_cache_cpuid80000006(CPUCacheInfo *l2,
{
assert(l2->size % 1024 == 0);
assert(l2->associativity > 0);
- assert(l2->lines_per_tag > 0);
assert(l2->line_size > 0);
*ecx = ((l2->size / 1024) << 16) |
(X86_ENC_ASSOC(l2->associativity) << 12) |
(l2->lines_per_tag << 8) | (l2->line_size);
+ /* For Intel, EDX is reserved. */
if (l3) {
assert(l3->size % (512 * 1024) == 0);
assert(l3->associativity > 0);
- assert(l3->lines_per_tag > 0);
assert(l3->line_size > 0);
*edx = ((l3->size / (512 * 1024)) << 18) |
(X86_ENC_ASSOC(l3->associativity) << 12) |
@@ -712,7 +711,6 @@ static CPUCacheInfo legacy_l2_cache = {
.share_level = CPU_TOPOLOGY_LEVEL_CORE,
};
-/*FIXME: CPUID leaf 0x80000006 is inconsistent with leaves 2 & 4 */
static CPUCacheInfo legacy_l2_cache_amd = {
.type = UNIFIED_CACHE,
.level = 2,
@@ -7900,11 +7898,20 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*edx = encode_cache_cpuid80000005(env->cache_info_amd.l1i_cache);
break;
case 0x80000006:
- /* cache info (L2 cache) */
+ /* cache info (L2 cache/TLB/L3 cache) */
if (cpu->cache_info_passthrough) {
x86_cpu_get_cache_cpuid(index, 0, eax, ebx, ecx, edx);
break;
}
+
+ if (cpu->vendor_cpuid_only_v2 &&
+ (IS_INTEL_CPU(env) || IS_ZHAOXIN_CPU(env))) {
+ *eax = *ebx = 0;
+ encode_cache_cpuid80000006(env->cache_info_cpuid4.l2_cache,
+ NULL, ecx, edx);
+ break;
+ }
+
*eax = (X86_ENC_ASSOC(L2_DTLB_2M_ASSOC) << 28) |
(L2_DTLB_2M_ENTRIES << 16) |
(X86_ENC_ASSOC(L2_ITLB_2M_ASSOC) << 12) |
@@ -7913,6 +7920,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
(L2_DTLB_4K_ENTRIES << 16) |
(X86_ENC_ASSOC(L2_ITLB_4K_ASSOC) << 12) |
(L2_ITLB_4K_ENTRIES);
+
encode_cache_cpuid80000006(env->cache_info_amd.l2_cache,
cpu->enable_l3_cache ?
env->cache_info_amd.l3_cache : NULL,