diff --git a/i386-cache-passthrough-Update-Intel-CPUID4.EAX-25-14.patch b/i386-cache-passthrough-Update-Intel-CPUID4.EAX-25-14.patch new file mode 100644 index 0000000..a0fc157 --- /dev/null +++ b/i386-cache-passthrough-Update-Intel-CPUID4.EAX-25-14.patch @@ -0,0 +1,88 @@ +From 3eaa433ca1cbee753698893b7732819ba2e31302 Mon Sep 17 00:00:00 2001 +From: Jian Wang +Date: Thu, 10 Feb 2022 19:43:55 +0800 +Subject: [PATCH] i386: cache passthrough: Update Intel CPUID4.EAX[25:14] based + on vCPU topo + +On Intel target, when host cache passthrough is disabled we will +emulate the guest caches with default values and initialize the +shared cpu list of the caches based on vCPU topology. However when +host cache passthrough is enabled, the shared cpu list is consistent +with host regardless what the vCPU topology is. + +For example, when cache passthrough is enabled, running a guest +with vThreads=1 on a host with pThreads=2, we will get that there +are every *two* logical vCPUs sharing a L1/L2 cache, which is not +consistent with the vCPU topology (vThreads=1). + +So let's reinitialize BITs[25:14] of Intel CPUID 4 based on the +actual vCPU topology instead of host pCPU topology. + +Signed-off-by: Jian Wang +Signed-off-by: Yanan Wang +--- + target/i386/cpu.c | 27 +++++++++++++++++++++++---- + 1 file changed, 23 insertions(+), 4 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 868cf3e7e8..c1fe2895fd 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -5196,7 +5196,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, + { + X86CPU *cpu = env_archcpu(env); + CPUState *cs = env_cpu(env); +- uint32_t die_offset; ++ uint32_t die_offset, smt_width; + uint32_t limit; + uint32_t signature[3]; + X86CPUTopoInfo topo_info; +@@ -5205,6 +5205,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, + topo_info.cores_per_die = cs->nr_cores; + topo_info.threads_per_core = cs->nr_threads; + ++ die_offset = apicid_die_offset(&topo_info); ++ smt_width = apicid_smt_width(&topo_info); ++ + /* Calculate & apply limits for different index ranges */ + if (index >= 0xC0000000) { + limit = env->cpuid_xlevel2; +@@ -5272,8 +5275,25 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, + /* cache info: needed for Core compatibility */ + if (cpu->cache_info_passthrough) { + host_cpuid(index, count, eax, ebx, ecx, edx); +- /* QEMU gives out its own APIC IDs, never pass down bits 31..26. */ +- *eax &= ~0xFC000000; ++ /* ++ * QEMU gives out its own APIC IDs, never pass down bits 31..26. ++ * Update the cache topo bits 25..14, according to the guest ++ * vCPU topology instead of the host pCPU topology. ++ */ ++ *eax &= ~0xFFFFC000; ++ switch (count) { ++ case 0: /* L1 dcache info */ ++ case 1: /* L1 icache info */ ++ case 2: /* L2 cache info */ ++ *eax |= ((1 << smt_width) - 1) << 14; ++ break; ++ case 3: /* L3 cache info */ ++ *eax |= ((1 << die_offset) - 1) << 14; ++ break; ++ default: /* end of info */ ++ *eax = *ebx = *ecx = *edx = 0; ++ break; ++ } + if ((*eax & 31) && cs->nr_cores > 1) { + *eax |= (cs->nr_cores - 1) << 26; + } +@@ -5298,7 +5318,6 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, + eax, ebx, ecx, edx); + break; + case 3: /* L3 cache info */ +- die_offset = apicid_die_offset(&topo_info); + if (cpu->enable_l3_cache) { + encode_cache_cpuid4(env->cache_info_cpuid4.l3_cache, + (1 << die_offset), cs->nr_cores, +-- +2.27.0 +