lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 29 Mar 2017 22:55:31 +0800
From:   Dou Liyang <douly.fnst@...fujitsu.com>
To:     <x86@...nel.org>, <linux-kernel@...r.kernel.org>
CC:     <tglx@...utronix.de>, <mingo@...nel.org>, <ebiederm@...ssion.com>,
        <bhe@...hat.com>, <hpa@...or.com>, <izumi.taku@...fujitsu.com>,
        Dou Liyang <douly.fnst@...fujitsu.com>
Subject: [RFC PATCH 4/6] x86/apic: Make the APIC mode setup earlier for SMP-capable system

In the SMP-capable system, enable and setup the APIC mode in
native_smp_prepare_boot_cpu() which almost be called at the end
of start_kernel().

The MP table or ACPI has been read earlier, and time_init() which
is called before the APIC mode setup may need the IRQ.

Move the APIC mode setup code to init_IRQ(). Do it at the end of
IRQ initialization for SMP-capable system.

Signed-off-by: Dou Liyang <douly.fnst@...fujitsu.com>
---
 arch/x86/include/asm/apic.h |  3 ++-
 arch/x86/kernel/apic/apic.c | 39 ++++++++++++++++++++++++++++++++-------
 arch/x86/kernel/smpboot.c   | 10 +---------
 3 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index c973f18..be2abc3 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -146,7 +146,8 @@ static inline int apic_force_enable(unsigned long addr)
 extern int apic_force_enable(unsigned long addr);
 #endif
 
-extern int apic_bsp_setup(bool upmode);
+extern int apic_bsp_timer_setup(void);
+extern void apic_bsp_setup(bool upmode);
 extern void apic_ap_setup(void);
 
 /*
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 0ba8a85..ce8f88d 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1157,6 +1157,7 @@ enum apic_bsp_mode {
 	APIC_BSP_MODEL_PIC = 0,
 	APIC_BSP_MODEL_VIRTUAL_WIRE,
 	APIC_BSP_MODEL_SYMMETRIC_IO,
+	APIC_BSP_MODEL_SYMMETRIC_IO_NO_ROUTING,
 	APIC_BSP_MODEL_COUNT
 };
 
@@ -1207,7 +1208,29 @@ static int __init apic_bsp_mode_check(void)
 
 	/* Other checks of ACPI options will be done in each setup function */
 
+#ifdef CONFIG_SMP
+	if (read_apic_id() != boot_cpu_physical_apicid) {
+		pr_info("Boot APIC ID in local APIC unexpected (%d vs %d)",
+			read_apic_id(), boot_cpu_physical_apicid);
+
+		disable_ioapic_support();
+		/*Do nothing, just switch back to PIC here */
+		return APIC_BSP_MODEL_PIC;
+	}
+
+	/*
+	 * If SMP should be disabled, then really disable it!
+	 * No need setup apic routing ?
+	 */
+	if (!setup_max_cpus) {
+		pr_info("SMP mode deactivated\n");
+		return APIC_BSP_MODEL_SYMMETRIC_IO_NO_ROUTING;
+	}
+
 	return APIC_BSP_MODEL_SYMMETRIC_IO;
+#else
+	return APIC_BSP_MODEL_PIC;
+#endif
 }
 
 /*
@@ -1271,6 +1294,12 @@ void __init init_bsp_APIC(void)
 		return;
 	case APIC_BSP_MODEL_SYMMETRIC_IO:
 		pr_info("switch to symmectic I/O model.\n");
+		default_setup_apic_routing();
+		apic_bsp_setup(false);
+		return;
+	case APIC_BSP_MODEL_SYMMETRIC_IO_NO_ROUTING:
+		pr_info("switch to symmectic I/O model with no apic routing.\n");
+		apic_bsp_setup(false);
 		return;
 	}
 }
@@ -2325,7 +2354,7 @@ static void __init apic_bsp_up_setup(void)
 }
 
 /* Setup local APIC timer and get the Id*/
-static int __init apic_bsp_timer_setup(void)
+int __init apic_bsp_timer_setup(void)
 {
 	int id;
 
@@ -2350,10 +2379,8 @@ static int __init apic_bsp_timer_setup(void)
  * Returns:
  * apic_id of BSP APIC
  */
-int __init apic_bsp_setup(bool upmode)
+void __init apic_bsp_setup(bool upmode)
 {
-	int id;
-
 	connect_bsp_APIC();
 	if (upmode)
 		apic_bsp_up_setup();
@@ -2363,9 +2390,6 @@ int __init apic_bsp_setup(bool upmode)
 	end_local_APIC_setup();
 	irq_remap_enable_fault_handling();
 	setup_IO_APIC();
-
-	id = apic_bsp_timer_setup();
-	return id;
 }
 
 /*
@@ -2404,6 +2428,7 @@ int __init APIC_init_uniprocessor(void)
 
 	default_setup_apic_routing();
 	apic_bsp_setup(true);
+	apic_bsp_timer_setup();
 	return 0;
 }
 
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index bd1f1ad..a556281 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1332,20 +1332,12 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
 		return;
 	case SMP_FORCE_UP:
 		disable_smp();
-		apic_bsp_setup(false);
 		return;
 	case SMP_OK:
 		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();
-	cpu0_logical_apicid = apic_bsp_setup(false);
+	cpu0_logical_apicid = apic_bsp_timer_setup();
 
 	pr_info("CPU0: ");
 	print_cpu_info(&cpu_data(0));
-- 
2.5.5



Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ