summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/mpspec.h2
-rw-r--r--arch/x86/kernel/apic/apic.c3
-rw-r--r--arch/x86/kernel/apic/bigsmp_32.c22
-rw-r--r--arch/x86/kernel/apic/local.h11
-rw-r--r--arch/x86/kernel/apic/probe_32.c35
-rw-r--r--arch/x86/kernel/setup.c1
-rw-r--r--arch/x86/kernel/smpboot.c37
7 files changed, 41 insertions, 70 deletions
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index 5d01bdee0186..f46df8349e86 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -23,8 +23,6 @@ extern int pic_mode;
#define MAX_IRQ_SOURCES 256
-extern unsigned int def_to_bigsmp;
-
#else /* CONFIG_X86_64: */
#define MAX_MP_BUSSES 256
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 224dff4b9258..24912b2279de 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -63,6 +63,8 @@
#include <asm/irq_regs.h>
#include <asm/cpu.h>
+#include "local.h"
+
unsigned int num_processors;
unsigned disabled_cpus;
@@ -2420,6 +2422,7 @@ static __init void cpu_set_boot_apic(void)
{
cpuid_to_apicid[0] = boot_cpu_physical_apicid;
cpu_update_apic(0, boot_cpu_physical_apicid);
+ x86_32_probe_bigsmp_early();
}
int generic_processor_info(int apicid)
diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c
index d19dcf99bd05..a26cb4684017 100644
--- a/arch/x86/kernel/apic/bigsmp_32.c
+++ b/arch/x86/kernel/apic/bigsmp_32.c
@@ -100,12 +100,7 @@ static const struct dmi_system_id bigsmp_dmi_table[] = {
static int probe_bigsmp(void)
{
- if (def_to_bigsmp)
- dmi_bigsmp = 1;
- else
- dmi_check_system(bigsmp_dmi_table);
-
- return dmi_bigsmp;
+ return dmi_check_system(bigsmp_dmi_table);
}
static struct apic apic_bigsmp __ro_after_init = {
@@ -149,14 +144,17 @@ static struct apic apic_bigsmp __ro_after_init = {
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
};
-void __init generic_bigsmp_probe(void)
+bool __init apic_bigsmp_possible(bool cmdline_override)
{
- if (!probe_bigsmp())
- return;
-
- apic = &apic_bigsmp;
+ return apic == &apic_bigsmp || !cmdline_override;
+}
- pr_info("Overriding APIC driver with %s\n", apic_bigsmp.name);
+void __init apic_bigsmp_force(void)
+{
+ if (apic != &apic_bigsmp) {
+ apic = &apic_bigsmp;
+ pr_info("Overriding APIC driver with bigsmp\n");
+ }
}
apic_driver(apic_bigsmp);
diff --git a/arch/x86/kernel/apic/local.h b/arch/x86/kernel/apic/local.h
index a997d849509a..ad96c1aece2f 100644
--- a/arch/x86/kernel/apic/local.h
+++ b/arch/x86/kernel/apic/local.h
@@ -66,4 +66,15 @@ void default_send_IPI_self(int vector);
void default_send_IPI_mask_sequence_logical(const struct cpumask *mask, int vector);
void default_send_IPI_mask_allbutself_logical(const struct cpumask *mask, int vector);
void default_send_IPI_mask_logical(const struct cpumask *mask, int vector);
+void x86_32_probe_bigsmp_early(void);
+#else
+static inline void x86_32_probe_bigsmp_early(void) { }
+#endif
+
+#ifdef CONFIG_X86_BIGSMP
+bool apic_bigsmp_possible(bool cmdline_selected);
+void apic_bigsmp_force(void);
+#else
+static inline bool apic_bigsmp_possible(bool cmdline_selected) { return false; };
+static inline void apic_bigsmp_force(void) { }
#endif
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c
index 20d7f571b80f..706a8447ac17 100644
--- a/arch/x86/kernel/apic/probe_32.c
+++ b/arch/x86/kernel/apic/probe_32.c
@@ -10,6 +10,8 @@
#include <linux/errno.h>
#include <linux/smp.h>
+#include <xen/xen.h>
+
#include <asm/io_apic.h>
#include <asm/apic.h>
#include <asm/acpi.h>
@@ -123,36 +125,33 @@ static int __init parse_apic(char *arg)
}
early_param("apic", parse_apic);
-void __init default_setup_apic_routing(void)
+void __init x86_32_probe_bigsmp_early(void)
{
- int version = boot_cpu_apic_version;
+ if (nr_cpu_ids <= 8 || xen_pv_domain())
+ return;
- if (num_possible_cpus() > 8) {
+ if (IS_ENABLED(CONFIG_X86_BIGSMP)) {
switch (boot_cpu_data.x86_vendor) {
case X86_VENDOR_INTEL:
- if (!APIC_XAPIC(version)) {
- def_to_bigsmp = 0;
+ if (!APIC_XAPIC(boot_cpu_apic_version))
break;
- }
/* P4 and above */
fallthrough;
case X86_VENDOR_HYGON:
case X86_VENDOR_AMD:
- def_to_bigsmp = 1;
+ if (apic_bigsmp_possible(cmdline_apic))
+ return;
+ break;
}
}
+ pr_info("Limiting to 8 possible CPUs\n");
+ set_nr_cpu_ids(8);
+}
-#ifdef CONFIG_X86_BIGSMP
- /*
- * This is used to switch to bigsmp mode when
- * - There is no apic= option specified by the user
- * - generic_apic_probe() has chosen apic_default as the sub_arch
- * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support
- */
-
- if (!cmdline_apic && apic == &apic_default)
- generic_bigsmp_probe();
-#endif
+void __init default_setup_apic_routing(void)
+{
+ if (nr_cpu_ids > 8 && !xen_pv_domain())
+ apic_bigsmp_force();
if (apic->setup_apic_routing)
apic->setup_apic_routing();
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index a5ef400928da..779477d92caa 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -114,7 +114,6 @@ static struct resource bss_resource = {
#ifdef CONFIG_X86_32
/* CPU data as detected by the assembly code in head_32.S */
struct cpuinfo_x86 new_cpu_data;
-unsigned int def_to_bigsmp;
struct apm_info apm_info;
EXPORT_SYMBOL(apm_info);
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index da795f743542..df1c5f01411b 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1149,41 +1149,6 @@ static __init void disable_smp(void)
cpumask_set_cpu(0, topology_die_cpumask(0));
}
-/*
- * Various sanity checks.
- */
-static void __init smp_sanity_check(void)
-{
- preempt_disable();
-
-#if !defined(CONFIG_X86_BIGSMP) && defined(CONFIG_X86_32)
- if (def_to_bigsmp && nr_cpu_ids > 8) {
- unsigned int cpu;
- unsigned nr;
-
- pr_warn("More than 8 CPUs detected - skipping them\n"
- "Use CONFIG_X86_BIGSMP\n");
-
- nr = 0;
- for_each_present_cpu(cpu) {
- if (nr >= 8)
- set_cpu_present(cpu, false);
- nr++;
- }
-
- nr = 0;
- for_each_possible_cpu(cpu) {
- if (nr >= 8)
- set_cpu_possible(cpu, false);
- nr++;
- }
-
- set_nr_cpu_ids(8);
- }
-#endif
- preempt_enable();
-}
-
static void __init smp_cpu_index_default(void)
{
int i;
@@ -1243,8 +1208,6 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
{
smp_prepare_cpus_common();
- smp_sanity_check();
-
switch (apic_intr_mode) {
case APIC_PIC:
case APIC_VIRTUAL_WIRE_NO_CONFIG: