79c4324644
Change-Id: I2d302dda68298877c65c99147f5bf22186a59aac
89 lines
3.6 KiB
Diff
89 lines
3.6 KiB
Diff
From 3eaa433ca1cbee753698893b7732819ba2e31302 Mon Sep 17 00:00:00 2001
|
|
From: Jian Wang <wangjian161@huawei.com>
|
|
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 <wangjian161@huawei.com>
|
|
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
|
---
|
|
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
|
|
|