aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/Kconfig15
-rw-r--r--arch/x86/include/asm/apic.h18
-rw-r--r--arch/x86/kernel/Makefile4
-rw-r--r--arch/x86/kernel/apic.c24
-rw-r--r--arch/x86/kernel/cpu/common.c2
-rw-r--r--arch/x86/kernel/genapic_64.c4
-rw-r--r--arch/x86/kernel/setup.c3
-rw-r--r--arch/x86/kernel/smpboot.c2
8 files changed, 51 insertions, 21 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 1042d69b267d..bce241fe1d2d 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -235,6 +235,20 @@ config SMP
235 235
236 If you don't know what to do here, say N. 236 If you don't know what to do here, say N.
237 237
238config X86_X2APIC
239 bool "Support x2apic"
240 depends on X86_LOCAL_APIC && X86_64
241 ---help---
242 This enables x2apic support on CPUs that have this feature.
243
244 This allows 32-bit apic IDs (so it can support very large systems),
245 and accesses the local apic via MSRs not via mmio.
246
247 ( On certain CPU models you may need to enable INTR_REMAP too,
248 to get functional x2apic mode. )
249
250 If you don't know what to do here, say N.
251
238config SPARSE_IRQ 252config SPARSE_IRQ
239 bool "Support sparse irq numbering" 253 bool "Support sparse irq numbering"
240 depends on PCI_MSI || HT_IRQ 254 depends on PCI_MSI || HT_IRQ
@@ -1828,6 +1842,7 @@ config DMAR_FLOPPY_WA
1828config INTR_REMAP 1842config INTR_REMAP
1829 bool "Support for Interrupt Remapping (EXPERIMENTAL)" 1843 bool "Support for Interrupt Remapping (EXPERIMENTAL)"
1830 depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL 1844 depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL
1845 select X86_X2APIC
1831 ---help--- 1846 ---help---
1832 Supports Interrupt remapping for IO-APIC and MSI devices. 1847 Supports Interrupt remapping for IO-APIC and MSI devices.
1833 To use x2apic mode in the CPU's which support x2APIC enhancements or 1848 To use x2apic mode in the CPU's which support x2APIC enhancements or
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index fba49f66228f..dc1db99cd40e 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -112,7 +112,7 @@ static inline u32 native_apic_msr_read(u32 reg)
112 return low; 112 return low;
113} 113}
114 114
115#ifndef CONFIG_X86_32 115#ifdef CONFIG_X86_X2APIC
116extern int x2apic; 116extern int x2apic;
117extern void check_x2apic(void); 117extern void check_x2apic(void);
118extern void enable_x2apic(void); 118extern void enable_x2apic(void);
@@ -131,7 +131,19 @@ static inline int x2apic_enabled(void)
131 return 0; 131 return 0;
132} 132}
133#else 133#else
134#define x2apic_enabled() 0 134static inline void check_x2apic(void)
135{
136}
137static inline void enable_x2apic(void)
138{
139}
140static inline void enable_IR_x2apic(void)
141{
142}
143static inline int x2apic_enabled(void)
144{
145 return 0;
146}
135#endif 147#endif
136 148
137struct apic_ops { 149struct apic_ops {
@@ -177,7 +189,7 @@ static inline u32 safe_apic_wait_icr_idle(void)
177 189
178extern int get_physical_broadcast(void); 190extern int get_physical_broadcast(void);
179 191
180#ifdef CONFIG_X86_64 192#ifdef CONFIG_X86_X2APIC
181static inline void ack_x2APIC_irq(void) 193static inline void ack_x2APIC_irq(void)
182{ 194{
183 /* Docs say use 0 for future compatibility */ 195 /* Docs say use 0 for future compatibility */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 24f357e7557a..1cefd218f764 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -117,8 +117,8 @@ obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o # NB rename without _64
117# 64 bit specific files 117# 64 bit specific files
118ifeq ($(CONFIG_X86_64),y) 118ifeq ($(CONFIG_X86_64),y)
119 obj-y += genapic_64.o genapic_flat_64.o 119 obj-y += genapic_64.o genapic_flat_64.o
120 obj-y += genx2apic_cluster.o 120 obj-$(CONFIG_X86_X2APIC) += genx2apic_cluster.o
121 obj-y += genx2apic_phys.o 121 obj-$(CONFIG_X86_X2APIC) += genx2apic_phys.o
122 obj-$(CONFIG_X86_UV) += genx2apic_uv_x.o tlb_uv.o 122 obj-$(CONFIG_X86_UV) += genx2apic_uv_x.o tlb_uv.o
123 obj-$(CONFIG_X86_UV) += bios_uv.o uv_irq.o uv_sysfs.o 123 obj-$(CONFIG_X86_UV) += bios_uv.o uv_irq.o uv_sysfs.o
124 obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o 124 obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o
diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c
index a894eea9d51a..004aa1c31e4f 100644
--- a/arch/x86/kernel/apic.c
+++ b/arch/x86/kernel/apic.c
@@ -112,11 +112,7 @@ static __init int setup_apicpmtimer(char *s)
112__setup("apicpmtimer", setup_apicpmtimer); 112__setup("apicpmtimer", setup_apicpmtimer);
113#endif 113#endif
114 114
115#ifdef CONFIG_X86_64 115#ifdef CONFIG_X86_X2APIC
116#define HAVE_X2APIC
117#endif
118
119#ifdef HAVE_X2APIC
120int x2apic; 116int x2apic;
121/* x2apic enabled before OS handover */ 117/* x2apic enabled before OS handover */
122static int x2apic_preenabled; 118static int x2apic_preenabled;
@@ -269,7 +265,7 @@ static struct apic_ops xapic_ops = {
269struct apic_ops __read_mostly *apic_ops = &xapic_ops; 265struct apic_ops __read_mostly *apic_ops = &xapic_ops;
270EXPORT_SYMBOL_GPL(apic_ops); 266EXPORT_SYMBOL_GPL(apic_ops);
271 267
272#ifdef HAVE_X2APIC 268#ifdef CONFIG_X86_X2APIC
273static void x2apic_wait_icr_idle(void) 269static void x2apic_wait_icr_idle(void)
274{ 270{
275 /* no need to wait for icr idle in x2apic */ 271 /* no need to wait for icr idle in x2apic */
@@ -1320,11 +1316,14 @@ void __cpuinit end_local_APIC_setup(void)
1320 apic_pm_activate(); 1316 apic_pm_activate();
1321} 1317}
1322 1318
1323#ifdef HAVE_X2APIC 1319#ifdef CONFIG_X86_X2APIC
1324void check_x2apic(void) 1320void check_x2apic(void)
1325{ 1321{
1326 int msr, msr2; 1322 int msr, msr2;
1327 1323
1324 if (!cpu_has_x2apic)
1325 return;
1326
1328 rdmsr(MSR_IA32_APICBASE, msr, msr2); 1327 rdmsr(MSR_IA32_APICBASE, msr, msr2);
1329 1328
1330 if (msr & X2APIC_ENABLE) { 1329 if (msr & X2APIC_ENABLE) {
@@ -1338,6 +1337,9 @@ void enable_x2apic(void)
1338{ 1337{
1339 int msr, msr2; 1338 int msr, msr2;
1340 1339
1340 if (!x2apic)
1341 return;
1342
1341 rdmsr(MSR_IA32_APICBASE, msr, msr2); 1343 rdmsr(MSR_IA32_APICBASE, msr, msr2);
1342 if (!(msr & X2APIC_ENABLE)) { 1344 if (!(msr & X2APIC_ENABLE)) {
1343 pr_info("Enabling x2apic\n"); 1345 pr_info("Enabling x2apic\n");
@@ -1439,7 +1441,7 @@ end:
1439 1441
1440 return; 1442 return;
1441} 1443}
1442#endif /* HAVE_X2APIC */ 1444#endif /* CONFIG_X86_X2APIC */
1443 1445
1444#ifdef CONFIG_X86_64 1446#ifdef CONFIG_X86_64
1445/* 1447/*
@@ -1570,7 +1572,7 @@ void __init early_init_lapic_mapping(void)
1570 */ 1572 */
1571void __init init_apic_mappings(void) 1573void __init init_apic_mappings(void)
1572{ 1574{
1573#ifdef HAVE_X2APIC 1575#ifdef CONFIG_X86_X2APIC
1574 if (x2apic) { 1576 if (x2apic) {
1575 boot_cpu_physical_apicid = read_apic_id(); 1577 boot_cpu_physical_apicid = read_apic_id();
1576 return; 1578 return;
@@ -1634,9 +1636,7 @@ int __init APIC_init_uniprocessor(void)
1634 } 1636 }
1635#endif 1637#endif
1636 1638
1637#ifdef HAVE_X2APIC
1638 enable_IR_x2apic(); 1639 enable_IR_x2apic();
1639#endif
1640#ifdef CONFIG_X86_64 1640#ifdef CONFIG_X86_64
1641 default_setup_apic_routing(); 1641 default_setup_apic_routing();
1642#endif 1642#endif
@@ -2021,7 +2021,7 @@ static int lapic_resume(struct sys_device *dev)
2021 2021
2022 local_irq_save(flags); 2022 local_irq_save(flags);
2023 2023
2024#ifdef HAVE_X2APIC 2024#ifdef CONFIG_X86_X2APIC
2025 if (x2apic) 2025 if (x2apic)
2026 enable_x2apic(); 2026 enable_x2apic();
2027 else 2027 else
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 4db150ed446d..4b5d13e472d6 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1051,7 +1051,7 @@ void __cpuinit cpu_init(void)
1051 barrier(); 1051 barrier();
1052 1052
1053 check_efer(); 1053 check_efer();
1054 if (cpu != 0 && x2apic) 1054 if (cpu != 0)
1055 enable_x2apic(); 1055 enable_x2apic();
1056 1056
1057 /* 1057 /*
diff --git a/arch/x86/kernel/genapic_64.c b/arch/x86/kernel/genapic_64.c
index 820dea5d0ebe..cdc4772d9c87 100644
--- a/arch/x86/kernel/genapic_64.c
+++ b/arch/x86/kernel/genapic_64.c
@@ -35,8 +35,10 @@ static struct genapic *apic_probe[] __initdata = {
35#ifdef CONFIG_X86_UV 35#ifdef CONFIG_X86_UV
36 &apic_x2apic_uv_x, 36 &apic_x2apic_uv_x,
37#endif 37#endif
38#ifdef CONFIG_X86_X2APIC
38 &apic_x2apic_phys, 39 &apic_x2apic_phys,
39 &apic_x2apic_cluster, 40 &apic_x2apic_cluster,
41#endif
40 &apic_physflat, 42 &apic_physflat,
41 NULL, 43 NULL,
42}; 44};
@@ -46,10 +48,12 @@ static struct genapic *apic_probe[] __initdata = {
46 */ 48 */
47void __init default_setup_apic_routing(void) 49void __init default_setup_apic_routing(void)
48{ 50{
51#ifdef CONFIG_X86_X2APIC
49 if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) { 52 if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) {
50 if (!intr_remapping_enabled) 53 if (!intr_remapping_enabled)
51 apic = &apic_flat; 54 apic = &apic_flat;
52 } 55 }
56#endif
53 57
54 if (apic == &apic_flat) { 58 if (apic == &apic_flat) {
55 if (max_physical_apicid >= 8) 59 if (max_physical_apicid >= 8)
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 8fce6c714514..43d964411c0d 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -836,8 +836,7 @@ void __init setup_arch(char **cmdline_p)
836#else 836#else
837 num_physpages = max_pfn; 837 num_physpages = max_pfn;
838 838
839 if (cpu_has_x2apic) 839 check_x2apic();
840 check_x2apic();
841 840
842 /* How many end-of-memory variables you have, grandma! */ 841 /* How many end-of-memory variables you have, grandma! */
843 /* need this before calling reserve_initrd */ 842 /* need this before calling reserve_initrd */
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 10834954e301..b5f2b698973f 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1128,8 +1128,8 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
1128 current_thread_info()->cpu = 0; /* needed? */ 1128 current_thread_info()->cpu = 0; /* needed? */
1129 set_cpu_sibling_map(0); 1129 set_cpu_sibling_map(0);
1130 1130
1131#ifdef CONFIG_X86_64
1132 enable_IR_x2apic(); 1131 enable_IR_x2apic();
1132#ifdef CONFIG_X86_64
1133 default_setup_apic_routing(); 1133 default_setup_apic_routing();
1134#endif 1134#endif
1135 1135