public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Suresh Siddha <suresh.b.siddha@intel.com>
To: mingo@elte.hu, hpa@zytor.com, tglx@linutronix.de,
	akpm@linux-foundation.org, arjan@linux.intel.com,
	andi@firstfloor.org, ebiederm@xmission.com,
	jbarnes@virtuousgeek.org, steiner@sgi.com
Cc: linux-kernel@vger.kernel.org, Suresh Siddha <suresh.b.siddha@intel.com>
Subject: [patch 24/26] x64, x2apic/intr-remap: add x2apic support, including enabling interrupt-remapping
Date: Thu, 10 Jul 2008 11:16:58 -0700	[thread overview]
Message-ID: <20080710182239.348607000@linux-os.sc.intel.com> (raw)
In-Reply-To: 20080710181634.764954000@linux-os.sc.intel.com

[-- Attachment #1: enable_x2apic.patch --]
[-- Type: text/plain, Size: 9400 bytes --]

x2apic support.  Interrupt-remapping must be enabled before enabling x2apic,
this is needed to ensure that IO interrupts continue to work properly after the
cpu mode is changed to x2apic(which uses 32bit extended physical/cluster
apic id).

On systems where apicid's are > 255, BIOS can handover the control to OS in
x2apic mode. Or if the OS handover was in legacy xapic mode, check
if it is capable of x2apic mode. And if we succeed in enabling
Interrupt-remapping, then we can enable x2apic mode in the CPU.

Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
---

Index: tree-x86/arch/x86/kernel/apic_64.c
===================================================================
--- tree-x86.orig/arch/x86/kernel/apic_64.c	2008-07-10 09:52:31.000000000 -0700
+++ tree-x86/arch/x86/kernel/apic_64.c	2008-07-10 09:52:36.000000000 -0700
@@ -27,6 +27,7 @@
 #include <linux/clockchips.h>
 #include <linux/acpi_pmtmr.h>
 #include <linux/module.h>
+#include <linux/dmar.h>
 
 #include <asm/atomic.h>
 #include <asm/smp.h>
@@ -39,6 +40,7 @@
 #include <asm/proto.h>
 #include <asm/timex.h>
 #include <asm/apic.h>
+#include <asm/i8259.h>
 
 #include <mach_ipi.h>
 #include <mach_apic.h>
@@ -46,8 +48,12 @@
 static int disable_apic_timer __cpuinitdata;
 static int apic_calibrate_pmtmr __initdata;
 int disable_apic;
+int disable_x2apic;
 int x2apic;
 
+/* x2apic enabled before OS handover */
+int x2apic_preenabled;
+
 /* Local APIC timer works in C2 */
 int local_apic_timer_c2_ok;
 EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
@@ -896,6 +902,125 @@
 	apic_pm_activate();
 }
 
+void check_x2apic(void)
+{
+	int msr, msr2;
+
+	rdmsr(MSR_IA32_APICBASE, msr, msr2);
+
+	if (msr & X2APIC_ENABLE) {
+		printk("x2apic enabled by BIOS, switching to x2apic ops\n");
+		x2apic_preenabled = x2apic = 1;
+		apic_ops = &x2apic_ops;
+	}
+}
+
+void enable_x2apic(void)
+{
+	int msr, msr2;
+
+	rdmsr(MSR_IA32_APICBASE, msr, msr2);
+	if (!(msr & X2APIC_ENABLE)) {
+		printk("Enabling x2apic\n");
+		wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0);
+	}
+}
+
+void enable_IR_x2apic(void)
+{
+#ifdef CONFIG_INTR_REMAP
+	int ret;
+	unsigned long flags;
+
+	if (!cpu_has_x2apic)
+		return;
+
+	if (!x2apic_preenabled && disable_x2apic) {
+		printk(KERN_INFO
+		       "Skipped enabling x2apic and Interrupt-remapping "
+		       "because of nox2apic\n");
+		return;
+	}
+
+	if (x2apic_preenabled && disable_x2apic)
+		panic("Bios already enabled x2apic, can't enforce nox2apic");
+
+	if (!x2apic_preenabled && skip_ioapic_setup) {
+		printk(KERN_INFO
+		       "Skipped enabling x2apic and Interrupt-remapping "
+		       "because of skipping io-apic setup\n");
+		return;
+	}
+
+	ret = dmar_table_init();
+	if (ret) {
+		printk(KERN_INFO
+		       "dmar_table_init() failed with %d:\n", ret);
+
+		if (x2apic_preenabled)
+			panic("x2apic enabled by bios. But IR enabling failed");
+		else
+			printk(KERN_INFO
+			       "Not enabling x2apic,Intr-remapping\n");
+		return;
+	}
+
+	local_irq_save(flags);
+	mask_8259A();
+	save_mask_IO_APIC_setup();
+
+	ret = enable_intr_remapping(1);
+
+	if (ret && x2apic_preenabled) {
+		local_irq_restore(flags);
+		panic("x2apic enabled by bios. But IR enabling failed");
+	}
+
+	if (ret)
+		goto end;
+
+	if (!x2apic) {
+		x2apic = 1;
+		apic_ops = &x2apic_ops;
+		enable_x2apic();
+	}
+end:
+	if (ret)
+		/*
+		 * IR enabling failed
+		 */
+		restore_IO_APIC_setup();
+	else
+		reinit_intr_remapped_IO_APIC(x2apic_preenabled);
+
+	unmask_8259A();
+	local_irq_restore(flags);
+
+	if (!ret) {
+		if (!x2apic_preenabled)
+			printk(KERN_INFO
+			       "Enabled x2apic and interrupt-remapping\n");
+		else
+			printk(KERN_INFO
+			       "Enabled Interrupt-remapping\n");
+	} else
+		printk(KERN_ERR
+		       "Failed to enable Interrupt-remapping and x2apic\n");
+#else
+	if (!cpu_has_x2apic)
+		return;
+
+	if (x2apic_preenabled)
+		panic("x2apic enabled prior OS handover,"
+		      " enable CONFIG_INTR_REMAP");
+
+	printk(KERN_INFO "Enable CONFIG_INTR_REMAP for enabling intr-remapping "
+	       " and x2apic\n");
+#endif
+
+	return;
+}
+
 /*
  * Detect and enable local APICs on non-SMP boards.
  * Original code written by Keir Fraser.
@@ -943,6 +1068,11 @@
  */
 void __init init_apic_mappings(void)
 {
+	if (x2apic) {
+		boot_cpu_physical_apicid = GET_APIC_ID(read_apic_id());
+		return;
+	}
+
 	/*
 	 * If no local APIC can be found then set up a fake all
 	 * zeroes page to simulate the local APIC and another
@@ -981,6 +1111,9 @@
 		return -1;
 	}
 
+	enable_IR_x2apic();
+	setup_apic_routing();
+
 	verify_local_APIC();
 
 	connect_bsp_APIC();
@@ -1238,10 +1371,14 @@
 	maxlvt = lapic_get_maxlvt();
 
 	local_irq_save(flags);
-	rdmsr(MSR_IA32_APICBASE, l, h);
-	l &= ~MSR_IA32_APICBASE_BASE;
-	l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr;
-	wrmsr(MSR_IA32_APICBASE, l, h);
+	if (!x2apic) {
+		rdmsr(MSR_IA32_APICBASE, l, h);
+		l &= ~MSR_IA32_APICBASE_BASE;
+		l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr;
+		wrmsr(MSR_IA32_APICBASE, l, h);
+	} else
+		enable_x2apic();
+
 	apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED);
 	apic_write(APIC_ID, apic_pm_state.apic_id);
 	apic_write(APIC_DFR, apic_pm_state.apic_dfr);
@@ -1381,6 +1518,15 @@
 	return (clusters > 2);
 }
 
+static __init int setup_nox2apic(char *str)
+{
+	disable_x2apic = 1;
+	clear_cpu_cap(&boot_cpu_data, X86_FEATURE_X2APIC);
+	return 0;
+}
+early_param("nox2apic", setup_nox2apic);
+
+
 /*
  * APIC command line parameters
  */
Index: tree-x86/arch/x86/kernel/genapic_64.c
===================================================================
--- tree-x86.orig/arch/x86/kernel/genapic_64.c	2008-07-10 09:52:27.000000000 -0700
+++ tree-x86/arch/x86/kernel/genapic_64.c	2008-07-10 09:52:36.000000000 -0700
@@ -16,6 +16,7 @@
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/hardirq.h>
+#include <linux/dmar.h>
 
 #include <asm/smp.h>
 #include <asm/ipi.h>
Index: tree-x86/arch/x86/kernel/setup.c
===================================================================
--- tree-x86.orig/arch/x86/kernel/setup.c	2008-07-10 09:51:44.000000000 -0700
+++ tree-x86/arch/x86/kernel/setup.c	2008-07-10 09:52:36.000000000 -0700
@@ -729,6 +729,8 @@
 	num_physpages = max_pfn;
 
 	check_efer();
+ 	if (cpu_has_x2apic)
+ 		check_x2apic();
 
 	/* How many end-of-memory variables you have, grandma! */
 	/* need this before calling reserve_initrd */
Index: tree-x86/arch/x86/kernel/smpboot.c
===================================================================
--- tree-x86.orig/arch/x86/kernel/smpboot.c	2008-07-10 09:52:14.000000000 -0700
+++ tree-x86/arch/x86/kernel/smpboot.c	2008-07-10 09:52:36.000000000 -0700
@@ -1145,6 +1145,11 @@
 	current_thread_info()->cpu = 0;  /* needed? */
 	set_cpu_sibling_map(0);
 
+#ifdef CONFIG_X86_64
+	enable_IR_x2apic();
+	setup_apic_routing();
+#endif
+
 	if (smp_sanity_check(max_cpus) < 0) {
 		printk(KERN_INFO "SMP disabled\n");
 		disable_smp();
Index: tree-x86/arch/x86/kernel/acpi/boot.c
===================================================================
--- tree-x86.orig/arch/x86/kernel/acpi/boot.c	2008-07-10 09:51:44.000000000 -0700
+++ tree-x86/arch/x86/kernel/acpi/boot.c	2008-07-10 09:52:36.000000000 -0700
@@ -1347,7 +1347,9 @@
 				acpi_ioapic = 1;
 
 				smp_found_config = 1;
+#ifdef CONFIG_X86_32
 				setup_apic_routing();
+#endif
 			}
 		}
 		if (error == -EINVAL) {
Index: tree-x86/arch/x86/kernel/cpu/common_64.c
===================================================================
--- tree-x86.orig/arch/x86/kernel/cpu/common_64.c	2008-07-10 09:51:44.000000000 -0700
+++ tree-x86/arch/x86/kernel/cpu/common_64.c	2008-07-10 09:52:36.000000000 -0700
@@ -603,6 +603,8 @@
 	barrier();
 
 	check_efer();
+	if (cpu != 0 && x2apic)
+		enable_x2apic();
 
 	/*
 	 * set up and load the per-CPU TSS
Index: tree-x86/arch/x86/kernel/mpparse.c
===================================================================
--- tree-x86.orig/arch/x86/kernel/mpparse.c	2008-07-10 09:51:44.000000000 -0700
+++ tree-x86/arch/x86/kernel/mpparse.c	2008-07-10 09:52:36.000000000 -0700
@@ -545,7 +545,9 @@
        generic_bigsmp_probe();
 #endif
 
+#ifdef CONFIG_X86_32
 	setup_apic_routing();
+#endif
 	if (!num_processors)
 		printk(KERN_ERR "MPTABLE: no processors registered!\n");
 	return num_processors;
Index: tree-x86/Documentation/kernel-parameters.txt
===================================================================
--- tree-x86.orig/Documentation/kernel-parameters.txt	2008-07-10 09:51:44.000000000 -0700
+++ tree-x86/Documentation/kernel-parameters.txt	2008-07-10 09:52:36.000000000 -0700
@@ -1377,6 +1377,8 @@
 
 	nolapic_timer	[X86-32,APIC] Do not use the local APIC timer.
 
+	nox2apic	[X86-64,APIC] Do not enable x2APIC mode.
+
 	noltlbs		[PPC] Do not use large page/tlb entries for kernel
 			lowmem mapping on PPC40x.
 
Index: tree-x86/include/asm-x86/apic.h
===================================================================
--- tree-x86.orig/include/asm-x86/apic.h	2008-07-10 09:52:31.000000000 -0700
+++ tree-x86/include/asm-x86/apic.h	2008-07-10 09:52:36.000000000 -0700
@@ -100,6 +100,11 @@
 extern u32 safe_apic_wait_icr_idle(void);
 extern void apic_icr_write(u32 low, u32 id);
 #else
+extern int x2apic, x2apic_preenabled;
+extern void check_x2apic(void);
+extern void enable_x2apic(void);
+extern void enable_IR_x2apic(void);
+extern void x2apic_icr_write(u32 low, u32 id);
 
 struct apic_ops {
 	u32 (*read)(u32 reg);

-- 


  parent reply	other threads:[~2008-07-10 18:46 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-10 18:16 [patch 00/26] x64, x2apic/intr-remap: Interrupt-remapping and x2apic support Suresh Siddha
2008-07-10 18:16 ` [patch 01/26] x64, x2apic/intr-remap: Intel vt-d, IOMMU code reorganization Suresh Siddha
2008-07-10 18:16 ` [patch 02/26] x64, x2apic/intr-remap: fix the need for sequential array allocation of iommus Suresh Siddha
2008-07-10 18:16 ` [patch 03/26] x64, x2apic/intr-remap: code re-structuring, to be used by both DMA and Interrupt remapping Suresh Siddha
2008-07-10 18:16 ` [patch 04/26] x64, x2apic/intr-remap: use CONFIG_DMAR for DMA-remapping specific code Suresh Siddha
2008-07-10 18:16 ` [patch 05/26] x64, x2apic/intr-remap: Fix the need for RMRR in the DMA-remapping detection Suresh Siddha
2008-07-10 18:16 ` [patch 06/26] x64, x2apic/intr-remap: parse ioapic scope under vt-d structures Suresh Siddha
2008-07-10 18:16 ` [patch 07/26] x64, x2apic/intr-remap: move IOMMU_WAIT_OP() macro to intel-iommu.h Suresh Siddha
2008-07-10 18:16 ` [patch 08/26] x64, x2apic/intr-remap: Queued invalidation infrastructure (part of VT-d) Suresh Siddha
2008-07-10 18:16 ` [patch 09/26] x64, x2apic/intr-remap: Interrupt remapping infrastructure Suresh Siddha
2008-07-10 18:16 ` [patch 10/26] x64, x2apic/intr-remap: routines managing Interrupt remapping table entries Suresh Siddha
2008-07-10 18:16 ` [patch 11/26] x64, x2apic/intr-remap: generic irq migration support from process context Suresh Siddha
2008-07-10 23:08   ` Eric W. Biederman
2008-07-11  5:41     ` Suresh Siddha
2008-07-11  9:19       ` Eric W. Biederman
2008-07-10 18:16 ` [patch 12/26] x64, x2apic/intr-remap: 8259 specific mask/unmask routines Suresh Siddha
2008-07-10 18:16 ` [patch 13/26] x64, x2apic/intr-remap: ioapic routines which deal with initial io-apic RTE setup Suresh Siddha
2008-07-10 18:16 ` [patch 14/26] x64, x2apic/intr-remap: introduce read_apic_id() to genapic routines Suresh Siddha
2008-07-10 18:16 ` [patch 15/26] x64, x2apic/intr-remap: basic apic ops support Suresh Siddha
2008-07-10 18:16 ` [patch 16/26] x64, x2apic/intr-remap: cpuid bits for x2apic feature Suresh Siddha
2008-07-10 18:16 ` [patch 17/26] x64, x2apic/intr-remap: disable DMA-remapping if Interrupt-remapping is detected (temporary quirk) Suresh Siddha
2008-07-10 18:16 ` [patch 18/26] x64, x2apic/intr-remap: x2apic ops for x2apic mode support Suresh Siddha
2008-07-10 18:16 ` [patch 19/26] x64, x2apic/intr-remap: introcude self IPI to genapic routines Suresh Siddha
2008-07-10 23:34   ` Eric W. Biederman
2008-07-11  2:29     ` Mike Travis
2008-07-11  3:50       ` Eric W. Biederman
2008-07-11 13:55         ` Mike Travis
2008-07-10 18:16 ` [patch 20/26] x64, x2apic/intr-remap: x2apic cluster mode support Suresh Siddha
2008-07-10 18:16 ` [patch 21/26] x64, x2apic/intr-remap: setup init_apic_ldr for UV Suresh Siddha
2008-07-11  0:14   ` Andrew Morton
2008-07-11  1:56     ` Suresh Siddha
2008-07-10 18:16 ` [patch 22/26] x64, x2apic/intr-remap: IO-APIC support for interrupt-remapping Suresh Siddha
2008-07-10 18:16 ` [patch 23/26] x64, x2apic/intr-remap: MSI and MSI-X support for interrupt remapping infrastructure Suresh Siddha
2008-07-11  1:22   ` Eric W. Biederman
2008-07-11  6:07     ` Suresh Siddha
2008-07-11  8:59       ` Eric W. Biederman
2008-07-11 23:07         ` Suresh Siddha
2008-07-11 23:50           ` Eric W. Biederman
2008-07-10 18:16 ` Suresh Siddha [this message]
2008-07-10 18:16 ` [patch 25/26] x64, x2apic/intr-remap: support for x2apic physical mode support Suresh Siddha
2008-07-10 18:17 ` [patch 26/26] x64, x2apic/intr-remap: introduce CONFIG_INTR_REMAP Suresh Siddha
2008-07-10 23:29   ` Eric W. Biederman
2008-07-10 23:37     ` Yong Wang
2008-07-11  1:50       ` Suresh Siddha
2008-07-11  1:53       ` Eric W. Biederman
2008-07-10 19:53 ` [patch 00/26] x64, x2apic/intr-remap: Interrupt-remapping and x2apic support Ingo Molnar
2008-07-10 20:22   ` Suresh Siddha
2008-07-10 21:56   ` Suresh Siddha
2008-07-11 10:28     ` Ingo Molnar
2008-07-11 20:09       ` Ingo Molnar
2008-07-11 20:31         ` Suresh Siddha
2008-07-11 20:42           ` Yinghai Lu
2008-07-11 20:45             ` Ingo Molnar
2008-07-11 21:24               ` Suresh Siddha
2008-07-11 22:02                 ` Yinghai Lu
2008-07-12  3:16                   ` Yinghai Lu
2008-07-12  3:52                     ` Eric W. Biederman
2008-07-12  6:17                       ` Yinghai Lu
2008-07-12  7:02                         ` Eric W. Biederman
2008-07-12  7:49                           ` Yinghai Lu
2008-07-12  8:11                             ` Eric W. Biederman
2008-07-12  8:37                               ` Yinghai Lu
2008-07-12  9:46                                 ` Eric W. Biederman
2008-07-13  1:02                                 ` Suresh Siddha
2008-07-13  1:01                             ` Suresh Siddha
2008-07-13  1:32                           ` Suresh Siddha
2008-07-13  1:00                         ` Suresh Siddha
2008-07-13  0:55                     ` Suresh Siddha
2008-07-12  5:37                   ` Ingo Molnar
2008-07-12  6:06                     ` Yinghai Lu
2008-07-12  6:45                       ` Ingo Molnar
2008-07-11 20:49           ` Ingo Molnar
2008-07-16 14:37   ` Yong Wang
2008-07-16 14:53     ` Ingo Molnar
2008-07-22 20:49   ` Andrew Morton
2008-07-22 21:00     ` Mike Travis
2008-07-22 21:14       ` Andrew Morton
2008-07-24  5:03       ` Ingo Molnar
2008-07-10 20:05 ` Eric W. Biederman
2008-07-10 20:18   ` Ingo Molnar
2008-07-10 21:07     ` Eric W. Biederman
2008-07-10 21:15   ` Suresh Siddha
2008-07-10 22:52     ` Eric W. Biederman
2008-07-11  2:35       ` Suresh Siddha
2008-07-11  3:15         ` Eric W. Biederman
2008-07-10 22:09   ` Arjan van de Ven
2008-07-10 22:54     ` Eric W. Biederman

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=20080710182239.348607000@linux-os.sc.intel.com \
    --to=suresh.b.siddha@intel.com \
    --cc=akpm@linux-foundation.org \
    --cc=andi@firstfloor.org \
    --cc=arjan@linux.intel.com \
    --cc=ebiederm@xmission.com \
    --cc=hpa@zytor.com \
    --cc=jbarnes@virtuousgeek.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=steiner@sgi.com \
    --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