diff options
-rw-r--r-- | arch/x86/Kconfig | 15 | ||||
-rw-r--r-- | arch/x86/include/asm/apic.h | 18 | ||||
-rw-r--r-- | arch/x86/kernel/Makefile | 4 | ||||
-rw-r--r-- | arch/x86/kernel/apic.c | 24 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/genapic_64.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/setup.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/smpboot.c | 2 |
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 | ||
238 | config 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 | |||
238 | config SPARSE_IRQ | 252 | config 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 | |||
1828 | config INTR_REMAP | 1842 | config 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 |
116 | extern int x2apic; | 116 | extern int x2apic; |
117 | extern void check_x2apic(void); | 117 | extern void check_x2apic(void); |
118 | extern void enable_x2apic(void); | 118 | extern 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 | 134 | static inline void check_x2apic(void) |
135 | { | ||
136 | } | ||
137 | static inline void enable_x2apic(void) | ||
138 | { | ||
139 | } | ||
140 | static inline void enable_IR_x2apic(void) | ||
141 | { | ||
142 | } | ||
143 | static inline int x2apic_enabled(void) | ||
144 | { | ||
145 | return 0; | ||
146 | } | ||
135 | #endif | 147 | #endif |
136 | 148 | ||
137 | struct apic_ops { | 149 | struct apic_ops { |
@@ -177,7 +189,7 @@ static inline u32 safe_apic_wait_icr_idle(void) | |||
177 | 189 | ||
178 | extern int get_physical_broadcast(void); | 190 | extern int get_physical_broadcast(void); |
179 | 191 | ||
180 | #ifdef CONFIG_X86_64 | 192 | #ifdef CONFIG_X86_X2APIC |
181 | static inline void ack_x2APIC_irq(void) | 193 | static 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 |
118 | ifeq ($(CONFIG_X86_64),y) | 118 | ifeq ($(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 | ||
120 | int x2apic; | 116 | int x2apic; |
121 | /* x2apic enabled before OS handover */ | 117 | /* x2apic enabled before OS handover */ |
122 | static int x2apic_preenabled; | 118 | static int x2apic_preenabled; |
@@ -269,7 +265,7 @@ static struct apic_ops xapic_ops = { | |||
269 | struct apic_ops __read_mostly *apic_ops = &xapic_ops; | 265 | struct apic_ops __read_mostly *apic_ops = &xapic_ops; |
270 | EXPORT_SYMBOL_GPL(apic_ops); | 266 | EXPORT_SYMBOL_GPL(apic_ops); |
271 | 267 | ||
272 | #ifdef HAVE_X2APIC | 268 | #ifdef CONFIG_X86_X2APIC |
273 | static void x2apic_wait_icr_idle(void) | 269 | static 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 |
1324 | void check_x2apic(void) | 1320 | void 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 | */ |
1571 | void __init init_apic_mappings(void) | 1573 | void __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 | */ |
47 | void __init default_setup_apic_routing(void) | 49 | void __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 | ||