mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Yinghai Lu <yinghai@kernel.org>
To: Ingo Molnar <mingo@elte.hu>, Thomas Gleixner <tglx@linutronix.de>,
	"H. Peter Anvin" <hpa@zytor.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Len Brown <lenb@kernel.org>,
	linux-kernel@vger.kernel.org, Yinghai Lu <yinghai@kernel.org>
Subject: [PATCH 15/15] x86: Disabling x2apic if nox2apic is specified
Date: Sat, 23 Oct 2010 18:02:29 -0700	[thread overview]
Message-ID: <1287882149-29275-16-git-send-email-yinghai@kernel.org> (raw)
In-Reply-To: <1287882149-29275-1-git-send-email-yinghai@kernel.org>

For
1. x2apic preenabled system
2. first kernel have x2apic enabled, and try to boot second kernel with "nox2apic"

Will put back cpu with apic id < 255 into xapic mode, instead of panic.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/apic.h    |    6 ++++
 arch/x86/include/asm/apicdef.h |    1 +
 arch/x86/kernel/acpi/boot.c    |   10 ++++++-
 arch/x86/kernel/apic/apic.c    |   54 +++++++++++++++++++++++++++++++--------
 arch/x86/mm/srat_64.c          |   12 ++++++++-
 5 files changed, 69 insertions(+), 14 deletions(-)

diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 69879dd..522f39b 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -176,6 +176,7 @@ static inline u64 native_x2apic_icr_read(void)
 }
 
 extern int x2apic_phys;
+extern int nox2apic;
 extern void check_x2apic(void);
 extern void enable_x2apic(void);
 extern void x2apic_icr_write(u32 low, u32 id);
@@ -186,6 +187,10 @@ static inline int x2apic_enabled(void)
 	if (!cpu_has_x2apic)
 		return 0;
 
+	/* avoid to read msr */
+	if (nox2apic)
+		return 0;
+
 	rdmsr(MSR_IA32_APICBASE, msr, msr2);
 	if (msr & X2APIC_ENABLE)
 		return 1;
@@ -214,6 +219,7 @@ static inline void x2apic_force_phys(void)
 
 #define	x2apic_preenabled 0
 #define	x2apic_supported()	0
+#define	nox2apic	1
 #endif
 
 extern void enable_IR_x2apic(void);
diff --git a/arch/x86/include/asm/apicdef.h b/arch/x86/include/asm/apicdef.h
index a859ca4..f28feba 100644
--- a/arch/x86/include/asm/apicdef.h
+++ b/arch/x86/include/asm/apicdef.h
@@ -141,6 +141,7 @@
 
 #define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
 #define APIC_BASE_MSR	0x800
+#define XAPIC_ENABLE	(1UL << 11)
 #define X2APIC_ENABLE	(1UL << 10)
 
 #ifdef CONFIG_X86_32
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 8e13ec8..5a4e67e 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -213,6 +213,8 @@ static int __init
 acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)
 {
 	struct acpi_madt_local_x2apic *processor = NULL;
+	int apic_id;
+	u8 enabled;
 
 	processor = (struct acpi_madt_local_x2apic *)header;
 
@@ -221,6 +223,8 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)
 
 	acpi_table_print_madt_entry(header);
 
+	apic_id = processor->local_apic_id;
+	enabled = processor->lapic_flags & ACPI_MADT_ENABLED;
 #ifdef CONFIG_X86_X2APIC
 	/*
 	 * We need to register disabled CPU as well to permit
@@ -229,8 +233,10 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)
 	 * to not preallocating memory for all NR_CPUS
 	 * when we use CPU hotplug.
 	 */
-	acpi_register_lapic(processor->local_apic_id,	/* APIC ID */
-			    processor->lapic_flags & ACPI_MADT_ENABLED);
+	if (nox2apic && (apic_id >= 0xff) && enabled)
+		printk(KERN_WARNING PREFIX "x2apic entry ignored\n");
+	else
+		acpi_register_lapic(apic_id, enabled);
 #else
 	printk(KERN_WARNING PREFIX "x2apic entry ignored\n");
 #endif
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index d286db1..ebb13e8 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -138,15 +138,14 @@ int x2apic_mode;
 #ifdef CONFIG_X86_X2APIC
 /* x2apic enabled before OS handover */
 static int x2apic_preenabled;
+int nox2apic;
 static __init int setup_nox2apic(char *str)
 {
-	if (x2apic_enabled()) {
-		pr_warning("Bios already enabled x2apic, "
-			   "can't enforce nox2apic");
-		return 0;
-	}
+	if (x2apic_enabled())
+		pr_warning("Bios already enabled x2apic, will disable it");
+
+	nox2apic = 1;
 
-	setup_clear_cpu_cap(X86_FEATURE_X2APIC);
 	return 0;
 }
 early_param("nox2apic", setup_nox2apic);
@@ -1393,8 +1392,33 @@ void __cpuinit end_local_APIC_setup(void)
 }
 
 #ifdef CONFIG_X86_X2APIC
+
+static void disable_x2apic(void)
+{
+	int msr, msr2;
+
+	if (!cpu_has_x2apic)
+		return;
+
+	rdmsr(MSR_IA32_APICBASE, msr, msr2);
+	if (msr & X2APIC_ENABLE) {
+		pr_info("Disabling x2apic\n");
+		/*
+		 * Need to disable xapic and x2apic at the same time at first
+		 *  then enable xapic
+		 */
+		wrmsr(MSR_IA32_APICBASE, msr & ~(X2APIC_ENABLE | XAPIC_ENABLE),
+			 0);
+		wrmsr(MSR_IA32_APICBASE, msr & ~X2APIC_ENABLE, 0);
+	}
+}
 void check_x2apic(void)
 {
+	if (nox2apic) {
+		disable_x2apic();
+		return;
+	}
+
 	if (x2apic_enabled()) {
 		pr_info("x2apic enabled by BIOS, switching to x2apic ops\n");
 		x2apic_preenabled = x2apic_mode = 1;
@@ -1405,6 +1429,11 @@ void enable_x2apic(void)
 {
 	int msr, msr2;
 
+	if (nox2apic) {
+		disable_x2apic();
+		return;
+	}
+
 	if (!x2apic_mode)
 		return;
 
@@ -1430,7 +1459,7 @@ int __init enable_IR(void)
 		return 0;
 	}
 
-	if (enable_intr_remapping(x2apic_supported()))
+	if (enable_intr_remapping(x2apic_supported() && !nox2apic))
 		return 0;
 
 	pr_info("Enabled Interrupt-remapping\n");
@@ -1449,7 +1478,7 @@ void __init enable_IR_x2apic(void)
 	int dmar_table_init_ret;
 
 	dmar_table_init_ret = dmar_table_init();
-	if (dmar_table_init_ret && !x2apic_supported())
+	if (dmar_table_init_ret && (!x2apic_supported() || nox2apic))
 		return;
 
 	ioapic_entries = alloc_ioapic_entries();
@@ -1473,12 +1502,15 @@ void __init enable_IR_x2apic(void)
 	else
 		ret = enable_IR();
 
+	if (nox2apic)
+		goto without_x2apic;
+
 	if (!ret) {
 		/* IR is required if there is APIC ID > 255 even when running
 		 * under KVM
 		 */
 		if (max_physical_apicid > 255 || !kvm_para_available())
-			goto nox2apic;
+			goto without_x2apic;
 		/*
 		 * without IR all CPUs can be addressed by IOAPIC/MSI
 		 * only in physical mode
@@ -1494,7 +1526,7 @@ void __init enable_IR_x2apic(void)
 		pr_info("Enabled x2apic\n");
 	}
 
-nox2apic:
+without_x2apic:
 	if (!ret) /* IR enabling failed */
 		restore_IO_APIC_setup(ioapic_entries);
 	legacy_pic->restore_mask();
@@ -1509,7 +1541,7 @@ out:
 
 	if (x2apic_preenabled)
 		panic("x2apic: enabled by BIOS but kernel init failed.");
-	else if (cpu_has_x2apic)
+	else if (cpu_has_x2apic && !nox2apic)
 		pr_info("Not enabling x2apic, Intr-remapping init failed.\n");
 }
 
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
index a35cb9d..baa9eab 100644
--- a/arch/x86/mm/srat_64.c
+++ b/arch/x86/mm/srat_64.c
@@ -126,6 +126,13 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
 	if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0)
 		return;
 	pxm = pa->proximity_domain;
+	apic_id = pa->apic_id;
+#ifdef CONFIG_X86_X2APIC
+	if (nox2apic && (apic_id >= 0xff)) {
+		printk(KERN_INFO "SRAT: PXM %u -> X2APIC 0x%04x ignored\n",
+			 pxm, apic_id);
+		return;
+	}
 	node = setup_node(pxm);
 	if (node < 0) {
 		printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
@@ -133,12 +140,15 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
 		return;
 	}
 
-	apic_id = pa->apic_id;
 	apicid_to_node[apic_id] = node;
 	node_set(node, cpu_nodes_parsed);
 	acpi_numa = 1;
 	printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u\n",
 	       pxm, apic_id, node);
+#else
+	printk(KERN_INFO "SRAT: PXM %u -> X2APIC 0x%04x ignored\n",
+		 pxm, apic_id);
+#endif
 }
 
 /* Callback for Proximity Domain -> LAPIC mapping */
-- 
1.7.1


  parent reply	other threads:[~2010-10-24  1:05 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-10-24  1:02 [PATCH 00/15] x86: APIC related clean up Yinghai Lu
2010-10-24  1:02 ` [PATCH 01/15] x86, apic: Don't write io_apic ID if it is not changed Yinghai Lu
2010-10-24  1:02 ` [PATCH 02/15] x86, apic: Fix lapic mapping with construct ISA and visws mptable path Yinghai Lu
2010-10-24  9:47   ` Thomas Gleixner
2010-10-24  1:02 ` [PATCH 03/15] x86, apic: Merge two register_lapic_address() Yinghai Lu
2010-10-24  9:49   ` Thomas Gleixner
2010-10-24  1:02 ` [PATCH 04/15] x86, apic: Remove early_init_lapic_mapping Yinghai Lu
2010-10-24  9:53   ` Thomas Gleixner
2010-10-24  1:02 ` [PATCH 05/15] x86: Call smp_register_lapic_address for contruct_default mptable path Yinghai Lu
2010-10-24  1:02 ` [PATCH 06/15] x86, apic: Use smp_register_lapic_address in init_apic_mapping Yinghai Lu
2010-10-24  1:02 ` [PATCH 07/15] x86, sfi: Use smp_register_lapic_address() Yinghai Lu
2010-10-24  9:56   ` Thomas Gleixner
2010-10-24  1:02 ` [PATCH 08/15] x86, visws: Set_fixmap in find_smp_config Yinghai Lu
2010-10-24  9:58   ` Thomas Gleixner
2010-10-24  1:02 ` [PATCH 09/15] x86: on !find_smp_config path use smp_register_lapic_address Yinghai Lu
2010-10-24 10:01   ` Thomas Gleixner
2010-10-24  1:02 ` [PATCH 10/15] x86, apic: Set fixmap only one time Yinghai Lu
2010-10-24 10:03   ` Thomas Gleixner
2010-10-24  1:02 ` [PATCH 11/15] x86, ioapic: Only print mapping for ioapic in right place Yinghai Lu
2010-10-25 16:55   ` [PATCH] x86, ioapic: Add debug printing when mapping for ioapic Yinghai Lu
2010-10-25 16:59     ` [PATCH] x86, ioapic: Don't map ioapic regs two times Yinghai Lu
2010-10-24  1:02 ` [PATCH 12/15] x86, x2apic: Don't map lapic addr for preenabled x2apic Yinghai Lu
2010-10-24  1:02 ` [PATCH 13/15] x86, apic, acpi: Handle xapic/x2apic entries in MADT at same time Yinghai Lu
2010-10-24  9:44   ` Thomas Gleixner
2010-10-24  1:02 ` [PATCH 14/15] acpi: Reverse uid and apic_id print out for x2apic Yinghai Lu
2010-10-24  1:02 ` Yinghai Lu [this message]
2010-10-24 10:15   ` [PATCH 15/15] x86: Disabling x2apic if nox2apic is specified Thomas Gleixner
2010-10-24 22:09     ` Yinghai Lu
2010-10-25 17:50       ` Suresh Siddha
2010-10-27  6:27         ` [PATCH -v3] x86: Disable " Yinghai Lu
2010-10-29  5:53           ` Suresh Siddha
2010-10-29  7:26             ` Yinghai Lu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1287882149-29275-16-git-send-email-yinghai@kernel.org \
    --to=yinghai@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=hpa@zytor.com \
    --cc=lenb@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome