]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
x86/apic: Unify interrupt mode setup for SMP-capable system
authorDou Liyang <douly.fnst@cn.fujitsu.com>
Wed, 13 Sep 2017 09:12:48 +0000 (17:12 +0800)
committerThomas Gleixner <tglx@linutronix.de>
Mon, 25 Sep 2017 13:03:15 +0000 (15:03 +0200)
On a SMP-capable system, the kernel enables and sets up the APIC interrupt
delivery mode in native_smp_prepare_cpus(). The decision how to setup the
APIC is intermingled with the decision of setting up SMP or not.

Split the initialization of the APIC interrupt mode independent from other
decisions and have a separate apic_intr_mode_init() function for it.

The invocation time stays the same for now.

Signed-off-by: Dou Liyang <douly.fnst@cn.fujitsu.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: yinghai@kernel.org
Cc: bhe@redhat.com
Link: https://lkml.kernel.org/r/1505293975-26005-6-git-send-email-douly.fnst@cn.fujitsu.com
arch/x86/kernel/apic/apic.c
arch/x86/kernel/smpboot.c

index eafed8fbf340a09bd4871fe15eb1b012e794e6aa..7ae97c26d23ca25caf3c008284f5afe11a139629 100644 (file)
@@ -1221,7 +1221,9 @@ void __init sync_Arb_IDs(void)
 enum apic_intr_mode {
        APIC_PIC,
        APIC_VIRTUAL_WIRE,
+       APIC_VIRTUAL_WIRE_NO_CONFIG,
        APIC_SYMMETRIC_IO,
+       APIC_SYMMETRIC_IO_NO_ROUTING,
 };
 
 static int __init apic_intr_mode_select(void)
@@ -1262,11 +1264,27 @@ static int __init apic_intr_mode_select(void)
        /* Check MP table or ACPI MADT configuration */
        if (!smp_found_config) {
                disable_ioapic_support();
-               if (!acpi_lapic)
+               if (!acpi_lapic) {
                        pr_info("APIC: ACPI MADT or MP tables are not detected\n");
+                       return APIC_VIRTUAL_WIRE_NO_CONFIG;
+               }
                return APIC_VIRTUAL_WIRE;
        }
 
+#ifdef CONFIG_SMP
+       /* If SMP should be disabled, then really disable it! */
+       if (!setup_max_cpus) {
+               pr_info("APIC: SMP mode deactivated\n");
+               return APIC_SYMMETRIC_IO_NO_ROUTING;
+       }
+
+       if (read_apic_id() != boot_cpu_physical_apicid) {
+               panic("Boot APIC ID in local APIC unexpected (%d vs %d)",
+                    read_apic_id(), boot_cpu_physical_apicid);
+               /* Or can we switch back to PIC here? */
+       }
+#endif
+
        return APIC_SYMMETRIC_IO;
 }
 
@@ -1322,17 +1340,31 @@ void __init init_bsp_APIC(void)
 /* Init the interrupt delivery mode for the BSP */
 void __init apic_intr_mode_init(void)
 {
+       bool upmode = false;
+
        switch (apic_intr_mode_select()) {
        case APIC_PIC:
                pr_info("APIC: Keep in PIC mode(8259)\n");
                return;
        case APIC_VIRTUAL_WIRE:
                pr_info("APIC: Switch to virtual wire mode setup\n");
-               return;
+               default_setup_apic_routing();
+               break;
+       case APIC_VIRTUAL_WIRE_NO_CONFIG:
+               pr_info("APIC: Switch to virtual wire mode setup with no configuration\n");
+               upmode = true;
+               default_setup_apic_routing();
+               break;
        case APIC_SYMMETRIC_IO:
                pr_info("APIC: Switch to symmectic I/O mode setup\n");
-               return;
+               default_setup_apic_routing();
+               break;
+       case APIC_SYMMETRIC_IO_NO_ROUTING:
+               pr_info("APIC: Switch to symmectic I/O mode setup in no SMP routine\n");
+               break;
        }
+
+       apic_bsp_setup(upmode);
 }
 
 static void lapic_setup_esr(void)
index d367ddbec5d02e4c14cabeb3b3390c11013e7b5e..d0a1d28c23e81c074197e4302062ae74fc6049f9 100644 (file)
@@ -1336,18 +1336,17 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
 
        set_cpu_sibling_map(0);
 
+       apic_intr_mode_init();
+
        switch (smp_sanity_check(max_cpus)) {
        case SMP_NO_CONFIG:
                disable_smp();
-               if (APIC_init_uniprocessor())
-                       pr_notice("Local APIC not detected. Using dummy APIC emulation.\n");
                return;
        case SMP_NO_APIC:
                disable_smp();
                return;
        case SMP_FORCE_UP:
                disable_smp();
-               apic_bsp_setup(false);
                /* Setup local timer */
                x86_init.timers.setup_percpu_clockev();
                return;
@@ -1355,15 +1354,6 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
                break;
        }
 
-       if (read_apic_id() != boot_cpu_physical_apicid) {
-               panic("Boot APIC ID in local APIC unexpected (%d vs %d)",
-                    read_apic_id(), boot_cpu_physical_apicid);
-               /* Or can we switch back to PIC here? */
-       }
-
-       default_setup_apic_routing();
-       apic_bsp_setup(false);
-
        /* Setup local timer */
        x86_init.timers.setup_percpu_clockev();