The CPUID[4].EAX[bits 25:14] encodes the "maximum number of addressable
IDs for logical processors", which value may be different with the
actual number of threads.
For example, there's a Guest with the topology like: 3 threads per core
and 3 cores per package. Its maximum ids for package level is 15 (0xf),
but it has 9 threads per package.
Therefore, using "threads_per_pkg" to check sharing threads overflow (out
of package scope) is not sufficient.
Use Guest's maximum ids for package level information to compare with
Host's.
Note the original check is stricter, but it can be mathematically proven
that the original check does not contain redundant case (e.g.
guest_thread_ids_per_pkg >= host_thread_ids_per_cache > threads_per_pkg,
which is impossible for the current QEMU APIC ID encoding rule).
Therefore, the behavior of this feature is consistent before and after
the change.
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
target/i386/cpu.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index c4d4048ec32a..c20ff69b7b65 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6453,16 +6453,22 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
* set 24..14, 31..26 bit to configured values
*/
if (*eax & 0x1f) {
- int host_vcpus_per_cache = 1 + ((*eax & 0x3FFC000) >> 14);
+ int host_thread_ids_per_cache;
+ int guest_thread_ids_per_pkg;
*eax &= ~0xFC000000;
*eax |= max_core_ids_in_package(&topo_info) << 26;
- if (host_vcpus_per_cache > threads_per_pkg) {
+
+ host_thread_ids_per_cache = 1 + ((*eax & 0x3FFC000) >> 14);
+ guest_thread_ids_per_pkg =
+ max_thread_ids_for_cache(&topo_info,
+ CPU_TOPO_LEVEL_PACKAGE);
+
+ if (host_thread_ids_per_cache > guest_thread_ids_per_pkg) {
*eax &= ~0x3FFC000;
/* Share the cache at package level. */
- *eax |= max_thread_ids_for_cache(&topo_info,
- CPU_TOPO_LEVEL_PACKAGE) << 14;
+ *eax |= guest_thread_ids_per_pkg << 14;
}
}
} else if (cpu->vendor_cpuid_only && IS_AMD_CPU(env)) {
--
2.34.1