diff options
author | Wei Huang <wei@redhat.com> | 2014-10-21 11:00:45 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-10-23 16:41:26 +0200 |
commit | e48638fdb31bb79de964cd8bbd4621648f5d38c6 (patch) | |
tree | 2c2c6c51da0eae5718ff3ed59ba1daf985e6a8a7 | |
parent | b5917219090d14065196fc2dca15562e13c23a26 (diff) |
target-i386: warns users when CPU threads>1 for non-Intel CPUs
Only Intel CPUs support hyperthreading. When users select threads>1 in
-smp option, QEMU fixes it by adjusting CPUID_0000_0001_EBX and
CPUID_8000_0008_ECX based on inputs (sockets, cores, threads);
so guest VM can boot correctly. However it is still better to gives
users a warning when such case happens.
Signed-off-by: Wei Huang <wei@redhat.com>
[As suggested by Eduardo, check for !IS_INTEL instead of AMD. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | target-i386/cpu.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/target-i386/cpu.c b/target-i386/cpu.c index e7bf9de80f..69a2bd39c5 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2696,6 +2696,13 @@ static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp) } #endif + +#define IS_INTEL_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_INTEL_1 && \ + (env)->cpuid_vendor2 == CPUID_VENDOR_INTEL_2 && \ + (env)->cpuid_vendor3 == CPUID_VENDOR_INTEL_3) +#define IS_AMD_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_AMD_1 && \ + (env)->cpuid_vendor2 == CPUID_VENDOR_AMD_2 && \ + (env)->cpuid_vendor3 == CPUID_VENDOR_AMD_3) static void x86_cpu_realizefn(DeviceState *dev, Error **errp) { CPUState *cs = CPU(dev); @@ -2703,6 +2710,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) X86CPUClass *xcc = X86_CPU_GET_CLASS(dev); CPUX86State *env = &cpu->env; Error *local_err = NULL; + static bool ht_warned; if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) { env->cpuid_level = 7; @@ -2711,9 +2719,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on * CPUID[1].EDX. */ - if (env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 && - env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 && - env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) { + if (IS_AMD_CPU(env)) { env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES; env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX] & CPUID_EXT2_AMD_ALIASES); @@ -2742,6 +2748,20 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) mce_init(cpu); qemu_init_vcpu(cs); + /* Only Intel CPUs support hyperthreading. Even though QEMU fixes this + * issue by adjusting CPUID_0000_0001_EBX and CPUID_8000_0008_ECX + * based on inputs (sockets,cores,threads), it is still better to gives + * users a warning. + * + * NOTE: the following code has to follow qemu_init_vcpu(). Otherwise + * cs->nr_threads hasn't be populated yet and the checking is incorrect. + */ + if (!IS_INTEL_CPU(env) && cs->nr_threads > 1 && !ht_warned) { + error_report("AMD CPU doesn't support hyperthreading. Please configure" + " -smp options properly."); + ht_warned = true; + } + x86_cpu_apic_realize(cpu, &local_err); if (local_err != NULL) { goto out; |