[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 12/21] cpuid: Fix multicore setup on Intel
From: |
Andre Przywara |
Subject: |
[Qemu-devel] [PATCH v2 12/21] cpuid: Fix multicore setup on Intel |
Date: |
Fri, 18 Sep 2009 13:48:05 +0200 |
The multicore CPUID code detects whether the guest is an Intel or an
AMD CPU, because the Linux kernel is picky about the CmpLegacy bit.
KVM by default passes through the host's vendor, which was not
catched by the code. So fork out the vendor determining bits into a
separate function to be used from both places and always get the real
vendor.
This fixes KVM's multicore setup on Intel CPUs.
Signed-off-by: Andre Przywara <address@hidden>
Reported-by: Dietmar Maurer <address@hidden>
---
target-i386/cpuid.c | 49 +++++++++++++++++++++++++++++++------------------
1 files changed, 31 insertions(+), 18 deletions(-)
diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 4f2b359..e76457c 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -615,6 +615,24 @@ int cpu_x86_register (CPUX86State *env, const char
*cpu_model)
return 0;
}
+static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
+ uint32_t *ecx, uint32_t *edx)
+{
+ *ebx = env->cpuid_vendor1;
+ *edx = env->cpuid_vendor2;
+ *ecx = env->cpuid_vendor3;
+
+ /* sysenter isn't supported on compatibility mode on AMD, syscall
+ * isn't supported in compatibility mode on Intel.
+ * Normally we advertise the actual cpu vendor, but you can override
+ * this if you want to use KVM's sysenter/syscall emulation
+ * in compatibility mode and when doing cross vendor migration
+ */
+ if (kvm_enabled() &&
+ (env->cpuid_flags & CPUID_FLAGS_VENDOR_OVERRIDE) == 0)
+ host_cpuid(0, 0, NULL, ebx, ecx, edx);
+}
+
#define CPUID_LEAF_PROPAGATE ((1 << 0x02) | (1 << 0x04) | (1 << 0x05) |\
(1 << 0x0D))
#define CPUID_LEAF_PROPAGATE_EXTENDED ((1 << 0x05) | (1 << 0x06) |\
@@ -646,19 +664,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index,
uint32_t count,
switch(index) {
case 0:
*eax = env->cpuid_level;
- *ebx = env->cpuid_vendor1;
- *edx = env->cpuid_vendor2;
- *ecx = env->cpuid_vendor3;
-
- /* sysenter isn't supported on compatibility mode on AMD, syscall
- * isn't supported in compatibility mode on Intel.
- * Normally we advertise the actual cpu vendor, but you can override
- * this if you want to use KVM's sysenter/syscall emulation
- * in compatibility mode and when doing cross vendor migration
- */
- if (kvm_enabled() &&
- (env->cpuid_flags & CPUID_FLAGS_VENDOR_OVERRIDE) == 0)
- host_cpuid(0, 0, NULL, ebx, ecx, edx);
+ get_cpuid_vendor(env, ebx, ecx, edx);
break;
case 1:
*eax = env->cpuid_version;
@@ -755,11 +761,18 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index,
uint32_t count,
*ecx = env->cpuid_ext3_features;
*edx = env->cpuid_ext2_features;
- if (env->nr_cores * env->nr_threads > 1 &&
- env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
- env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
- env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
- *ecx |= 1 << 1; /* CmpLegacy bit */
+ /* The Linux kernel checks for the CMPLegacy bit and
+ * discards multiple thread information if it is set.
+ * So dont set it here for Intel to make Linux guests happy.
+ */
+ if (env->nr_cores * env->nr_threads > 1) {
+ uint32_t tebx, tecx, tedx;
+ get_cpuid_vendor(env, &tebx, &tecx, &tedx);
+ if (tebx != CPUID_VENDOR_INTEL_1 ||
+ tedx != CPUID_VENDOR_INTEL_2 ||
+ tecx != CPUID_VENDOR_INTEL_3) {
+ *ecx |= 1 << 1; /* CmpLegacy bit */
+ }
}
if (kvm_enabled()) {
--
1.6.1.3
- [Qemu-devel] [PATCH v2 07/21] cpuid: add missing CPUID feature flag names, (continued)
- [Qemu-devel] [PATCH v2 07/21] cpuid: add missing CPUID feature flag names, Andre Przywara, 2009/09/18
- [Qemu-devel] [PATCH v2 10/21] cpuid: simplify CPUID flag search function, Andre Przywara, 2009/09/18
- [Qemu-devel] [PATCH v2 09/21] cpuid: remove unnecessary kvm_trim function, Andre Przywara, 2009/09/18
- [Qemu-devel] [PATCH v2 13/21] cpuid: add TCG feature bit trimming, Andre Przywara, 2009/09/18
- [Qemu-devel] [PATCH v2 08/21] cpuid: list all known x86 CPUID feature flags, Andre Przywara, 2009/09/18
- [Qemu-devel] [PATCH v2 15/21] cpuid: Adjust feature bit constants, Andre Przywara, 2009/09/18
- [Qemu-devel] [PATCH v2 16/21] cpuid: Update qemu64/32 CPU models, Andre Przywara, 2009/09/18
- [Qemu-devel] [PATCH v2 14/21] cpuid: decrease L2 cache for Intel and add comments, Andre Przywara, 2009/09/18
- [Qemu-devel] [PATCH v2 01/21] cpuid: move CPUID functions into separate file, Andre Przywara, 2009/09/18
- [Qemu-devel] [PATCH v2 20/21] cpuid: Add kvm32 CPU model, Andre Przywara, 2009/09/18
- [Qemu-devel] [PATCH v2 12/21] cpuid: Fix multicore setup on Intel,
Andre Przywara <=
- [Qemu-devel] [PATCH v2 05/21] cpuid: moved host_cpuid function and remove prototype, Andre Przywara, 2009/09/18
- [Qemu-devel] [PATCH v2 17/21] cpuid: Fix CPU models to use new feature set names, Andre Przywara, 2009/09/18
- [Qemu-devel] [PATCH v2 03/21] cpuid: replace magic number with named constant, Andre Przywara, 2009/09/18
- [Qemu-devel] [PATCH v2 19/21] cpuid: Add athlon64 CPU model, Andre Przywara, 2009/09/18
- [Qemu-devel] [PATCH v2 21/21] cpuid: Always expose 32 and 64-bit CPUs, Andre Przywara, 2009/09/18
- [Qemu-devel] [PATCH v2 18/21] cpuid: Fix 486 CPU model, Andre Przywara, 2009/09/18
- [Qemu-devel] [PATCH v2 11/21] cpuid: propagate further CPUID leafs when -cpu host, Andre Przywara, 2009/09/18