aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhao Liu <zhao1.liu@intel.com>2025-07-11 18:21:42 +0800
committerPaolo Bonzini <pbonzini@redhat.com>2025-07-12 15:28:22 +0200
commit25acae4c6e7635ff0f0d36945548de4c0dc70608 (patch)
tree5c17496f04853ba1df479215dd21a861c96fb8ed
parent00fa96c96a864e133c22a5f3793b468bb8a121a5 (diff)
downloadqemu-25acae4c6e7635ff0f0d36945548de4c0dc70608.zip
qemu-25acae4c6e7635ff0f0d36945548de4c0dc70608.tar.gz
qemu-25acae4c6e7635ff0f0d36945548de4c0dc70608.tar.bz2
i386/cpu: Select legacy cache model based on vendor in CPUID 0x8000001D
As preparation for merging cache_info_cpuid4 and cache_info_amd in X86CPUState, set legacy cache model based on vendor in the CPUID 0x8000001D leaf. For AMD CPU, select legacy AMD cache model (in cache_info_amd) as the default cache model like before, otherwise, select legacy Intel cache model (in cache_info_cpuid4). In fact, for Intel (and Zhaoxin) CPU, this change is safe because the extended CPUID level supported by Intel is up to 0x80000008. So Intel Guest doesn't have this 0x8000001D leaf. Although someone could bump "xlevel" up to 0x8000001D for Intel Guest, it's meaningless and this is undefined behavior. This leaf should be considered reserved, but the SDM does not explicitly state this. So, there's no need to specifically use vendor_cpuid_only_v2 to fix anything, as it doesn't even qualify as a fix since nothing is currently broken. Therefore, it is acceptable to select the default legacy cache model based on the vendor. For the CPUID 0x8000001D leaf, in X86CPUState, a unified cache_info is enough. It only needs to be initialized and configured with the corresponding legacy cache model based on the vendor. 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-18-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--target/i386/cpu.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index b557fd0..5b96974 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -8080,7 +8080,22 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*edx = 0;
}
break;
- case 0x8000001D:
+ case 0x8000001D: {
+ const CPUCaches *caches;
+
+ /*
+ * FIXME: Temporarily select cache info model here based on
+ * vendor, and merge these 2 cache info models later.
+ *
+ * Intel doesn't support this leaf so that Intel Guests don't
+ * have this leaf. This change is harmless to Intel CPUs.
+ */
+ if (IS_AMD_CPU(env)) {
+ caches = &env->cache_info_amd;
+ } else {
+ caches = &env->cache_info_cpuid4;
+ }
+
*eax = 0;
if (cpu->cache_info_passthrough) {
x86_cpu_get_cache_cpuid(index, count, eax, ebx, ecx, edx);
@@ -8088,19 +8103,19 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
}
switch (count) {
case 0: /* L1 dcache info */
- encode_cache_cpuid8000001d(env->cache_info_amd.l1d_cache,
+ encode_cache_cpuid8000001d(caches->l1d_cache,
topo_info, eax, ebx, ecx, edx);
break;
case 1: /* L1 icache info */
- encode_cache_cpuid8000001d(env->cache_info_amd.l1i_cache,
+ encode_cache_cpuid8000001d(caches->l1i_cache,
topo_info, eax, ebx, ecx, edx);
break;
case 2: /* L2 cache info */
- encode_cache_cpuid8000001d(env->cache_info_amd.l2_cache,
+ encode_cache_cpuid8000001d(caches->l2_cache,
topo_info, eax, ebx, ecx, edx);
break;
case 3: /* L3 cache info */
- encode_cache_cpuid8000001d(env->cache_info_amd.l3_cache,
+ encode_cache_cpuid8000001d(caches->l3_cache,
topo_info, eax, ebx, ecx, edx);
break;
default: /* end of info */
@@ -8111,6 +8126,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*edx &= CACHE_NO_INVD_SHARING | CACHE_INCLUSIVE;
}
break;
+ }
case 0x8000001E:
if (cpu->core_id <= 255) {
encode_topo_cpuid8000001e(cpu, topo_info, eax, ebx, ecx, edx);