From 56402d63eefe22179f7311a51ff2094731420406 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 6 May 2016 20:48:16 +0200 Subject: x86/topology: Handle CPUID bogosity gracefully Joseph reported that a XEN guest dies with a division by 0 in the package topology setup code. This happens if cpu_info.x86_max_cores is zero. Handle that case and emit a warning. This does not fix the underlying XEN bug, but makes the code more robust. Reported-and-tested-by: Joseph Salisbury Cc: Peter Zijlstra Cc: Boris Ostrovsky Cc: David Vrabel Link: http://lkml.kernel.org/r/alpine.DEB.2.11.1605062046270.3540@nanos Signed-off-by: Thomas Gleixner --- arch/x86/kernel/smpboot.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index a2065d3b3b39..0e4329ed91ef 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -332,6 +332,11 @@ static void __init smp_init_package_map(void) * primary cores. */ ncpus = boot_cpu_data.x86_max_cores; + if (!ncpus) { + pr_warn("x86_max_cores == zero !?!?"); + ncpus = 1; + } + __max_logical_packages = DIV_ROUND_UP(total_cpus, ncpus); /* -- cgit v1.2.3 From 8d415ee225a3d15d3e3029524350e8237a4de7b8 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 10 May 2016 09:20:33 +0200 Subject: x86/topology: Set x86_max_cores to 1 for CONFIG_SMP=n Josef reported that the uncore driver trips over with CONFIG_SMP=n because x86_max_cores is 16 instead of 12. The reason is, that for SMP=n the extended topology detection is a NOOP and the cache leaf is used to determine the number of cores. That's wrong in two aspects: 1) The cache leaf enumerates the maximum addressable number of cores in the package, which is obviously not correct 2) UP has no business with topology bits at all. Make intel_num_cpu_cores() return 1 for CONFIG_SMP=n Reported-by: Josef Bacik Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: kernel-team Cc: Kan Liang Link: http://lkml.kernel.org/r/761b4a2a-0332-7954-f030-c6639f949612@fb.com --- arch/x86/kernel/cpu/intel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 1f7fdb91a818..e4393bfc7f0d 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -336,7 +336,7 @@ static int intel_num_cpu_cores(struct cpuinfo_x86 *c) { unsigned int eax, ebx, ecx, edx; - if (c->cpuid_level < 4) + if (!IS_ENABLED(CONFIG_SMP) || c->cpuid_level < 4) return 1; /* Intel has a non-standard dependency on %ecx for this CPUID level. */ -- cgit v1.2.3