diff options
Diffstat (limited to 'arch/x86/kernel/apic')
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 318 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic_flat_64.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/apic/es7000_32.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 923 | ||||
-rw-r--r-- | arch/x86/kernel/apic/nmi.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/apic/probe_32.c | 12 | ||||
-rw-r--r-- | arch/x86/kernel/apic/probe_64.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/apic/summit_32.c | 8 | ||||
-rw-r--r-- | arch/x86/kernel/apic/x2apic_cluster.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/apic/x2apic_uv_x.c | 22 |
10 files changed, 681 insertions, 616 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index f2870920f246..8c7c042ecad1 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -14,6 +14,7 @@ | |||
14 | * Mikael Pettersson : PM converted to driver model. | 14 | * Mikael Pettersson : PM converted to driver model. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/perf_counter.h> | ||
17 | #include <linux/kernel_stat.h> | 18 | #include <linux/kernel_stat.h> |
18 | #include <linux/mc146818rtc.h> | 19 | #include <linux/mc146818rtc.h> |
19 | #include <linux/acpi_pmtmr.h> | 20 | #include <linux/acpi_pmtmr.h> |
@@ -34,6 +35,7 @@ | |||
34 | #include <linux/smp.h> | 35 | #include <linux/smp.h> |
35 | #include <linux/mm.h> | 36 | #include <linux/mm.h> |
36 | 37 | ||
38 | #include <asm/perf_counter.h> | ||
37 | #include <asm/pgalloc.h> | 39 | #include <asm/pgalloc.h> |
38 | #include <asm/atomic.h> | 40 | #include <asm/atomic.h> |
39 | #include <asm/mpspec.h> | 41 | #include <asm/mpspec.h> |
@@ -98,6 +100,29 @@ early_param("lapic", parse_lapic); | |||
98 | /* Local APIC was disabled by the BIOS and enabled by the kernel */ | 100 | /* Local APIC was disabled by the BIOS and enabled by the kernel */ |
99 | static int enabled_via_apicbase; | 101 | static int enabled_via_apicbase; |
100 | 102 | ||
103 | /* | ||
104 | * Handle interrupt mode configuration register (IMCR). | ||
105 | * This register controls whether the interrupt signals | ||
106 | * that reach the BSP come from the master PIC or from the | ||
107 | * local APIC. Before entering Symmetric I/O Mode, either | ||
108 | * the BIOS or the operating system must switch out of | ||
109 | * PIC Mode by changing the IMCR. | ||
110 | */ | ||
111 | static inline void imcr_pic_to_apic(void) | ||
112 | { | ||
113 | /* select IMCR register */ | ||
114 | outb(0x70, 0x22); | ||
115 | /* NMI and 8259 INTR go through APIC */ | ||
116 | outb(0x01, 0x23); | ||
117 | } | ||
118 | |||
119 | static inline void imcr_apic_to_pic(void) | ||
120 | { | ||
121 | /* select IMCR register */ | ||
122 | outb(0x70, 0x22); | ||
123 | /* NMI and 8259 INTR go directly to BSP */ | ||
124 | outb(0x00, 0x23); | ||
125 | } | ||
101 | #endif | 126 | #endif |
102 | 127 | ||
103 | #ifdef CONFIG_X86_64 | 128 | #ifdef CONFIG_X86_64 |
@@ -111,13 +136,19 @@ static __init int setup_apicpmtimer(char *s) | |||
111 | __setup("apicpmtimer", setup_apicpmtimer); | 136 | __setup("apicpmtimer", setup_apicpmtimer); |
112 | #endif | 137 | #endif |
113 | 138 | ||
139 | int x2apic_mode; | ||
114 | #ifdef CONFIG_X86_X2APIC | 140 | #ifdef CONFIG_X86_X2APIC |
115 | int x2apic; | ||
116 | /* x2apic enabled before OS handover */ | 141 | /* x2apic enabled before OS handover */ |
117 | static int x2apic_preenabled; | 142 | static int x2apic_preenabled; |
118 | static int disable_x2apic; | 143 | static int disable_x2apic; |
119 | static __init int setup_nox2apic(char *str) | 144 | static __init int setup_nox2apic(char *str) |
120 | { | 145 | { |
146 | if (x2apic_enabled()) { | ||
147 | pr_warning("Bios already enabled x2apic, " | ||
148 | "can't enforce nox2apic"); | ||
149 | return 0; | ||
150 | } | ||
151 | |||
121 | disable_x2apic = 1; | 152 | disable_x2apic = 1; |
122 | setup_clear_cpu_cap(X86_FEATURE_X2APIC); | 153 | setup_clear_cpu_cap(X86_FEATURE_X2APIC); |
123 | return 0; | 154 | return 0; |
@@ -209,6 +240,31 @@ static int modern_apic(void) | |||
209 | return lapic_get_version() >= 0x14; | 240 | return lapic_get_version() >= 0x14; |
210 | } | 241 | } |
211 | 242 | ||
243 | /* | ||
244 | * bare function to substitute write operation | ||
245 | * and it's _that_ fast :) | ||
246 | */ | ||
247 | static void native_apic_write_dummy(u32 reg, u32 v) | ||
248 | { | ||
249 | WARN_ON_ONCE((cpu_has_apic || !disable_apic)); | ||
250 | } | ||
251 | |||
252 | static u32 native_apic_read_dummy(u32 reg) | ||
253 | { | ||
254 | WARN_ON_ONCE((cpu_has_apic && !disable_apic)); | ||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | /* | ||
259 | * right after this call apic->write/read doesn't do anything | ||
260 | * note that there is no restore operation it works one way | ||
261 | */ | ||
262 | void apic_disable(void) | ||
263 | { | ||
264 | apic->read = native_apic_read_dummy; | ||
265 | apic->write = native_apic_write_dummy; | ||
266 | } | ||
267 | |||
212 | void native_apic_wait_icr_idle(void) | 268 | void native_apic_wait_icr_idle(void) |
213 | { | 269 | { |
214 | while (apic_read(APIC_ICR) & APIC_ICR_BUSY) | 270 | while (apic_read(APIC_ICR) & APIC_ICR_BUSY) |
@@ -348,7 +404,7 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) | |||
348 | 404 | ||
349 | static void setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask) | 405 | static void setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask) |
350 | { | 406 | { |
351 | unsigned long reg = (lvt_off << 4) + APIC_EILVT0; | 407 | unsigned long reg = (lvt_off << 4) + APIC_EILVTn(0); |
352 | unsigned int v = (mask << 16) | (msg_type << 8) | vector; | 408 | unsigned int v = (mask << 16) | (msg_type << 8) | vector; |
353 | 409 | ||
354 | apic_write(reg, v); | 410 | apic_write(reg, v); |
@@ -815,7 +871,7 @@ void clear_local_APIC(void) | |||
815 | u32 v; | 871 | u32 v; |
816 | 872 | ||
817 | /* APIC hasn't been mapped yet */ | 873 | /* APIC hasn't been mapped yet */ |
818 | if (!x2apic && !apic_phys) | 874 | if (!x2apic_mode && !apic_phys) |
819 | return; | 875 | return; |
820 | 876 | ||
821 | maxlvt = lapic_get_maxlvt(); | 877 | maxlvt = lapic_get_maxlvt(); |
@@ -843,7 +899,7 @@ void clear_local_APIC(void) | |||
843 | } | 899 | } |
844 | 900 | ||
845 | /* lets not touch this if we didn't frob it */ | 901 | /* lets not touch this if we didn't frob it */ |
846 | #if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL) | 902 | #ifdef CONFIG_X86_THERMAL_VECTOR |
847 | if (maxlvt >= 5) { | 903 | if (maxlvt >= 5) { |
848 | v = apic_read(APIC_LVTTHMR); | 904 | v = apic_read(APIC_LVTTHMR); |
849 | apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED); | 905 | apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED); |
@@ -1133,6 +1189,7 @@ void __cpuinit setup_local_APIC(void) | |||
1133 | apic_write(APIC_ESR, 0); | 1189 | apic_write(APIC_ESR, 0); |
1134 | } | 1190 | } |
1135 | #endif | 1191 | #endif |
1192 | perf_counters_lapic_init(); | ||
1136 | 1193 | ||
1137 | preempt_disable(); | 1194 | preempt_disable(); |
1138 | 1195 | ||
@@ -1287,7 +1344,7 @@ void check_x2apic(void) | |||
1287 | { | 1344 | { |
1288 | if (x2apic_enabled()) { | 1345 | if (x2apic_enabled()) { |
1289 | pr_info("x2apic enabled by BIOS, switching to x2apic ops\n"); | 1346 | pr_info("x2apic enabled by BIOS, switching to x2apic ops\n"); |
1290 | x2apic_preenabled = x2apic = 1; | 1347 | x2apic_preenabled = x2apic_mode = 1; |
1291 | } | 1348 | } |
1292 | } | 1349 | } |
1293 | 1350 | ||
@@ -1295,7 +1352,7 @@ void enable_x2apic(void) | |||
1295 | { | 1352 | { |
1296 | int msr, msr2; | 1353 | int msr, msr2; |
1297 | 1354 | ||
1298 | if (!x2apic) | 1355 | if (!x2apic_mode) |
1299 | return; | 1356 | return; |
1300 | 1357 | ||
1301 | rdmsr(MSR_IA32_APICBASE, msr, msr2); | 1358 | rdmsr(MSR_IA32_APICBASE, msr, msr2); |
@@ -1304,6 +1361,7 @@ void enable_x2apic(void) | |||
1304 | wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0); | 1361 | wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0); |
1305 | } | 1362 | } |
1306 | } | 1363 | } |
1364 | #endif /* CONFIG_X86_X2APIC */ | ||
1307 | 1365 | ||
1308 | void __init enable_IR_x2apic(void) | 1366 | void __init enable_IR_x2apic(void) |
1309 | { | 1367 | { |
@@ -1312,32 +1370,21 @@ void __init enable_IR_x2apic(void) | |||
1312 | unsigned long flags; | 1370 | unsigned long flags; |
1313 | struct IO_APIC_route_entry **ioapic_entries = NULL; | 1371 | struct IO_APIC_route_entry **ioapic_entries = NULL; |
1314 | 1372 | ||
1315 | if (!cpu_has_x2apic) | 1373 | ret = dmar_table_init(); |
1316 | return; | 1374 | if (ret) { |
1317 | 1375 | pr_debug("dmar_table_init() failed with %d:\n", ret); | |
1318 | if (!x2apic_preenabled && disable_x2apic) { | 1376 | goto ir_failed; |
1319 | pr_info("Skipped enabling x2apic and Interrupt-remapping " | ||
1320 | "because of nox2apic\n"); | ||
1321 | return; | ||
1322 | } | 1377 | } |
1323 | 1378 | ||
1324 | if (x2apic_preenabled && disable_x2apic) | 1379 | if (!intr_remapping_supported()) { |
1325 | panic("Bios already enabled x2apic, can't enforce nox2apic"); | 1380 | pr_debug("intr-remapping not supported\n"); |
1326 | 1381 | goto ir_failed; | |
1327 | if (!x2apic_preenabled && skip_ioapic_setup) { | ||
1328 | pr_info("Skipped enabling x2apic and Interrupt-remapping " | ||
1329 | "because of skipping io-apic setup\n"); | ||
1330 | return; | ||
1331 | } | 1382 | } |
1332 | 1383 | ||
1333 | ret = dmar_table_init(); | ||
1334 | if (ret) { | ||
1335 | pr_info("dmar_table_init() failed with %d:\n", ret); | ||
1336 | 1384 | ||
1337 | if (x2apic_preenabled) | 1385 | if (!x2apic_preenabled && skip_ioapic_setup) { |
1338 | panic("x2apic enabled by bios. But IR enabling failed"); | 1386 | pr_info("Skipped enabling intr-remap because of skipping " |
1339 | else | 1387 | "io-apic setup\n"); |
1340 | pr_info("Not enabling x2apic,Intr-remapping\n"); | ||
1341 | return; | 1388 | return; |
1342 | } | 1389 | } |
1343 | 1390 | ||
@@ -1357,19 +1404,16 @@ void __init enable_IR_x2apic(void) | |||
1357 | mask_IO_APIC_setup(ioapic_entries); | 1404 | mask_IO_APIC_setup(ioapic_entries); |
1358 | mask_8259A(); | 1405 | mask_8259A(); |
1359 | 1406 | ||
1360 | ret = enable_intr_remapping(EIM_32BIT_APIC_ID); | 1407 | ret = enable_intr_remapping(x2apic_supported()); |
1361 | |||
1362 | if (ret && x2apic_preenabled) { | ||
1363 | local_irq_restore(flags); | ||
1364 | panic("x2apic enabled by bios. But IR enabling failed"); | ||
1365 | } | ||
1366 | |||
1367 | if (ret) | 1408 | if (ret) |
1368 | goto end_restore; | 1409 | goto end_restore; |
1369 | 1410 | ||
1370 | if (!x2apic) { | 1411 | pr_info("Enabled Interrupt-remapping\n"); |
1371 | x2apic = 1; | 1412 | |
1413 | if (x2apic_supported() && !x2apic_mode) { | ||
1414 | x2apic_mode = 1; | ||
1372 | enable_x2apic(); | 1415 | enable_x2apic(); |
1416 | pr_info("Enabled x2apic\n"); | ||
1373 | } | 1417 | } |
1374 | 1418 | ||
1375 | end_restore: | 1419 | end_restore: |
@@ -1378,37 +1422,34 @@ end_restore: | |||
1378 | * IR enabling failed | 1422 | * IR enabling failed |
1379 | */ | 1423 | */ |
1380 | restore_IO_APIC_setup(ioapic_entries); | 1424 | restore_IO_APIC_setup(ioapic_entries); |
1381 | else | ||
1382 | reinit_intr_remapped_IO_APIC(x2apic_preenabled, ioapic_entries); | ||
1383 | 1425 | ||
1384 | unmask_8259A(); | 1426 | unmask_8259A(); |
1385 | local_irq_restore(flags); | 1427 | local_irq_restore(flags); |
1386 | 1428 | ||
1387 | end: | 1429 | end: |
1388 | if (!ret) { | ||
1389 | if (!x2apic_preenabled) | ||
1390 | pr_info("Enabled x2apic and interrupt-remapping\n"); | ||
1391 | else | ||
1392 | pr_info("Enabled Interrupt-remapping\n"); | ||
1393 | } else | ||
1394 | pr_err("Failed to enable Interrupt-remapping and x2apic\n"); | ||
1395 | if (ioapic_entries) | 1430 | if (ioapic_entries) |
1396 | free_ioapic_entries(ioapic_entries); | 1431 | free_ioapic_entries(ioapic_entries); |
1432 | |||
1433 | if (!ret) | ||
1434 | return; | ||
1435 | |||
1436 | ir_failed: | ||
1437 | if (x2apic_preenabled) | ||
1438 | panic("x2apic enabled by bios. But IR enabling failed"); | ||
1439 | else if (cpu_has_x2apic) | ||
1440 | pr_info("Not enabling x2apic,Intr-remapping\n"); | ||
1397 | #else | 1441 | #else |
1398 | if (!cpu_has_x2apic) | 1442 | if (!cpu_has_x2apic) |
1399 | return; | 1443 | return; |
1400 | 1444 | ||
1401 | if (x2apic_preenabled) | 1445 | if (x2apic_preenabled) |
1402 | panic("x2apic enabled prior OS handover," | 1446 | panic("x2apic enabled prior OS handover," |
1403 | " enable CONFIG_INTR_REMAP"); | 1447 | " enable CONFIG_X86_X2APIC, CONFIG_INTR_REMAP"); |
1404 | |||
1405 | pr_info("Enable CONFIG_INTR_REMAP for enabling intr-remapping " | ||
1406 | " and x2apic\n"); | ||
1407 | #endif | 1448 | #endif |
1408 | 1449 | ||
1409 | return; | 1450 | return; |
1410 | } | 1451 | } |
1411 | #endif /* CONFIG_X86_X2APIC */ | 1452 | |
1412 | 1453 | ||
1413 | #ifdef CONFIG_X86_64 | 1454 | #ifdef CONFIG_X86_64 |
1414 | /* | 1455 | /* |
@@ -1425,7 +1466,6 @@ static int __init detect_init_APIC(void) | |||
1425 | } | 1466 | } |
1426 | 1467 | ||
1427 | mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; | 1468 | mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; |
1428 | boot_cpu_physical_apicid = 0; | ||
1429 | return 0; | 1469 | return 0; |
1430 | } | 1470 | } |
1431 | #else | 1471 | #else |
@@ -1539,32 +1579,49 @@ void __init early_init_lapic_mapping(void) | |||
1539 | */ | 1579 | */ |
1540 | void __init init_apic_mappings(void) | 1580 | void __init init_apic_mappings(void) |
1541 | { | 1581 | { |
1542 | if (x2apic) { | 1582 | unsigned int new_apicid; |
1583 | |||
1584 | if (x2apic_mode) { | ||
1543 | boot_cpu_physical_apicid = read_apic_id(); | 1585 | boot_cpu_physical_apicid = read_apic_id(); |
1544 | return; | 1586 | return; |
1545 | } | 1587 | } |
1546 | 1588 | ||
1547 | /* | 1589 | /* If no local APIC can be found return early */ |
1548 | * If no local APIC can be found then set up a fake all | ||
1549 | * zeroes page to simulate the local APIC and another | ||
1550 | * one for the IO-APIC. | ||
1551 | */ | ||
1552 | if (!smp_found_config && detect_init_APIC()) { | 1590 | if (!smp_found_config && detect_init_APIC()) { |
1553 | apic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE); | 1591 | /* lets NOP'ify apic operations */ |
1554 | apic_phys = __pa(apic_phys); | 1592 | pr_info("APIC: disable apic facility\n"); |
1555 | } else | 1593 | apic_disable(); |
1594 | } else { | ||
1556 | apic_phys = mp_lapic_addr; | 1595 | apic_phys = mp_lapic_addr; |
1557 | 1596 | ||
1558 | set_fixmap_nocache(FIX_APIC_BASE, apic_phys); | 1597 | /* |
1559 | apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n", | 1598 | * acpi lapic path already maps that address in |
1560 | APIC_BASE, apic_phys); | 1599 | * acpi_register_lapic_address() |
1600 | */ | ||
1601 | if (!acpi_lapic) | ||
1602 | set_fixmap_nocache(FIX_APIC_BASE, apic_phys); | ||
1603 | |||
1604 | apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n", | ||
1605 | APIC_BASE, apic_phys); | ||
1606 | } | ||
1561 | 1607 | ||
1562 | /* | 1608 | /* |
1563 | * Fetch the APIC ID of the BSP in case we have a | 1609 | * Fetch the APIC ID of the BSP in case we have a |
1564 | * default configuration (or the MP table is broken). | 1610 | * default configuration (or the MP table is broken). |
1565 | */ | 1611 | */ |
1566 | if (boot_cpu_physical_apicid == -1U) | 1612 | new_apicid = read_apic_id(); |
1567 | boot_cpu_physical_apicid = read_apic_id(); | 1613 | if (boot_cpu_physical_apicid != new_apicid) { |
1614 | boot_cpu_physical_apicid = new_apicid; | ||
1615 | /* | ||
1616 | * yeah -- we lie about apic_version | ||
1617 | * in case if apic was disabled via boot option | ||
1618 | * but it's not a problem for SMP compiled kernel | ||
1619 | * since smp_sanity_check is prepared for such a case | ||
1620 | * and disable smp mode | ||
1621 | */ | ||
1622 | apic_version[new_apicid] = | ||
1623 | GET_APIC_VERSION(apic_read(APIC_LVR)); | ||
1624 | } | ||
1568 | } | 1625 | } |
1569 | 1626 | ||
1570 | /* | 1627 | /* |
@@ -1733,8 +1790,7 @@ void __init connect_bsp_APIC(void) | |||
1733 | */ | 1790 | */ |
1734 | apic_printk(APIC_VERBOSE, "leaving PIC mode, " | 1791 | apic_printk(APIC_VERBOSE, "leaving PIC mode, " |
1735 | "enabling APIC mode.\n"); | 1792 | "enabling APIC mode.\n"); |
1736 | outb(0x70, 0x22); | 1793 | imcr_pic_to_apic(); |
1737 | outb(0x01, 0x23); | ||
1738 | } | 1794 | } |
1739 | #endif | 1795 | #endif |
1740 | if (apic->enable_apic_mode) | 1796 | if (apic->enable_apic_mode) |
@@ -1762,8 +1818,7 @@ void disconnect_bsp_APIC(int virt_wire_setup) | |||
1762 | */ | 1818 | */ |
1763 | apic_printk(APIC_VERBOSE, "disabling APIC mode, " | 1819 | apic_printk(APIC_VERBOSE, "disabling APIC mode, " |
1764 | "entering PIC mode.\n"); | 1820 | "entering PIC mode.\n"); |
1765 | outb(0x70, 0x22); | 1821 | imcr_apic_to_pic(); |
1766 | outb(0x00, 0x23); | ||
1767 | return; | 1822 | return; |
1768 | } | 1823 | } |
1769 | #endif | 1824 | #endif |
@@ -1962,17 +2017,17 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state) | |||
1962 | apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR); | 2017 | apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR); |
1963 | apic_pm_state.apic_tmict = apic_read(APIC_TMICT); | 2018 | apic_pm_state.apic_tmict = apic_read(APIC_TMICT); |
1964 | apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); | 2019 | apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); |
1965 | #if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL) | 2020 | #ifdef CONFIG_X86_THERMAL_VECTOR |
1966 | if (maxlvt >= 5) | 2021 | if (maxlvt >= 5) |
1967 | apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); | 2022 | apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); |
1968 | #endif | 2023 | #endif |
1969 | 2024 | ||
1970 | local_irq_save(flags); | 2025 | local_irq_save(flags); |
1971 | disable_local_APIC(); | 2026 | disable_local_APIC(); |
1972 | #ifdef CONFIG_INTR_REMAP | 2027 | |
1973 | if (intr_remapping_enabled) | 2028 | if (intr_remapping_enabled) |
1974 | disable_intr_remapping(); | 2029 | disable_intr_remapping(); |
1975 | #endif | 2030 | |
1976 | local_irq_restore(flags); | 2031 | local_irq_restore(flags); |
1977 | return 0; | 2032 | return 0; |
1978 | } | 2033 | } |
@@ -1982,42 +2037,34 @@ static int lapic_resume(struct sys_device *dev) | |||
1982 | unsigned int l, h; | 2037 | unsigned int l, h; |
1983 | unsigned long flags; | 2038 | unsigned long flags; |
1984 | int maxlvt; | 2039 | int maxlvt; |
1985 | 2040 | int ret = 0; | |
1986 | #ifdef CONFIG_INTR_REMAP | ||
1987 | int ret; | ||
1988 | struct IO_APIC_route_entry **ioapic_entries = NULL; | 2041 | struct IO_APIC_route_entry **ioapic_entries = NULL; |
1989 | 2042 | ||
1990 | if (!apic_pm_state.active) | 2043 | if (!apic_pm_state.active) |
1991 | return 0; | 2044 | return 0; |
1992 | 2045 | ||
1993 | local_irq_save(flags); | 2046 | local_irq_save(flags); |
1994 | if (x2apic) { | 2047 | if (intr_remapping_enabled) { |
1995 | ioapic_entries = alloc_ioapic_entries(); | 2048 | ioapic_entries = alloc_ioapic_entries(); |
1996 | if (!ioapic_entries) { | 2049 | if (!ioapic_entries) { |
1997 | WARN(1, "Alloc ioapic_entries in lapic resume failed."); | 2050 | WARN(1, "Alloc ioapic_entries in lapic resume failed."); |
1998 | return -ENOMEM; | 2051 | ret = -ENOMEM; |
2052 | goto restore; | ||
1999 | } | 2053 | } |
2000 | 2054 | ||
2001 | ret = save_IO_APIC_setup(ioapic_entries); | 2055 | ret = save_IO_APIC_setup(ioapic_entries); |
2002 | if (ret) { | 2056 | if (ret) { |
2003 | WARN(1, "Saving IO-APIC state failed: %d\n", ret); | 2057 | WARN(1, "Saving IO-APIC state failed: %d\n", ret); |
2004 | free_ioapic_entries(ioapic_entries); | 2058 | free_ioapic_entries(ioapic_entries); |
2005 | return ret; | 2059 | goto restore; |
2006 | } | 2060 | } |
2007 | 2061 | ||
2008 | mask_IO_APIC_setup(ioapic_entries); | 2062 | mask_IO_APIC_setup(ioapic_entries); |
2009 | mask_8259A(); | 2063 | mask_8259A(); |
2010 | enable_x2apic(); | ||
2011 | } | 2064 | } |
2012 | #else | ||
2013 | if (!apic_pm_state.active) | ||
2014 | return 0; | ||
2015 | 2065 | ||
2016 | local_irq_save(flags); | 2066 | if (x2apic_mode) |
2017 | if (x2apic) | ||
2018 | enable_x2apic(); | 2067 | enable_x2apic(); |
2019 | #endif | ||
2020 | |||
2021 | else { | 2068 | else { |
2022 | /* | 2069 | /* |
2023 | * Make sure the APICBASE points to the right address | 2070 | * Make sure the APICBASE points to the right address |
@@ -2055,21 +2102,16 @@ static int lapic_resume(struct sys_device *dev) | |||
2055 | apic_write(APIC_ESR, 0); | 2102 | apic_write(APIC_ESR, 0); |
2056 | apic_read(APIC_ESR); | 2103 | apic_read(APIC_ESR); |
2057 | 2104 | ||
2058 | #ifdef CONFIG_INTR_REMAP | 2105 | if (intr_remapping_enabled) { |
2059 | if (intr_remapping_enabled) | 2106 | reenable_intr_remapping(x2apic_mode); |
2060 | reenable_intr_remapping(EIM_32BIT_APIC_ID); | ||
2061 | |||
2062 | if (x2apic) { | ||
2063 | unmask_8259A(); | 2107 | unmask_8259A(); |
2064 | restore_IO_APIC_setup(ioapic_entries); | 2108 | restore_IO_APIC_setup(ioapic_entries); |
2065 | free_ioapic_entries(ioapic_entries); | 2109 | free_ioapic_entries(ioapic_entries); |
2066 | } | 2110 | } |
2067 | #endif | 2111 | restore: |
2068 | |||
2069 | local_irq_restore(flags); | 2112 | local_irq_restore(flags); |
2070 | 2113 | ||
2071 | 2114 | return ret; | |
2072 | return 0; | ||
2073 | } | 2115 | } |
2074 | 2116 | ||
2075 | /* | 2117 | /* |
@@ -2117,31 +2159,14 @@ static void apic_pm_activate(void) { } | |||
2117 | #endif /* CONFIG_PM */ | 2159 | #endif /* CONFIG_PM */ |
2118 | 2160 | ||
2119 | #ifdef CONFIG_X86_64 | 2161 | #ifdef CONFIG_X86_64 |
2120 | /* | 2162 | |
2121 | * apic_is_clustered_box() -- Check if we can expect good TSC | 2163 | static int __cpuinit apic_cluster_num(void) |
2122 | * | ||
2123 | * Thus far, the major user of this is IBM's Summit2 series: | ||
2124 | * | ||
2125 | * Clustered boxes may have unsynced TSC problems if they are | ||
2126 | * multi-chassis. Use available data to take a good guess. | ||
2127 | * If in doubt, go HPET. | ||
2128 | */ | ||
2129 | __cpuinit int apic_is_clustered_box(void) | ||
2130 | { | 2164 | { |
2131 | int i, clusters, zeros; | 2165 | int i, clusters, zeros; |
2132 | unsigned id; | 2166 | unsigned id; |
2133 | u16 *bios_cpu_apicid; | 2167 | u16 *bios_cpu_apicid; |
2134 | DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS); | 2168 | DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS); |
2135 | 2169 | ||
2136 | /* | ||
2137 | * there is not this kind of box with AMD CPU yet. | ||
2138 | * Some AMD box with quadcore cpu and 8 sockets apicid | ||
2139 | * will be [4, 0x23] or [8, 0x27] could be thought to | ||
2140 | * vsmp box still need checking... | ||
2141 | */ | ||
2142 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && !is_vsmp_box()) | ||
2143 | return 0; | ||
2144 | |||
2145 | bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid); | 2170 | bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid); |
2146 | bitmap_zero(clustermap, NUM_APIC_CLUSTERS); | 2171 | bitmap_zero(clustermap, NUM_APIC_CLUSTERS); |
2147 | 2172 | ||
@@ -2177,18 +2202,67 @@ __cpuinit int apic_is_clustered_box(void) | |||
2177 | ++zeros; | 2202 | ++zeros; |
2178 | } | 2203 | } |
2179 | 2204 | ||
2180 | /* ScaleMP vSMPowered boxes have one cluster per board and TSCs are | 2205 | return clusters; |
2181 | * not guaranteed to be synced between boards | 2206 | } |
2182 | */ | 2207 | |
2183 | if (is_vsmp_box() && clusters > 1) | 2208 | static int __cpuinitdata multi_checked; |
2209 | static int __cpuinitdata multi; | ||
2210 | |||
2211 | static int __cpuinit set_multi(const struct dmi_system_id *d) | ||
2212 | { | ||
2213 | if (multi) | ||
2214 | return 0; | ||
2215 | pr_info("APIC: %s detected, Multi Chassis\n", d->ident); | ||
2216 | multi = 1; | ||
2217 | return 0; | ||
2218 | } | ||
2219 | |||
2220 | static const __cpuinitconst struct dmi_system_id multi_dmi_table[] = { | ||
2221 | { | ||
2222 | .callback = set_multi, | ||
2223 | .ident = "IBM System Summit2", | ||
2224 | .matches = { | ||
2225 | DMI_MATCH(DMI_SYS_VENDOR, "IBM"), | ||
2226 | DMI_MATCH(DMI_PRODUCT_NAME, "Summit2"), | ||
2227 | }, | ||
2228 | }, | ||
2229 | {} | ||
2230 | }; | ||
2231 | |||
2232 | static void __cpuinit dmi_check_multi(void) | ||
2233 | { | ||
2234 | if (multi_checked) | ||
2235 | return; | ||
2236 | |||
2237 | dmi_check_system(multi_dmi_table); | ||
2238 | multi_checked = 1; | ||
2239 | } | ||
2240 | |||
2241 | /* | ||
2242 | * apic_is_clustered_box() -- Check if we can expect good TSC | ||
2243 | * | ||
2244 | * Thus far, the major user of this is IBM's Summit2 series: | ||
2245 | * Clustered boxes may have unsynced TSC problems if they are | ||
2246 | * multi-chassis. | ||
2247 | * Use DMI to check them | ||
2248 | */ | ||
2249 | __cpuinit int apic_is_clustered_box(void) | ||
2250 | { | ||
2251 | dmi_check_multi(); | ||
2252 | if (multi) | ||
2184 | return 1; | 2253 | return 1; |
2185 | 2254 | ||
2255 | if (!is_vsmp_box()) | ||
2256 | return 0; | ||
2257 | |||
2186 | /* | 2258 | /* |
2187 | * If clusters > 2, then should be multi-chassis. | 2259 | * ScaleMP vSMPowered boxes have one cluster per board and TSCs are |
2188 | * May have to revisit this when multi-core + hyperthreaded CPUs come | 2260 | * not guaranteed to be synced between boards |
2189 | * out, but AFAIK this will work even for them. | ||
2190 | */ | 2261 | */ |
2191 | return (clusters > 2); | 2262 | if (apic_cluster_num() > 1) |
2263 | return 1; | ||
2264 | |||
2265 | return 0; | ||
2192 | } | 2266 | } |
2193 | #endif | 2267 | #endif |
2194 | 2268 | ||
diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index 306e5e88fb6f..d0c99abc26c3 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c | |||
@@ -161,7 +161,7 @@ static int flat_apic_id_registered(void) | |||
161 | 161 | ||
162 | static int flat_phys_pkg_id(int initial_apic_id, int index_msb) | 162 | static int flat_phys_pkg_id(int initial_apic_id, int index_msb) |
163 | { | 163 | { |
164 | return hard_smp_processor_id() >> index_msb; | 164 | return initial_apic_id >> index_msb; |
165 | } | 165 | } |
166 | 166 | ||
167 | struct apic apic_flat = { | 167 | struct apic apic_flat = { |
@@ -235,7 +235,7 @@ static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |||
235 | * regardless of how many processors are present (x86_64 ES7000 | 235 | * regardless of how many processors are present (x86_64 ES7000 |
236 | * is an example). | 236 | * is an example). |
237 | */ | 237 | */ |
238 | if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID && | 238 | if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID && |
239 | (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) { | 239 | (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) { |
240 | printk(KERN_DEBUG "system APIC only can use physical flat"); | 240 | printk(KERN_DEBUG "system APIC only can use physical flat"); |
241 | return 1; | 241 | return 1; |
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index 302947775575..69328ac8de9c 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c | |||
@@ -145,7 +145,7 @@ es7000_rename_gsi(int ioapic, int gsi) | |||
145 | return gsi; | 145 | return gsi; |
146 | } | 146 | } |
147 | 147 | ||
148 | static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip) | 148 | static int __cpuinit wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip) |
149 | { | 149 | { |
150 | unsigned long vect = 0, psaival = 0; | 150 | unsigned long vect = 0, psaival = 0; |
151 | 151 | ||
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 30da617d18e4..4d0216fcb36c 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #include <asm/setup.h> | 59 | #include <asm/setup.h> |
60 | #include <asm/irq_remapping.h> | 60 | #include <asm/irq_remapping.h> |
61 | #include <asm/hpet.h> | 61 | #include <asm/hpet.h> |
62 | #include <asm/hw_irq.h> | ||
62 | #include <asm/uv/uv_hub.h> | 63 | #include <asm/uv/uv_hub.h> |
63 | #include <asm/uv/uv_irq.h> | 64 | #include <asm/uv/uv_irq.h> |
64 | 65 | ||
@@ -129,12 +130,9 @@ struct irq_pin_list { | |||
129 | struct irq_pin_list *next; | 130 | struct irq_pin_list *next; |
130 | }; | 131 | }; |
131 | 132 | ||
132 | static struct irq_pin_list *get_one_free_irq_2_pin(int cpu) | 133 | static struct irq_pin_list *get_one_free_irq_2_pin(int node) |
133 | { | 134 | { |
134 | struct irq_pin_list *pin; | 135 | struct irq_pin_list *pin; |
135 | int node; | ||
136 | |||
137 | node = cpu_to_node(cpu); | ||
138 | 136 | ||
139 | pin = kzalloc_node(sizeof(*pin), GFP_ATOMIC, node); | 137 | pin = kzalloc_node(sizeof(*pin), GFP_ATOMIC, node); |
140 | 138 | ||
@@ -148,9 +146,6 @@ struct irq_cfg { | |||
148 | unsigned move_cleanup_count; | 146 | unsigned move_cleanup_count; |
149 | u8 vector; | 147 | u8 vector; |
150 | u8 move_in_progress : 1; | 148 | u8 move_in_progress : 1; |
151 | #ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC | ||
152 | u8 move_desc_pending : 1; | ||
153 | #endif | ||
154 | }; | 149 | }; |
155 | 150 | ||
156 | /* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */ | 151 | /* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */ |
@@ -182,16 +177,18 @@ int __init arch_early_irq_init(void) | |||
182 | struct irq_cfg *cfg; | 177 | struct irq_cfg *cfg; |
183 | struct irq_desc *desc; | 178 | struct irq_desc *desc; |
184 | int count; | 179 | int count; |
180 | int node; | ||
185 | int i; | 181 | int i; |
186 | 182 | ||
187 | cfg = irq_cfgx; | 183 | cfg = irq_cfgx; |
188 | count = ARRAY_SIZE(irq_cfgx); | 184 | count = ARRAY_SIZE(irq_cfgx); |
185 | node= cpu_to_node(boot_cpu_id); | ||
189 | 186 | ||
190 | for (i = 0; i < count; i++) { | 187 | for (i = 0; i < count; i++) { |
191 | desc = irq_to_desc(i); | 188 | desc = irq_to_desc(i); |
192 | desc->chip_data = &cfg[i]; | 189 | desc->chip_data = &cfg[i]; |
193 | alloc_bootmem_cpumask_var(&cfg[i].domain); | 190 | zalloc_cpumask_var_node(&cfg[i].domain, GFP_NOWAIT, node); |
194 | alloc_bootmem_cpumask_var(&cfg[i].old_domain); | 191 | zalloc_cpumask_var_node(&cfg[i].old_domain, GFP_NOWAIT, node); |
195 | if (i < NR_IRQS_LEGACY) | 192 | if (i < NR_IRQS_LEGACY) |
196 | cpumask_setall(cfg[i].domain); | 193 | cpumask_setall(cfg[i].domain); |
197 | } | 194 | } |
@@ -212,12 +209,9 @@ static struct irq_cfg *irq_cfg(unsigned int irq) | |||
212 | return cfg; | 209 | return cfg; |
213 | } | 210 | } |
214 | 211 | ||
215 | static struct irq_cfg *get_one_free_irq_cfg(int cpu) | 212 | static struct irq_cfg *get_one_free_irq_cfg(int node) |
216 | { | 213 | { |
217 | struct irq_cfg *cfg; | 214 | struct irq_cfg *cfg; |
218 | int node; | ||
219 | |||
220 | node = cpu_to_node(cpu); | ||
221 | 215 | ||
222 | cfg = kzalloc_node(sizeof(*cfg), GFP_ATOMIC, node); | 216 | cfg = kzalloc_node(sizeof(*cfg), GFP_ATOMIC, node); |
223 | if (cfg) { | 217 | if (cfg) { |
@@ -238,13 +232,13 @@ static struct irq_cfg *get_one_free_irq_cfg(int cpu) | |||
238 | return cfg; | 232 | return cfg; |
239 | } | 233 | } |
240 | 234 | ||
241 | int arch_init_chip_data(struct irq_desc *desc, int cpu) | 235 | int arch_init_chip_data(struct irq_desc *desc, int node) |
242 | { | 236 | { |
243 | struct irq_cfg *cfg; | 237 | struct irq_cfg *cfg; |
244 | 238 | ||
245 | cfg = desc->chip_data; | 239 | cfg = desc->chip_data; |
246 | if (!cfg) { | 240 | if (!cfg) { |
247 | desc->chip_data = get_one_free_irq_cfg(cpu); | 241 | desc->chip_data = get_one_free_irq_cfg(node); |
248 | if (!desc->chip_data) { | 242 | if (!desc->chip_data) { |
249 | printk(KERN_ERR "can not alloc irq_cfg\n"); | 243 | printk(KERN_ERR "can not alloc irq_cfg\n"); |
250 | BUG_ON(1); | 244 | BUG_ON(1); |
@@ -254,10 +248,9 @@ int arch_init_chip_data(struct irq_desc *desc, int cpu) | |||
254 | return 0; | 248 | return 0; |
255 | } | 249 | } |
256 | 250 | ||
257 | #ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC | 251 | /* for move_irq_desc */ |
258 | |||
259 | static void | 252 | static void |
260 | init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int cpu) | 253 | init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int node) |
261 | { | 254 | { |
262 | struct irq_pin_list *old_entry, *head, *tail, *entry; | 255 | struct irq_pin_list *old_entry, *head, *tail, *entry; |
263 | 256 | ||
@@ -266,7 +259,7 @@ init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int cpu) | |||
266 | if (!old_entry) | 259 | if (!old_entry) |
267 | return; | 260 | return; |
268 | 261 | ||
269 | entry = get_one_free_irq_2_pin(cpu); | 262 | entry = get_one_free_irq_2_pin(node); |
270 | if (!entry) | 263 | if (!entry) |
271 | return; | 264 | return; |
272 | 265 | ||
@@ -276,7 +269,7 @@ init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int cpu) | |||
276 | tail = entry; | 269 | tail = entry; |
277 | old_entry = old_entry->next; | 270 | old_entry = old_entry->next; |
278 | while (old_entry) { | 271 | while (old_entry) { |
279 | entry = get_one_free_irq_2_pin(cpu); | 272 | entry = get_one_free_irq_2_pin(node); |
280 | if (!entry) { | 273 | if (!entry) { |
281 | entry = head; | 274 | entry = head; |
282 | while (entry) { | 275 | while (entry) { |
@@ -316,12 +309,12 @@ static void free_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg) | |||
316 | } | 309 | } |
317 | 310 | ||
318 | void arch_init_copy_chip_data(struct irq_desc *old_desc, | 311 | void arch_init_copy_chip_data(struct irq_desc *old_desc, |
319 | struct irq_desc *desc, int cpu) | 312 | struct irq_desc *desc, int node) |
320 | { | 313 | { |
321 | struct irq_cfg *cfg; | 314 | struct irq_cfg *cfg; |
322 | struct irq_cfg *old_cfg; | 315 | struct irq_cfg *old_cfg; |
323 | 316 | ||
324 | cfg = get_one_free_irq_cfg(cpu); | 317 | cfg = get_one_free_irq_cfg(node); |
325 | 318 | ||
326 | if (!cfg) | 319 | if (!cfg) |
327 | return; | 320 | return; |
@@ -332,7 +325,7 @@ void arch_init_copy_chip_data(struct irq_desc *old_desc, | |||
332 | 325 | ||
333 | memcpy(cfg, old_cfg, sizeof(struct irq_cfg)); | 326 | memcpy(cfg, old_cfg, sizeof(struct irq_cfg)); |
334 | 327 | ||
335 | init_copy_irq_2_pin(old_cfg, cfg, cpu); | 328 | init_copy_irq_2_pin(old_cfg, cfg, node); |
336 | } | 329 | } |
337 | 330 | ||
338 | static void free_irq_cfg(struct irq_cfg *old_cfg) | 331 | static void free_irq_cfg(struct irq_cfg *old_cfg) |
@@ -356,19 +349,7 @@ void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc) | |||
356 | old_desc->chip_data = NULL; | 349 | old_desc->chip_data = NULL; |
357 | } | 350 | } |
358 | } | 351 | } |
359 | 352 | /* end for move_irq_desc */ | |
360 | static void | ||
361 | set_extra_move_desc(struct irq_desc *desc, const struct cpumask *mask) | ||
362 | { | ||
363 | struct irq_cfg *cfg = desc->chip_data; | ||
364 | |||
365 | if (!cfg->move_in_progress) { | ||
366 | /* it means that domain is not changed */ | ||
367 | if (!cpumask_intersects(desc->affinity, mask)) | ||
368 | cfg->move_desc_pending = 1; | ||
369 | } | ||
370 | } | ||
371 | #endif | ||
372 | 353 | ||
373 | #else | 354 | #else |
374 | static struct irq_cfg *irq_cfg(unsigned int irq) | 355 | static struct irq_cfg *irq_cfg(unsigned int irq) |
@@ -378,13 +359,6 @@ static struct irq_cfg *irq_cfg(unsigned int irq) | |||
378 | 359 | ||
379 | #endif | 360 | #endif |
380 | 361 | ||
381 | #ifndef CONFIG_NUMA_MIGRATE_IRQ_DESC | ||
382 | static inline void | ||
383 | set_extra_move_desc(struct irq_desc *desc, const struct cpumask *mask) | ||
384 | { | ||
385 | } | ||
386 | #endif | ||
387 | |||
388 | struct io_apic { | 362 | struct io_apic { |
389 | unsigned int index; | 363 | unsigned int index; |
390 | unsigned int unused[3]; | 364 | unsigned int unused[3]; |
@@ -488,7 +462,8 @@ static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) | |||
488 | static void | 462 | static void |
489 | __ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) | 463 | __ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) |
490 | { | 464 | { |
491 | union entry_union eu; | 465 | union entry_union eu = {{0, 0}}; |
466 | |||
492 | eu.entry = e; | 467 | eu.entry = e; |
493 | io_apic_write(apic, 0x11 + 2*pin, eu.w2); | 468 | io_apic_write(apic, 0x11 + 2*pin, eu.w2); |
494 | io_apic_write(apic, 0x10 + 2*pin, eu.w1); | 469 | io_apic_write(apic, 0x10 + 2*pin, eu.w1); |
@@ -518,132 +493,18 @@ static void ioapic_mask_entry(int apic, int pin) | |||
518 | spin_unlock_irqrestore(&ioapic_lock, flags); | 493 | spin_unlock_irqrestore(&ioapic_lock, flags); |
519 | } | 494 | } |
520 | 495 | ||
521 | #ifdef CONFIG_SMP | ||
522 | static void send_cleanup_vector(struct irq_cfg *cfg) | ||
523 | { | ||
524 | cpumask_var_t cleanup_mask; | ||
525 | |||
526 | if (unlikely(!alloc_cpumask_var(&cleanup_mask, GFP_ATOMIC))) { | ||
527 | unsigned int i; | ||
528 | cfg->move_cleanup_count = 0; | ||
529 | for_each_cpu_and(i, cfg->old_domain, cpu_online_mask) | ||
530 | cfg->move_cleanup_count++; | ||
531 | for_each_cpu_and(i, cfg->old_domain, cpu_online_mask) | ||
532 | apic->send_IPI_mask(cpumask_of(i), IRQ_MOVE_CLEANUP_VECTOR); | ||
533 | } else { | ||
534 | cpumask_and(cleanup_mask, cfg->old_domain, cpu_online_mask); | ||
535 | cfg->move_cleanup_count = cpumask_weight(cleanup_mask); | ||
536 | apic->send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR); | ||
537 | free_cpumask_var(cleanup_mask); | ||
538 | } | ||
539 | cfg->move_in_progress = 0; | ||
540 | } | ||
541 | |||
542 | static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg) | ||
543 | { | ||
544 | int apic, pin; | ||
545 | struct irq_pin_list *entry; | ||
546 | u8 vector = cfg->vector; | ||
547 | |||
548 | entry = cfg->irq_2_pin; | ||
549 | for (;;) { | ||
550 | unsigned int reg; | ||
551 | |||
552 | if (!entry) | ||
553 | break; | ||
554 | |||
555 | apic = entry->apic; | ||
556 | pin = entry->pin; | ||
557 | /* | ||
558 | * With interrupt-remapping, destination information comes | ||
559 | * from interrupt-remapping table entry. | ||
560 | */ | ||
561 | if (!irq_remapped(irq)) | ||
562 | io_apic_write(apic, 0x11 + pin*2, dest); | ||
563 | reg = io_apic_read(apic, 0x10 + pin*2); | ||
564 | reg &= ~IO_APIC_REDIR_VECTOR_MASK; | ||
565 | reg |= vector; | ||
566 | io_apic_modify(apic, 0x10 + pin*2, reg); | ||
567 | if (!entry->next) | ||
568 | break; | ||
569 | entry = entry->next; | ||
570 | } | ||
571 | } | ||
572 | |||
573 | static int | ||
574 | assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask); | ||
575 | |||
576 | /* | ||
577 | * Either sets desc->affinity to a valid value, and returns | ||
578 | * ->cpu_mask_to_apicid of that, or returns BAD_APICID and | ||
579 | * leaves desc->affinity untouched. | ||
580 | */ | ||
581 | static unsigned int | ||
582 | set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask) | ||
583 | { | ||
584 | struct irq_cfg *cfg; | ||
585 | unsigned int irq; | ||
586 | |||
587 | if (!cpumask_intersects(mask, cpu_online_mask)) | ||
588 | return BAD_APICID; | ||
589 | |||
590 | irq = desc->irq; | ||
591 | cfg = desc->chip_data; | ||
592 | if (assign_irq_vector(irq, cfg, mask)) | ||
593 | return BAD_APICID; | ||
594 | |||
595 | /* check that before desc->addinity get updated */ | ||
596 | set_extra_move_desc(desc, mask); | ||
597 | |||
598 | cpumask_copy(desc->affinity, mask); | ||
599 | |||
600 | return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain); | ||
601 | } | ||
602 | |||
603 | static void | ||
604 | set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask) | ||
605 | { | ||
606 | struct irq_cfg *cfg; | ||
607 | unsigned long flags; | ||
608 | unsigned int dest; | ||
609 | unsigned int irq; | ||
610 | |||
611 | irq = desc->irq; | ||
612 | cfg = desc->chip_data; | ||
613 | |||
614 | spin_lock_irqsave(&ioapic_lock, flags); | ||
615 | dest = set_desc_affinity(desc, mask); | ||
616 | if (dest != BAD_APICID) { | ||
617 | /* Only the high 8 bits are valid. */ | ||
618 | dest = SET_APIC_LOGICAL_ID(dest); | ||
619 | __target_IO_APIC_irq(irq, dest, cfg); | ||
620 | } | ||
621 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
622 | } | ||
623 | |||
624 | static void | ||
625 | set_ioapic_affinity_irq(unsigned int irq, const struct cpumask *mask) | ||
626 | { | ||
627 | struct irq_desc *desc; | ||
628 | |||
629 | desc = irq_to_desc(irq); | ||
630 | |||
631 | set_ioapic_affinity_irq_desc(desc, mask); | ||
632 | } | ||
633 | #endif /* CONFIG_SMP */ | ||
634 | |||
635 | /* | 496 | /* |
636 | * The common case is 1:1 IRQ<->pin mappings. Sometimes there are | 497 | * The common case is 1:1 IRQ<->pin mappings. Sometimes there are |
637 | * shared ISA-space IRQs, so we have to support them. We are super | 498 | * shared ISA-space IRQs, so we have to support them. We are super |
638 | * fast in the common case, and fast for shared ISA-space IRQs. | 499 | * fast in the common case, and fast for shared ISA-space IRQs. |
639 | */ | 500 | */ |
640 | static void add_pin_to_irq_cpu(struct irq_cfg *cfg, int cpu, int apic, int pin) | 501 | static void add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pin) |
641 | { | 502 | { |
642 | struct irq_pin_list *entry; | 503 | struct irq_pin_list *entry; |
643 | 504 | ||
644 | entry = cfg->irq_2_pin; | 505 | entry = cfg->irq_2_pin; |
645 | if (!entry) { | 506 | if (!entry) { |
646 | entry = get_one_free_irq_2_pin(cpu); | 507 | entry = get_one_free_irq_2_pin(node); |
647 | if (!entry) { | 508 | if (!entry) { |
648 | printk(KERN_ERR "can not alloc irq_2_pin to add %d - %d\n", | 509 | printk(KERN_ERR "can not alloc irq_2_pin to add %d - %d\n", |
649 | apic, pin); | 510 | apic, pin); |
@@ -663,7 +524,7 @@ static void add_pin_to_irq_cpu(struct irq_cfg *cfg, int cpu, int apic, int pin) | |||
663 | entry = entry->next; | 524 | entry = entry->next; |
664 | } | 525 | } |
665 | 526 | ||
666 | entry->next = get_one_free_irq_2_pin(cpu); | 527 | entry->next = get_one_free_irq_2_pin(node); |
667 | entry = entry->next; | 528 | entry = entry->next; |
668 | entry->apic = apic; | 529 | entry->apic = apic; |
669 | entry->pin = pin; | 530 | entry->pin = pin; |
@@ -672,7 +533,7 @@ static void add_pin_to_irq_cpu(struct irq_cfg *cfg, int cpu, int apic, int pin) | |||
672 | /* | 533 | /* |
673 | * Reroute an IRQ to a different pin. | 534 | * Reroute an IRQ to a different pin. |
674 | */ | 535 | */ |
675 | static void __init replace_pin_at_irq_cpu(struct irq_cfg *cfg, int cpu, | 536 | static void __init replace_pin_at_irq_node(struct irq_cfg *cfg, int node, |
676 | int oldapic, int oldpin, | 537 | int oldapic, int oldpin, |
677 | int newapic, int newpin) | 538 | int newapic, int newpin) |
678 | { | 539 | { |
@@ -692,7 +553,7 @@ static void __init replace_pin_at_irq_cpu(struct irq_cfg *cfg, int cpu, | |||
692 | 553 | ||
693 | /* why? call replace before add? */ | 554 | /* why? call replace before add? */ |
694 | if (!replaced) | 555 | if (!replaced) |
695 | add_pin_to_irq_cpu(cfg, cpu, newapic, newpin); | 556 | add_pin_to_irq_node(cfg, node, newapic, newpin); |
696 | } | 557 | } |
697 | 558 | ||
698 | static inline void io_apic_modify_irq(struct irq_cfg *cfg, | 559 | static inline void io_apic_modify_irq(struct irq_cfg *cfg, |
@@ -850,7 +711,6 @@ static int __init ioapic_pirq_setup(char *str) | |||
850 | __setup("pirq=", ioapic_pirq_setup); | 711 | __setup("pirq=", ioapic_pirq_setup); |
851 | #endif /* CONFIG_X86_32 */ | 712 | #endif /* CONFIG_X86_32 */ |
852 | 713 | ||
853 | #ifdef CONFIG_INTR_REMAP | ||
854 | struct IO_APIC_route_entry **alloc_ioapic_entries(void) | 714 | struct IO_APIC_route_entry **alloc_ioapic_entries(void) |
855 | { | 715 | { |
856 | int apic; | 716 | int apic; |
@@ -948,20 +808,6 @@ int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries) | |||
948 | return 0; | 808 | return 0; |
949 | } | 809 | } |
950 | 810 | ||
951 | void reinit_intr_remapped_IO_APIC(int intr_remapping, | ||
952 | struct IO_APIC_route_entry **ioapic_entries) | ||
953 | |||
954 | { | ||
955 | /* | ||
956 | * for now plain restore of previous settings. | ||
957 | * TBD: In the case of OS enabling interrupt-remapping, | ||
958 | * IO-APIC RTE's need to be setup to point to interrupt-remapping | ||
959 | * table entries. for now, do a plain restore, and wait for | ||
960 | * the setup_IO_APIC_irqs() to do proper initialization. | ||
961 | */ | ||
962 | restore_IO_APIC_setup(ioapic_entries); | ||
963 | } | ||
964 | |||
965 | void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries) | 811 | void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries) |
966 | { | 812 | { |
967 | int apic; | 813 | int apic; |
@@ -971,7 +817,6 @@ void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries) | |||
971 | 817 | ||
972 | kfree(ioapic_entries); | 818 | kfree(ioapic_entries); |
973 | } | 819 | } |
974 | #endif | ||
975 | 820 | ||
976 | /* | 821 | /* |
977 | * Find the IRQ entry number of a certain pin. | 822 | * Find the IRQ entry number of a certain pin. |
@@ -1032,54 +877,6 @@ static int __init find_isa_irq_apic(int irq, int type) | |||
1032 | return -1; | 877 | return -1; |
1033 | } | 878 | } |
1034 | 879 | ||
1035 | /* | ||
1036 | * Find a specific PCI IRQ entry. | ||
1037 | * Not an __init, possibly needed by modules | ||
1038 | */ | ||
1039 | static int pin_2_irq(int idx, int apic, int pin); | ||
1040 | |||
1041 | int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) | ||
1042 | { | ||
1043 | int apic, i, best_guess = -1; | ||
1044 | |||
1045 | apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n", | ||
1046 | bus, slot, pin); | ||
1047 | if (test_bit(bus, mp_bus_not_pci)) { | ||
1048 | apic_printk(APIC_VERBOSE, "PCI BIOS passed nonexistent PCI bus %d!\n", bus); | ||
1049 | return -1; | ||
1050 | } | ||
1051 | for (i = 0; i < mp_irq_entries; i++) { | ||
1052 | int lbus = mp_irqs[i].srcbus; | ||
1053 | |||
1054 | for (apic = 0; apic < nr_ioapics; apic++) | ||
1055 | if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic || | ||
1056 | mp_irqs[i].dstapic == MP_APIC_ALL) | ||
1057 | break; | ||
1058 | |||
1059 | if (!test_bit(lbus, mp_bus_not_pci) && | ||
1060 | !mp_irqs[i].irqtype && | ||
1061 | (bus == lbus) && | ||
1062 | (slot == ((mp_irqs[i].srcbusirq >> 2) & 0x1f))) { | ||
1063 | int irq = pin_2_irq(i, apic, mp_irqs[i].dstirq); | ||
1064 | |||
1065 | if (!(apic || IO_APIC_IRQ(irq))) | ||
1066 | continue; | ||
1067 | |||
1068 | if (pin == (mp_irqs[i].srcbusirq & 3)) | ||
1069 | return irq; | ||
1070 | /* | ||
1071 | * Use the first all-but-pin matching entry as a | ||
1072 | * best-guess fuzzy result for broken mptables. | ||
1073 | */ | ||
1074 | if (best_guess < 0) | ||
1075 | best_guess = irq; | ||
1076 | } | ||
1077 | } | ||
1078 | return best_guess; | ||
1079 | } | ||
1080 | |||
1081 | EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector); | ||
1082 | |||
1083 | #if defined(CONFIG_EISA) || defined(CONFIG_MCA) | 880 | #if defined(CONFIG_EISA) || defined(CONFIG_MCA) |
1084 | /* | 881 | /* |
1085 | * EISA Edge/Level control register, ELCR | 882 | * EISA Edge/Level control register, ELCR |
@@ -1298,6 +1095,64 @@ static int pin_2_irq(int idx, int apic, int pin) | |||
1298 | return irq; | 1095 | return irq; |
1299 | } | 1096 | } |
1300 | 1097 | ||
1098 | /* | ||
1099 | * Find a specific PCI IRQ entry. | ||
1100 | * Not an __init, possibly needed by modules | ||
1101 | */ | ||
1102 | int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin, | ||
1103 | struct io_apic_irq_attr *irq_attr) | ||
1104 | { | ||
1105 | int apic, i, best_guess = -1; | ||
1106 | |||
1107 | apic_printk(APIC_DEBUG, | ||
1108 | "querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n", | ||
1109 | bus, slot, pin); | ||
1110 | if (test_bit(bus, mp_bus_not_pci)) { | ||
1111 | apic_printk(APIC_VERBOSE, | ||
1112 | "PCI BIOS passed nonexistent PCI bus %d!\n", bus); | ||
1113 | return -1; | ||
1114 | } | ||
1115 | for (i = 0; i < mp_irq_entries; i++) { | ||
1116 | int lbus = mp_irqs[i].srcbus; | ||
1117 | |||
1118 | for (apic = 0; apic < nr_ioapics; apic++) | ||
1119 | if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic || | ||
1120 | mp_irqs[i].dstapic == MP_APIC_ALL) | ||
1121 | break; | ||
1122 | |||
1123 | if (!test_bit(lbus, mp_bus_not_pci) && | ||
1124 | !mp_irqs[i].irqtype && | ||
1125 | (bus == lbus) && | ||
1126 | (slot == ((mp_irqs[i].srcbusirq >> 2) & 0x1f))) { | ||
1127 | int irq = pin_2_irq(i, apic, mp_irqs[i].dstirq); | ||
1128 | |||
1129 | if (!(apic || IO_APIC_IRQ(irq))) | ||
1130 | continue; | ||
1131 | |||
1132 | if (pin == (mp_irqs[i].srcbusirq & 3)) { | ||
1133 | set_io_apic_irq_attr(irq_attr, apic, | ||
1134 | mp_irqs[i].dstirq, | ||
1135 | irq_trigger(i), | ||
1136 | irq_polarity(i)); | ||
1137 | return irq; | ||
1138 | } | ||
1139 | /* | ||
1140 | * Use the first all-but-pin matching entry as a | ||
1141 | * best-guess fuzzy result for broken mptables. | ||
1142 | */ | ||
1143 | if (best_guess < 0) { | ||
1144 | set_io_apic_irq_attr(irq_attr, apic, | ||
1145 | mp_irqs[i].dstirq, | ||
1146 | irq_trigger(i), | ||
1147 | irq_polarity(i)); | ||
1148 | best_guess = irq; | ||
1149 | } | ||
1150 | } | ||
1151 | } | ||
1152 | return best_guess; | ||
1153 | } | ||
1154 | EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector); | ||
1155 | |||
1301 | void lock_vector_lock(void) | 1156 | void lock_vector_lock(void) |
1302 | { | 1157 | { |
1303 | /* Used to the online set of cpus does not change | 1158 | /* Used to the online set of cpus does not change |
@@ -1559,6 +1414,9 @@ int setup_ioapic_entry(int apic_id, int irq, | |||
1559 | irte.vector = vector; | 1414 | irte.vector = vector; |
1560 | irte.dest_id = IRTE_DEST(destination); | 1415 | irte.dest_id = IRTE_DEST(destination); |
1561 | 1416 | ||
1417 | /* Set source-id of interrupt request */ | ||
1418 | set_ioapic_sid(&irte, apic_id); | ||
1419 | |||
1562 | modify_irte(irq, &irte); | 1420 | modify_irte(irq, &irte); |
1563 | 1421 | ||
1564 | ir_entry->index2 = (index >> 15) & 0x1; | 1422 | ir_entry->index2 = (index >> 15) & 0x1; |
@@ -1628,58 +1486,70 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq | |||
1628 | ioapic_write_entry(apic_id, pin, entry); | 1486 | ioapic_write_entry(apic_id, pin, entry); |
1629 | } | 1487 | } |
1630 | 1488 | ||
1489 | static struct { | ||
1490 | DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1); | ||
1491 | } mp_ioapic_routing[MAX_IO_APICS]; | ||
1492 | |||
1631 | static void __init setup_IO_APIC_irqs(void) | 1493 | static void __init setup_IO_APIC_irqs(void) |
1632 | { | 1494 | { |
1633 | int apic_id, pin, idx, irq; | 1495 | int apic_id = 0, pin, idx, irq; |
1634 | int notcon = 0; | 1496 | int notcon = 0; |
1635 | struct irq_desc *desc; | 1497 | struct irq_desc *desc; |
1636 | struct irq_cfg *cfg; | 1498 | struct irq_cfg *cfg; |
1637 | int cpu = boot_cpu_id; | 1499 | int node = cpu_to_node(boot_cpu_id); |
1638 | 1500 | ||
1639 | apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); | 1501 | apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); |
1640 | 1502 | ||
1641 | for (apic_id = 0; apic_id < nr_ioapics; apic_id++) { | 1503 | #ifdef CONFIG_ACPI |
1642 | for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) { | 1504 | if (!acpi_disabled && acpi_ioapic) { |
1643 | 1505 | apic_id = mp_find_ioapic(0); | |
1644 | idx = find_irq_entry(apic_id, pin, mp_INT); | 1506 | if (apic_id < 0) |
1645 | if (idx == -1) { | 1507 | apic_id = 0; |
1646 | if (!notcon) { | 1508 | } |
1647 | notcon = 1; | 1509 | #endif |
1648 | apic_printk(APIC_VERBOSE, | ||
1649 | KERN_DEBUG " %d-%d", | ||
1650 | mp_ioapics[apic_id].apicid, pin); | ||
1651 | } else | ||
1652 | apic_printk(APIC_VERBOSE, " %d-%d", | ||
1653 | mp_ioapics[apic_id].apicid, pin); | ||
1654 | continue; | ||
1655 | } | ||
1656 | if (notcon) { | ||
1657 | apic_printk(APIC_VERBOSE, | ||
1658 | " (apicid-pin) not connected\n"); | ||
1659 | notcon = 0; | ||
1660 | } | ||
1661 | 1510 | ||
1662 | irq = pin_2_irq(idx, apic_id, pin); | 1511 | for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) { |
1512 | idx = find_irq_entry(apic_id, pin, mp_INT); | ||
1513 | if (idx == -1) { | ||
1514 | if (!notcon) { | ||
1515 | notcon = 1; | ||
1516 | apic_printk(APIC_VERBOSE, | ||
1517 | KERN_DEBUG " %d-%d", | ||
1518 | mp_ioapics[apic_id].apicid, pin); | ||
1519 | } else | ||
1520 | apic_printk(APIC_VERBOSE, " %d-%d", | ||
1521 | mp_ioapics[apic_id].apicid, pin); | ||
1522 | continue; | ||
1523 | } | ||
1524 | if (notcon) { | ||
1525 | apic_printk(APIC_VERBOSE, | ||
1526 | " (apicid-pin) not connected\n"); | ||
1527 | notcon = 0; | ||
1528 | } | ||
1663 | 1529 | ||
1664 | /* | 1530 | irq = pin_2_irq(idx, apic_id, pin); |
1665 | * Skip the timer IRQ if there's a quirk handler | ||
1666 | * installed and if it returns 1: | ||
1667 | */ | ||
1668 | if (apic->multi_timer_check && | ||
1669 | apic->multi_timer_check(apic_id, irq)) | ||
1670 | continue; | ||
1671 | 1531 | ||
1672 | desc = irq_to_desc_alloc_cpu(irq, cpu); | 1532 | /* |
1673 | if (!desc) { | 1533 | * Skip the timer IRQ if there's a quirk handler |
1674 | printk(KERN_INFO "can not get irq_desc for %d\n", irq); | 1534 | * installed and if it returns 1: |
1675 | continue; | 1535 | */ |
1676 | } | 1536 | if (apic->multi_timer_check && |
1677 | cfg = desc->chip_data; | 1537 | apic->multi_timer_check(apic_id, irq)) |
1678 | add_pin_to_irq_cpu(cfg, cpu, apic_id, pin); | 1538 | continue; |
1679 | 1539 | ||
1680 | setup_IO_APIC_irq(apic_id, pin, irq, desc, | 1540 | desc = irq_to_desc_alloc_node(irq, node); |
1681 | irq_trigger(idx), irq_polarity(idx)); | 1541 | if (!desc) { |
1542 | printk(KERN_INFO "can not get irq_desc for %d\n", irq); | ||
1543 | continue; | ||
1682 | } | 1544 | } |
1545 | cfg = desc->chip_data; | ||
1546 | add_pin_to_irq_node(cfg, node, apic_id, pin); | ||
1547 | /* | ||
1548 | * don't mark it in pin_programmed, so later acpi could | ||
1549 | * set it correctly when irq < 16 | ||
1550 | */ | ||
1551 | setup_IO_APIC_irq(apic_id, pin, irq, desc, | ||
1552 | irq_trigger(idx), irq_polarity(idx)); | ||
1683 | } | 1553 | } |
1684 | 1554 | ||
1685 | if (notcon) | 1555 | if (notcon) |
@@ -1869,7 +1739,7 @@ __apicdebuginit(void) print_APIC_bitfield(int base) | |||
1869 | 1739 | ||
1870 | __apicdebuginit(void) print_local_APIC(void *dummy) | 1740 | __apicdebuginit(void) print_local_APIC(void *dummy) |
1871 | { | 1741 | { |
1872 | unsigned int v, ver, maxlvt; | 1742 | unsigned int i, v, ver, maxlvt; |
1873 | u64 icr; | 1743 | u64 icr; |
1874 | 1744 | ||
1875 | if (apic_verbosity == APIC_QUIET) | 1745 | if (apic_verbosity == APIC_QUIET) |
@@ -1957,6 +1827,18 @@ __apicdebuginit(void) print_local_APIC(void *dummy) | |||
1957 | printk(KERN_DEBUG "... APIC TMCCT: %08x\n", v); | 1827 | printk(KERN_DEBUG "... APIC TMCCT: %08x\n", v); |
1958 | v = apic_read(APIC_TDCR); | 1828 | v = apic_read(APIC_TDCR); |
1959 | printk(KERN_DEBUG "... APIC TDCR: %08x\n", v); | 1829 | printk(KERN_DEBUG "... APIC TDCR: %08x\n", v); |
1830 | |||
1831 | if (boot_cpu_has(X86_FEATURE_EXTAPIC)) { | ||
1832 | v = apic_read(APIC_EFEAT); | ||
1833 | maxlvt = (v >> 16) & 0xff; | ||
1834 | printk(KERN_DEBUG "... APIC EFEAT: %08x\n", v); | ||
1835 | v = apic_read(APIC_ECTRL); | ||
1836 | printk(KERN_DEBUG "... APIC ECTRL: %08x\n", v); | ||
1837 | for (i = 0; i < maxlvt; i++) { | ||
1838 | v = apic_read(APIC_EILVTn(i)); | ||
1839 | printk(KERN_DEBUG "... APIC EILVT%d: %08x\n", i, v); | ||
1840 | } | ||
1841 | } | ||
1960 | printk("\n"); | 1842 | printk("\n"); |
1961 | } | 1843 | } |
1962 | 1844 | ||
@@ -2005,6 +1887,11 @@ __apicdebuginit(void) print_PIC(void) | |||
2005 | __apicdebuginit(int) print_all_ICs(void) | 1887 | __apicdebuginit(int) print_all_ICs(void) |
2006 | { | 1888 | { |
2007 | print_PIC(); | 1889 | print_PIC(); |
1890 | |||
1891 | /* don't print out if apic is not there */ | ||
1892 | if (!cpu_has_apic || disable_apic) | ||
1893 | return 0; | ||
1894 | |||
2008 | print_all_local_APICs(); | 1895 | print_all_local_APICs(); |
2009 | print_IO_APIC(); | 1896 | print_IO_APIC(); |
2010 | 1897 | ||
@@ -2120,7 +2007,9 @@ void disable_IO_APIC(void) | |||
2120 | /* | 2007 | /* |
2121 | * Use virtual wire A mode when interrupt remapping is enabled. | 2008 | * Use virtual wire A mode when interrupt remapping is enabled. |
2122 | */ | 2009 | */ |
2123 | disconnect_bsp_APIC(!intr_remapping_enabled && ioapic_i8259.pin != -1); | 2010 | if (cpu_has_apic) |
2011 | disconnect_bsp_APIC(!intr_remapping_enabled && | ||
2012 | ioapic_i8259.pin != -1); | ||
2124 | } | 2013 | } |
2125 | 2014 | ||
2126 | #ifdef CONFIG_X86_32 | 2015 | #ifdef CONFIG_X86_32 |
@@ -2360,6 +2249,118 @@ static int ioapic_retrigger_irq(unsigned int irq) | |||
2360 | */ | 2249 | */ |
2361 | 2250 | ||
2362 | #ifdef CONFIG_SMP | 2251 | #ifdef CONFIG_SMP |
2252 | static void send_cleanup_vector(struct irq_cfg *cfg) | ||
2253 | { | ||
2254 | cpumask_var_t cleanup_mask; | ||
2255 | |||
2256 | if (unlikely(!alloc_cpumask_var(&cleanup_mask, GFP_ATOMIC))) { | ||
2257 | unsigned int i; | ||
2258 | cfg->move_cleanup_count = 0; | ||
2259 | for_each_cpu_and(i, cfg->old_domain, cpu_online_mask) | ||
2260 | cfg->move_cleanup_count++; | ||
2261 | for_each_cpu_and(i, cfg->old_domain, cpu_online_mask) | ||
2262 | apic->send_IPI_mask(cpumask_of(i), IRQ_MOVE_CLEANUP_VECTOR); | ||
2263 | } else { | ||
2264 | cpumask_and(cleanup_mask, cfg->old_domain, cpu_online_mask); | ||
2265 | cfg->move_cleanup_count = cpumask_weight(cleanup_mask); | ||
2266 | apic->send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR); | ||
2267 | free_cpumask_var(cleanup_mask); | ||
2268 | } | ||
2269 | cfg->move_in_progress = 0; | ||
2270 | } | ||
2271 | |||
2272 | static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg) | ||
2273 | { | ||
2274 | int apic, pin; | ||
2275 | struct irq_pin_list *entry; | ||
2276 | u8 vector = cfg->vector; | ||
2277 | |||
2278 | entry = cfg->irq_2_pin; | ||
2279 | for (;;) { | ||
2280 | unsigned int reg; | ||
2281 | |||
2282 | if (!entry) | ||
2283 | break; | ||
2284 | |||
2285 | apic = entry->apic; | ||
2286 | pin = entry->pin; | ||
2287 | /* | ||
2288 | * With interrupt-remapping, destination information comes | ||
2289 | * from interrupt-remapping table entry. | ||
2290 | */ | ||
2291 | if (!irq_remapped(irq)) | ||
2292 | io_apic_write(apic, 0x11 + pin*2, dest); | ||
2293 | reg = io_apic_read(apic, 0x10 + pin*2); | ||
2294 | reg &= ~IO_APIC_REDIR_VECTOR_MASK; | ||
2295 | reg |= vector; | ||
2296 | io_apic_modify(apic, 0x10 + pin*2, reg); | ||
2297 | if (!entry->next) | ||
2298 | break; | ||
2299 | entry = entry->next; | ||
2300 | } | ||
2301 | } | ||
2302 | |||
2303 | static int | ||
2304 | assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask); | ||
2305 | |||
2306 | /* | ||
2307 | * Either sets desc->affinity to a valid value, and returns | ||
2308 | * ->cpu_mask_to_apicid of that, or returns BAD_APICID and | ||
2309 | * leaves desc->affinity untouched. | ||
2310 | */ | ||
2311 | static unsigned int | ||
2312 | set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask) | ||
2313 | { | ||
2314 | struct irq_cfg *cfg; | ||
2315 | unsigned int irq; | ||
2316 | |||
2317 | if (!cpumask_intersects(mask, cpu_online_mask)) | ||
2318 | return BAD_APICID; | ||
2319 | |||
2320 | irq = desc->irq; | ||
2321 | cfg = desc->chip_data; | ||
2322 | if (assign_irq_vector(irq, cfg, mask)) | ||
2323 | return BAD_APICID; | ||
2324 | |||
2325 | cpumask_copy(desc->affinity, mask); | ||
2326 | |||
2327 | return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain); | ||
2328 | } | ||
2329 | |||
2330 | static int | ||
2331 | set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask) | ||
2332 | { | ||
2333 | struct irq_cfg *cfg; | ||
2334 | unsigned long flags; | ||
2335 | unsigned int dest; | ||
2336 | unsigned int irq; | ||
2337 | int ret = -1; | ||
2338 | |||
2339 | irq = desc->irq; | ||
2340 | cfg = desc->chip_data; | ||
2341 | |||
2342 | spin_lock_irqsave(&ioapic_lock, flags); | ||
2343 | dest = set_desc_affinity(desc, mask); | ||
2344 | if (dest != BAD_APICID) { | ||
2345 | /* Only the high 8 bits are valid. */ | ||
2346 | dest = SET_APIC_LOGICAL_ID(dest); | ||
2347 | __target_IO_APIC_irq(irq, dest, cfg); | ||
2348 | ret = 0; | ||
2349 | } | ||
2350 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
2351 | |||
2352 | return ret; | ||
2353 | } | ||
2354 | |||
2355 | static int | ||
2356 | set_ioapic_affinity_irq(unsigned int irq, const struct cpumask *mask) | ||
2357 | { | ||
2358 | struct irq_desc *desc; | ||
2359 | |||
2360 | desc = irq_to_desc(irq); | ||
2361 | |||
2362 | return set_ioapic_affinity_irq_desc(desc, mask); | ||
2363 | } | ||
2363 | 2364 | ||
2364 | #ifdef CONFIG_INTR_REMAP | 2365 | #ifdef CONFIG_INTR_REMAP |
2365 | 2366 | ||
@@ -2374,26 +2375,25 @@ static int ioapic_retrigger_irq(unsigned int irq) | |||
2374 | * Real vector that is used for interrupting cpu will be coming from | 2375 | * Real vector that is used for interrupting cpu will be coming from |
2375 | * the interrupt-remapping table entry. | 2376 | * the interrupt-remapping table entry. |
2376 | */ | 2377 | */ |
2377 | static void | 2378 | static int |
2378 | migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask) | 2379 | migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask) |
2379 | { | 2380 | { |
2380 | struct irq_cfg *cfg; | 2381 | struct irq_cfg *cfg; |
2381 | struct irte irte; | 2382 | struct irte irte; |
2382 | unsigned int dest; | 2383 | unsigned int dest; |
2383 | unsigned int irq; | 2384 | unsigned int irq; |
2385 | int ret = -1; | ||
2384 | 2386 | ||
2385 | if (!cpumask_intersects(mask, cpu_online_mask)) | 2387 | if (!cpumask_intersects(mask, cpu_online_mask)) |
2386 | return; | 2388 | return ret; |
2387 | 2389 | ||
2388 | irq = desc->irq; | 2390 | irq = desc->irq; |
2389 | if (get_irte(irq, &irte)) | 2391 | if (get_irte(irq, &irte)) |
2390 | return; | 2392 | return ret; |
2391 | 2393 | ||
2392 | cfg = desc->chip_data; | 2394 | cfg = desc->chip_data; |
2393 | if (assign_irq_vector(irq, cfg, mask)) | 2395 | if (assign_irq_vector(irq, cfg, mask)) |
2394 | return; | 2396 | return ret; |
2395 | |||
2396 | set_extra_move_desc(desc, mask); | ||
2397 | 2397 | ||
2398 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask); | 2398 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask); |
2399 | 2399 | ||
@@ -2409,27 +2409,30 @@ migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask) | |||
2409 | send_cleanup_vector(cfg); | 2409 | send_cleanup_vector(cfg); |
2410 | 2410 | ||
2411 | cpumask_copy(desc->affinity, mask); | 2411 | cpumask_copy(desc->affinity, mask); |
2412 | |||
2413 | return 0; | ||
2412 | } | 2414 | } |
2413 | 2415 | ||
2414 | /* | 2416 | /* |
2415 | * Migrates the IRQ destination in the process context. | 2417 | * Migrates the IRQ destination in the process context. |
2416 | */ | 2418 | */ |
2417 | static void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc, | 2419 | static int set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc, |
2418 | const struct cpumask *mask) | 2420 | const struct cpumask *mask) |
2419 | { | 2421 | { |
2420 | migrate_ioapic_irq_desc(desc, mask); | 2422 | return migrate_ioapic_irq_desc(desc, mask); |
2421 | } | 2423 | } |
2422 | static void set_ir_ioapic_affinity_irq(unsigned int irq, | 2424 | static int set_ir_ioapic_affinity_irq(unsigned int irq, |
2423 | const struct cpumask *mask) | 2425 | const struct cpumask *mask) |
2424 | { | 2426 | { |
2425 | struct irq_desc *desc = irq_to_desc(irq); | 2427 | struct irq_desc *desc = irq_to_desc(irq); |
2426 | 2428 | ||
2427 | set_ir_ioapic_affinity_irq_desc(desc, mask); | 2429 | return set_ir_ioapic_affinity_irq_desc(desc, mask); |
2428 | } | 2430 | } |
2429 | #else | 2431 | #else |
2430 | static inline void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc, | 2432 | static inline int set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc, |
2431 | const struct cpumask *mask) | 2433 | const struct cpumask *mask) |
2432 | { | 2434 | { |
2435 | return 0; | ||
2433 | } | 2436 | } |
2434 | #endif | 2437 | #endif |
2435 | 2438 | ||
@@ -2491,86 +2494,19 @@ static void irq_complete_move(struct irq_desc **descp) | |||
2491 | struct irq_cfg *cfg = desc->chip_data; | 2494 | struct irq_cfg *cfg = desc->chip_data; |
2492 | unsigned vector, me; | 2495 | unsigned vector, me; |
2493 | 2496 | ||
2494 | if (likely(!cfg->move_in_progress)) { | 2497 | if (likely(!cfg->move_in_progress)) |
2495 | #ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC | ||
2496 | if (likely(!cfg->move_desc_pending)) | ||
2497 | return; | ||
2498 | |||
2499 | /* domain has not changed, but affinity did */ | ||
2500 | me = smp_processor_id(); | ||
2501 | if (cpumask_test_cpu(me, desc->affinity)) { | ||
2502 | *descp = desc = move_irq_desc(desc, me); | ||
2503 | /* get the new one */ | ||
2504 | cfg = desc->chip_data; | ||
2505 | cfg->move_desc_pending = 0; | ||
2506 | } | ||
2507 | #endif | ||
2508 | return; | 2498 | return; |
2509 | } | ||
2510 | 2499 | ||
2511 | vector = ~get_irq_regs()->orig_ax; | 2500 | vector = ~get_irq_regs()->orig_ax; |
2512 | me = smp_processor_id(); | 2501 | me = smp_processor_id(); |
2513 | 2502 | ||
2514 | if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) { | 2503 | if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) |
2515 | #ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC | ||
2516 | *descp = desc = move_irq_desc(desc, me); | ||
2517 | /* get the new one */ | ||
2518 | cfg = desc->chip_data; | ||
2519 | #endif | ||
2520 | send_cleanup_vector(cfg); | 2504 | send_cleanup_vector(cfg); |
2521 | } | ||
2522 | } | 2505 | } |
2523 | #else | 2506 | #else |
2524 | static inline void irq_complete_move(struct irq_desc **descp) {} | 2507 | static inline void irq_complete_move(struct irq_desc **descp) {} |
2525 | #endif | 2508 | #endif |
2526 | 2509 | ||
2527 | static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) | ||
2528 | { | ||
2529 | int apic, pin; | ||
2530 | struct irq_pin_list *entry; | ||
2531 | |||
2532 | entry = cfg->irq_2_pin; | ||
2533 | for (;;) { | ||
2534 | |||
2535 | if (!entry) | ||
2536 | break; | ||
2537 | |||
2538 | apic = entry->apic; | ||
2539 | pin = entry->pin; | ||
2540 | io_apic_eoi(apic, pin); | ||
2541 | entry = entry->next; | ||
2542 | } | ||
2543 | } | ||
2544 | |||
2545 | static void | ||
2546 | eoi_ioapic_irq(struct irq_desc *desc) | ||
2547 | { | ||
2548 | struct irq_cfg *cfg; | ||
2549 | unsigned long flags; | ||
2550 | unsigned int irq; | ||
2551 | |||
2552 | irq = desc->irq; | ||
2553 | cfg = desc->chip_data; | ||
2554 | |||
2555 | spin_lock_irqsave(&ioapic_lock, flags); | ||
2556 | __eoi_ioapic_irq(irq, cfg); | ||
2557 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
2558 | } | ||
2559 | |||
2560 | #ifdef CONFIG_X86_X2APIC | ||
2561 | static void ack_x2apic_level(unsigned int irq) | ||
2562 | { | ||
2563 | struct irq_desc *desc = irq_to_desc(irq); | ||
2564 | ack_x2APIC_irq(); | ||
2565 | eoi_ioapic_irq(desc); | ||
2566 | } | ||
2567 | |||
2568 | static void ack_x2apic_edge(unsigned int irq) | ||
2569 | { | ||
2570 | ack_x2APIC_irq(); | ||
2571 | } | ||
2572 | #endif | ||
2573 | |||
2574 | static void ack_apic_edge(unsigned int irq) | 2510 | static void ack_apic_edge(unsigned int irq) |
2575 | { | 2511 | { |
2576 | struct irq_desc *desc = irq_to_desc(irq); | 2512 | struct irq_desc *desc = irq_to_desc(irq); |
@@ -2634,9 +2570,6 @@ static void ack_apic_level(unsigned int irq) | |||
2634 | */ | 2570 | */ |
2635 | ack_APIC_irq(); | 2571 | ack_APIC_irq(); |
2636 | 2572 | ||
2637 | if (irq_remapped(irq)) | ||
2638 | eoi_ioapic_irq(desc); | ||
2639 | |||
2640 | /* Now we can move and renable the irq */ | 2573 | /* Now we can move and renable the irq */ |
2641 | if (unlikely(do_unmask_irq)) { | 2574 | if (unlikely(do_unmask_irq)) { |
2642 | /* Only migrate the irq if the ack has been received. | 2575 | /* Only migrate the irq if the ack has been received. |
@@ -2683,22 +2616,50 @@ static void ack_apic_level(unsigned int irq) | |||
2683 | } | 2616 | } |
2684 | 2617 | ||
2685 | #ifdef CONFIG_INTR_REMAP | 2618 | #ifdef CONFIG_INTR_REMAP |
2619 | static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) | ||
2620 | { | ||
2621 | int apic, pin; | ||
2622 | struct irq_pin_list *entry; | ||
2623 | |||
2624 | entry = cfg->irq_2_pin; | ||
2625 | for (;;) { | ||
2626 | |||
2627 | if (!entry) | ||
2628 | break; | ||
2629 | |||
2630 | apic = entry->apic; | ||
2631 | pin = entry->pin; | ||
2632 | io_apic_eoi(apic, pin); | ||
2633 | entry = entry->next; | ||
2634 | } | ||
2635 | } | ||
2636 | |||
2637 | static void | ||
2638 | eoi_ioapic_irq(struct irq_desc *desc) | ||
2639 | { | ||
2640 | struct irq_cfg *cfg; | ||
2641 | unsigned long flags; | ||
2642 | unsigned int irq; | ||
2643 | |||
2644 | irq = desc->irq; | ||
2645 | cfg = desc->chip_data; | ||
2646 | |||
2647 | spin_lock_irqsave(&ioapic_lock, flags); | ||
2648 | __eoi_ioapic_irq(irq, cfg); | ||
2649 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
2650 | } | ||
2651 | |||
2686 | static void ir_ack_apic_edge(unsigned int irq) | 2652 | static void ir_ack_apic_edge(unsigned int irq) |
2687 | { | 2653 | { |
2688 | #ifdef CONFIG_X86_X2APIC | 2654 | ack_APIC_irq(); |
2689 | if (x2apic_enabled()) | ||
2690 | return ack_x2apic_edge(irq); | ||
2691 | #endif | ||
2692 | return ack_apic_edge(irq); | ||
2693 | } | 2655 | } |
2694 | 2656 | ||
2695 | static void ir_ack_apic_level(unsigned int irq) | 2657 | static void ir_ack_apic_level(unsigned int irq) |
2696 | { | 2658 | { |
2697 | #ifdef CONFIG_X86_X2APIC | 2659 | struct irq_desc *desc = irq_to_desc(irq); |
2698 | if (x2apic_enabled()) | 2660 | |
2699 | return ack_x2apic_level(irq); | 2661 | ack_APIC_irq(); |
2700 | #endif | 2662 | eoi_ioapic_irq(desc); |
2701 | return ack_apic_level(irq); | ||
2702 | } | 2663 | } |
2703 | #endif /* CONFIG_INTR_REMAP */ | 2664 | #endif /* CONFIG_INTR_REMAP */ |
2704 | 2665 | ||
@@ -2903,7 +2864,7 @@ static inline void __init check_timer(void) | |||
2903 | { | 2864 | { |
2904 | struct irq_desc *desc = irq_to_desc(0); | 2865 | struct irq_desc *desc = irq_to_desc(0); |
2905 | struct irq_cfg *cfg = desc->chip_data; | 2866 | struct irq_cfg *cfg = desc->chip_data; |
2906 | int cpu = boot_cpu_id; | 2867 | int node = cpu_to_node(boot_cpu_id); |
2907 | int apic1, pin1, apic2, pin2; | 2868 | int apic1, pin1, apic2, pin2; |
2908 | unsigned long flags; | 2869 | unsigned long flags; |
2909 | int no_pin1 = 0; | 2870 | int no_pin1 = 0; |
@@ -2969,7 +2930,7 @@ static inline void __init check_timer(void) | |||
2969 | * Ok, does IRQ0 through the IOAPIC work? | 2930 | * Ok, does IRQ0 through the IOAPIC work? |
2970 | */ | 2931 | */ |
2971 | if (no_pin1) { | 2932 | if (no_pin1) { |
2972 | add_pin_to_irq_cpu(cfg, cpu, apic1, pin1); | 2933 | add_pin_to_irq_node(cfg, node, apic1, pin1); |
2973 | setup_timer_IRQ0_pin(apic1, pin1, cfg->vector); | 2934 | setup_timer_IRQ0_pin(apic1, pin1, cfg->vector); |
2974 | } else { | 2935 | } else { |
2975 | /* for edge trigger, setup_IO_APIC_irq already | 2936 | /* for edge trigger, setup_IO_APIC_irq already |
@@ -3006,7 +2967,7 @@ static inline void __init check_timer(void) | |||
3006 | /* | 2967 | /* |
3007 | * legacy devices should be connected to IO APIC #0 | 2968 | * legacy devices should be connected to IO APIC #0 |
3008 | */ | 2969 | */ |
3009 | replace_pin_at_irq_cpu(cfg, cpu, apic1, pin1, apic2, pin2); | 2970 | replace_pin_at_irq_node(cfg, node, apic1, pin1, apic2, pin2); |
3010 | setup_timer_IRQ0_pin(apic2, pin2, cfg->vector); | 2971 | setup_timer_IRQ0_pin(apic2, pin2, cfg->vector); |
3011 | enable_8259A_irq(0); | 2972 | enable_8259A_irq(0); |
3012 | if (timer_irq_works()) { | 2973 | if (timer_irq_works()) { |
@@ -3218,14 +3179,13 @@ static int nr_irqs_gsi = NR_IRQS_LEGACY; | |||
3218 | /* | 3179 | /* |
3219 | * Dynamic irq allocate and deallocation | 3180 | * Dynamic irq allocate and deallocation |
3220 | */ | 3181 | */ |
3221 | unsigned int create_irq_nr(unsigned int irq_want) | 3182 | unsigned int create_irq_nr(unsigned int irq_want, int node) |
3222 | { | 3183 | { |
3223 | /* Allocate an unused irq */ | 3184 | /* Allocate an unused irq */ |
3224 | unsigned int irq; | 3185 | unsigned int irq; |
3225 | unsigned int new; | 3186 | unsigned int new; |
3226 | unsigned long flags; | 3187 | unsigned long flags; |
3227 | struct irq_cfg *cfg_new = NULL; | 3188 | struct irq_cfg *cfg_new = NULL; |
3228 | int cpu = boot_cpu_id; | ||
3229 | struct irq_desc *desc_new = NULL; | 3189 | struct irq_desc *desc_new = NULL; |
3230 | 3190 | ||
3231 | irq = 0; | 3191 | irq = 0; |
@@ -3234,7 +3194,7 @@ unsigned int create_irq_nr(unsigned int irq_want) | |||
3234 | 3194 | ||
3235 | spin_lock_irqsave(&vector_lock, flags); | 3195 | spin_lock_irqsave(&vector_lock, flags); |
3236 | for (new = irq_want; new < nr_irqs; new++) { | 3196 | for (new = irq_want; new < nr_irqs; new++) { |
3237 | desc_new = irq_to_desc_alloc_cpu(new, cpu); | 3197 | desc_new = irq_to_desc_alloc_node(new, node); |
3238 | if (!desc_new) { | 3198 | if (!desc_new) { |
3239 | printk(KERN_INFO "can not get irq_desc for %d\n", new); | 3199 | printk(KERN_INFO "can not get irq_desc for %d\n", new); |
3240 | continue; | 3200 | continue; |
@@ -3243,6 +3203,9 @@ unsigned int create_irq_nr(unsigned int irq_want) | |||
3243 | 3203 | ||
3244 | if (cfg_new->vector != 0) | 3204 | if (cfg_new->vector != 0) |
3245 | continue; | 3205 | continue; |
3206 | |||
3207 | desc_new = move_irq_desc(desc_new, node); | ||
3208 | |||
3246 | if (__assign_irq_vector(new, cfg_new, apic->target_cpus()) == 0) | 3209 | if (__assign_irq_vector(new, cfg_new, apic->target_cpus()) == 0) |
3247 | irq = new; | 3210 | irq = new; |
3248 | break; | 3211 | break; |
@@ -3260,11 +3223,12 @@ unsigned int create_irq_nr(unsigned int irq_want) | |||
3260 | 3223 | ||
3261 | int create_irq(void) | 3224 | int create_irq(void) |
3262 | { | 3225 | { |
3226 | int node = cpu_to_node(boot_cpu_id); | ||
3263 | unsigned int irq_want; | 3227 | unsigned int irq_want; |
3264 | int irq; | 3228 | int irq; |
3265 | 3229 | ||
3266 | irq_want = nr_irqs_gsi; | 3230 | irq_want = nr_irqs_gsi; |
3267 | irq = create_irq_nr(irq_want); | 3231 | irq = create_irq_nr(irq_want, node); |
3268 | 3232 | ||
3269 | if (irq == 0) | 3233 | if (irq == 0) |
3270 | irq = -1; | 3234 | irq = -1; |
@@ -3329,6 +3293,9 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms | |||
3329 | irte.vector = cfg->vector; | 3293 | irte.vector = cfg->vector; |
3330 | irte.dest_id = IRTE_DEST(dest); | 3294 | irte.dest_id = IRTE_DEST(dest); |
3331 | 3295 | ||
3296 | /* Set source-id of interrupt request */ | ||
3297 | set_msi_sid(&irte, pdev); | ||
3298 | |||
3332 | modify_irte(irq, &irte); | 3299 | modify_irte(irq, &irte); |
3333 | 3300 | ||
3334 | msg->address_hi = MSI_ADDR_BASE_HI; | 3301 | msg->address_hi = MSI_ADDR_BASE_HI; |
@@ -3366,7 +3333,7 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms | |||
3366 | } | 3333 | } |
3367 | 3334 | ||
3368 | #ifdef CONFIG_SMP | 3335 | #ifdef CONFIG_SMP |
3369 | static void set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask) | 3336 | static int set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask) |
3370 | { | 3337 | { |
3371 | struct irq_desc *desc = irq_to_desc(irq); | 3338 | struct irq_desc *desc = irq_to_desc(irq); |
3372 | struct irq_cfg *cfg; | 3339 | struct irq_cfg *cfg; |
@@ -3375,7 +3342,7 @@ static void set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask) | |||
3375 | 3342 | ||
3376 | dest = set_desc_affinity(desc, mask); | 3343 | dest = set_desc_affinity(desc, mask); |
3377 | if (dest == BAD_APICID) | 3344 | if (dest == BAD_APICID) |
3378 | return; | 3345 | return -1; |
3379 | 3346 | ||
3380 | cfg = desc->chip_data; | 3347 | cfg = desc->chip_data; |
3381 | 3348 | ||
@@ -3387,13 +3354,15 @@ static void set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask) | |||
3387 | msg.address_lo |= MSI_ADDR_DEST_ID(dest); | 3354 | msg.address_lo |= MSI_ADDR_DEST_ID(dest); |
3388 | 3355 | ||
3389 | write_msi_msg_desc(desc, &msg); | 3356 | write_msi_msg_desc(desc, &msg); |
3357 | |||
3358 | return 0; | ||
3390 | } | 3359 | } |
3391 | #ifdef CONFIG_INTR_REMAP | 3360 | #ifdef CONFIG_INTR_REMAP |
3392 | /* | 3361 | /* |
3393 | * Migrate the MSI irq to another cpumask. This migration is | 3362 | * Migrate the MSI irq to another cpumask. This migration is |
3394 | * done in the process context using interrupt-remapping hardware. | 3363 | * done in the process context using interrupt-remapping hardware. |
3395 | */ | 3364 | */ |
3396 | static void | 3365 | static int |
3397 | ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask) | 3366 | ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask) |
3398 | { | 3367 | { |
3399 | struct irq_desc *desc = irq_to_desc(irq); | 3368 | struct irq_desc *desc = irq_to_desc(irq); |
@@ -3402,11 +3371,11 @@ ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask) | |||
3402 | struct irte irte; | 3371 | struct irte irte; |
3403 | 3372 | ||
3404 | if (get_irte(irq, &irte)) | 3373 | if (get_irte(irq, &irte)) |
3405 | return; | 3374 | return -1; |
3406 | 3375 | ||
3407 | dest = set_desc_affinity(desc, mask); | 3376 | dest = set_desc_affinity(desc, mask); |
3408 | if (dest == BAD_APICID) | 3377 | if (dest == BAD_APICID) |
3409 | return; | 3378 | return -1; |
3410 | 3379 | ||
3411 | irte.vector = cfg->vector; | 3380 | irte.vector = cfg->vector; |
3412 | irte.dest_id = IRTE_DEST(dest); | 3381 | irte.dest_id = IRTE_DEST(dest); |
@@ -3423,6 +3392,8 @@ ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask) | |||
3423 | */ | 3392 | */ |
3424 | if (cfg->move_in_progress) | 3393 | if (cfg->move_in_progress) |
3425 | send_cleanup_vector(cfg); | 3394 | send_cleanup_vector(cfg); |
3395 | |||
3396 | return 0; | ||
3426 | } | 3397 | } |
3427 | 3398 | ||
3428 | #endif | 3399 | #endif |
@@ -3518,15 +3489,17 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
3518 | unsigned int irq_want; | 3489 | unsigned int irq_want; |
3519 | struct intel_iommu *iommu = NULL; | 3490 | struct intel_iommu *iommu = NULL; |
3520 | int index = 0; | 3491 | int index = 0; |
3492 | int node; | ||
3521 | 3493 | ||
3522 | /* x86 doesn't support multiple MSI yet */ | 3494 | /* x86 doesn't support multiple MSI yet */ |
3523 | if (type == PCI_CAP_ID_MSI && nvec > 1) | 3495 | if (type == PCI_CAP_ID_MSI && nvec > 1) |
3524 | return 1; | 3496 | return 1; |
3525 | 3497 | ||
3498 | node = dev_to_node(&dev->dev); | ||
3526 | irq_want = nr_irqs_gsi; | 3499 | irq_want = nr_irqs_gsi; |
3527 | sub_handle = 0; | 3500 | sub_handle = 0; |
3528 | list_for_each_entry(msidesc, &dev->msi_list, list) { | 3501 | list_for_each_entry(msidesc, &dev->msi_list, list) { |
3529 | irq = create_irq_nr(irq_want); | 3502 | irq = create_irq_nr(irq_want, node); |
3530 | if (irq == 0) | 3503 | if (irq == 0) |
3531 | return -1; | 3504 | return -1; |
3532 | irq_want = irq + 1; | 3505 | irq_want = irq + 1; |
@@ -3576,7 +3549,7 @@ void arch_teardown_msi_irq(unsigned int irq) | |||
3576 | 3549 | ||
3577 | #if defined (CONFIG_DMAR) || defined (CONFIG_INTR_REMAP) | 3550 | #if defined (CONFIG_DMAR) || defined (CONFIG_INTR_REMAP) |
3578 | #ifdef CONFIG_SMP | 3551 | #ifdef CONFIG_SMP |
3579 | static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask) | 3552 | static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask) |
3580 | { | 3553 | { |
3581 | struct irq_desc *desc = irq_to_desc(irq); | 3554 | struct irq_desc *desc = irq_to_desc(irq); |
3582 | struct irq_cfg *cfg; | 3555 | struct irq_cfg *cfg; |
@@ -3585,7 +3558,7 @@ static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask) | |||
3585 | 3558 | ||
3586 | dest = set_desc_affinity(desc, mask); | 3559 | dest = set_desc_affinity(desc, mask); |
3587 | if (dest == BAD_APICID) | 3560 | if (dest == BAD_APICID) |
3588 | return; | 3561 | return -1; |
3589 | 3562 | ||
3590 | cfg = desc->chip_data; | 3563 | cfg = desc->chip_data; |
3591 | 3564 | ||
@@ -3597,11 +3570,13 @@ static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask) | |||
3597 | msg.address_lo |= MSI_ADDR_DEST_ID(dest); | 3570 | msg.address_lo |= MSI_ADDR_DEST_ID(dest); |
3598 | 3571 | ||
3599 | dmar_msi_write(irq, &msg); | 3572 | dmar_msi_write(irq, &msg); |
3573 | |||
3574 | return 0; | ||
3600 | } | 3575 | } |
3601 | 3576 | ||
3602 | #endif /* CONFIG_SMP */ | 3577 | #endif /* CONFIG_SMP */ |
3603 | 3578 | ||
3604 | struct irq_chip dmar_msi_type = { | 3579 | static struct irq_chip dmar_msi_type = { |
3605 | .name = "DMAR_MSI", | 3580 | .name = "DMAR_MSI", |
3606 | .unmask = dmar_msi_unmask, | 3581 | .unmask = dmar_msi_unmask, |
3607 | .mask = dmar_msi_mask, | 3582 | .mask = dmar_msi_mask, |
@@ -3630,7 +3605,7 @@ int arch_setup_dmar_msi(unsigned int irq) | |||
3630 | #ifdef CONFIG_HPET_TIMER | 3605 | #ifdef CONFIG_HPET_TIMER |
3631 | 3606 | ||
3632 | #ifdef CONFIG_SMP | 3607 | #ifdef CONFIG_SMP |
3633 | static void hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask) | 3608 | static int hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask) |
3634 | { | 3609 | { |
3635 | struct irq_desc *desc = irq_to_desc(irq); | 3610 | struct irq_desc *desc = irq_to_desc(irq); |
3636 | struct irq_cfg *cfg; | 3611 | struct irq_cfg *cfg; |
@@ -3639,7 +3614,7 @@ static void hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask) | |||
3639 | 3614 | ||
3640 | dest = set_desc_affinity(desc, mask); | 3615 | dest = set_desc_affinity(desc, mask); |
3641 | if (dest == BAD_APICID) | 3616 | if (dest == BAD_APICID) |
3642 | return; | 3617 | return -1; |
3643 | 3618 | ||
3644 | cfg = desc->chip_data; | 3619 | cfg = desc->chip_data; |
3645 | 3620 | ||
@@ -3651,6 +3626,8 @@ static void hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask) | |||
3651 | msg.address_lo |= MSI_ADDR_DEST_ID(dest); | 3626 | msg.address_lo |= MSI_ADDR_DEST_ID(dest); |
3652 | 3627 | ||
3653 | hpet_msi_write(irq, &msg); | 3628 | hpet_msi_write(irq, &msg); |
3629 | |||
3630 | return 0; | ||
3654 | } | 3631 | } |
3655 | 3632 | ||
3656 | #endif /* CONFIG_SMP */ | 3633 | #endif /* CONFIG_SMP */ |
@@ -3707,7 +3684,7 @@ static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector) | |||
3707 | write_ht_irq_msg(irq, &msg); | 3684 | write_ht_irq_msg(irq, &msg); |
3708 | } | 3685 | } |
3709 | 3686 | ||
3710 | static void set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask) | 3687 | static int set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask) |
3711 | { | 3688 | { |
3712 | struct irq_desc *desc = irq_to_desc(irq); | 3689 | struct irq_desc *desc = irq_to_desc(irq); |
3713 | struct irq_cfg *cfg; | 3690 | struct irq_cfg *cfg; |
@@ -3715,11 +3692,13 @@ static void set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask) | |||
3715 | 3692 | ||
3716 | dest = set_desc_affinity(desc, mask); | 3693 | dest = set_desc_affinity(desc, mask); |
3717 | if (dest == BAD_APICID) | 3694 | if (dest == BAD_APICID) |
3718 | return; | 3695 | return -1; |
3719 | 3696 | ||
3720 | cfg = desc->chip_data; | 3697 | cfg = desc->chip_data; |
3721 | 3698 | ||
3722 | target_ht_irq(irq, dest, cfg->vector); | 3699 | target_ht_irq(irq, dest, cfg->vector); |
3700 | |||
3701 | return 0; | ||
3723 | } | 3702 | } |
3724 | 3703 | ||
3725 | #endif | 3704 | #endif |
@@ -3794,6 +3773,8 @@ int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, | |||
3794 | unsigned long flags; | 3773 | unsigned long flags; |
3795 | int err; | 3774 | int err; |
3796 | 3775 | ||
3776 | BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long)); | ||
3777 | |||
3797 | cfg = irq_cfg(irq); | 3778 | cfg = irq_cfg(irq); |
3798 | 3779 | ||
3799 | err = assign_irq_vector(irq, cfg, eligible_cpu); | 3780 | err = assign_irq_vector(irq, cfg, eligible_cpu); |
@@ -3807,15 +3788,13 @@ int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, | |||
3807 | 3788 | ||
3808 | mmr_value = 0; | 3789 | mmr_value = 0; |
3809 | entry = (struct uv_IO_APIC_route_entry *)&mmr_value; | 3790 | entry = (struct uv_IO_APIC_route_entry *)&mmr_value; |
3810 | BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long)); | 3791 | entry->vector = cfg->vector; |
3811 | 3792 | entry->delivery_mode = apic->irq_delivery_mode; | |
3812 | entry->vector = cfg->vector; | 3793 | entry->dest_mode = apic->irq_dest_mode; |
3813 | entry->delivery_mode = apic->irq_delivery_mode; | 3794 | entry->polarity = 0; |
3814 | entry->dest_mode = apic->irq_dest_mode; | 3795 | entry->trigger = 0; |
3815 | entry->polarity = 0; | 3796 | entry->mask = 0; |
3816 | entry->trigger = 0; | 3797 | entry->dest = apic->cpu_mask_to_apicid(eligible_cpu); |
3817 | entry->mask = 0; | ||
3818 | entry->dest = apic->cpu_mask_to_apicid(eligible_cpu); | ||
3819 | 3798 | ||
3820 | mmr_pnode = uv_blade_to_pnode(mmr_blade); | 3799 | mmr_pnode = uv_blade_to_pnode(mmr_blade); |
3821 | uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); | 3800 | uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); |
@@ -3833,10 +3812,10 @@ void arch_disable_uv_irq(int mmr_blade, unsigned long mmr_offset) | |||
3833 | struct uv_IO_APIC_route_entry *entry; | 3812 | struct uv_IO_APIC_route_entry *entry; |
3834 | int mmr_pnode; | 3813 | int mmr_pnode; |
3835 | 3814 | ||
3815 | BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long)); | ||
3816 | |||
3836 | mmr_value = 0; | 3817 | mmr_value = 0; |
3837 | entry = (struct uv_IO_APIC_route_entry *)&mmr_value; | 3818 | entry = (struct uv_IO_APIC_route_entry *)&mmr_value; |
3838 | BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long)); | ||
3839 | |||
3840 | entry->mask = 1; | 3819 | entry->mask = 1; |
3841 | 3820 | ||
3842 | mmr_pnode = uv_blade_to_pnode(mmr_blade); | 3821 | mmr_pnode = uv_blade_to_pnode(mmr_blade); |
@@ -3900,6 +3879,71 @@ int __init arch_probe_nr_irqs(void) | |||
3900 | } | 3879 | } |
3901 | #endif | 3880 | #endif |
3902 | 3881 | ||
3882 | static int __io_apic_set_pci_routing(struct device *dev, int irq, | ||
3883 | struct io_apic_irq_attr *irq_attr) | ||
3884 | { | ||
3885 | struct irq_desc *desc; | ||
3886 | struct irq_cfg *cfg; | ||
3887 | int node; | ||
3888 | int ioapic, pin; | ||
3889 | int trigger, polarity; | ||
3890 | |||
3891 | ioapic = irq_attr->ioapic; | ||
3892 | if (!IO_APIC_IRQ(irq)) { | ||
3893 | apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n", | ||
3894 | ioapic); | ||
3895 | return -EINVAL; | ||
3896 | } | ||
3897 | |||
3898 | if (dev) | ||
3899 | node = dev_to_node(dev); | ||
3900 | else | ||
3901 | node = cpu_to_node(boot_cpu_id); | ||
3902 | |||
3903 | desc = irq_to_desc_alloc_node(irq, node); | ||
3904 | if (!desc) { | ||
3905 | printk(KERN_INFO "can not get irq_desc %d\n", irq); | ||
3906 | return 0; | ||
3907 | } | ||
3908 | |||
3909 | pin = irq_attr->ioapic_pin; | ||
3910 | trigger = irq_attr->trigger; | ||
3911 | polarity = irq_attr->polarity; | ||
3912 | |||
3913 | /* | ||
3914 | * IRQs < 16 are already in the irq_2_pin[] map | ||
3915 | */ | ||
3916 | if (irq >= NR_IRQS_LEGACY) { | ||
3917 | cfg = desc->chip_data; | ||
3918 | add_pin_to_irq_node(cfg, node, ioapic, pin); | ||
3919 | } | ||
3920 | |||
3921 | setup_IO_APIC_irq(ioapic, pin, irq, desc, trigger, polarity); | ||
3922 | |||
3923 | return 0; | ||
3924 | } | ||
3925 | |||
3926 | int io_apic_set_pci_routing(struct device *dev, int irq, | ||
3927 | struct io_apic_irq_attr *irq_attr) | ||
3928 | { | ||
3929 | int ioapic, pin; | ||
3930 | /* | ||
3931 | * Avoid pin reprogramming. PRTs typically include entries | ||
3932 | * with redundant pin->gsi mappings (but unique PCI devices); | ||
3933 | * we only program the IOAPIC on the first. | ||
3934 | */ | ||
3935 | ioapic = irq_attr->ioapic; | ||
3936 | pin = irq_attr->ioapic_pin; | ||
3937 | if (test_bit(pin, mp_ioapic_routing[ioapic].pin_programmed)) { | ||
3938 | pr_debug("Pin %d-%d already programmed\n", | ||
3939 | mp_ioapics[ioapic].apicid, pin); | ||
3940 | return 0; | ||
3941 | } | ||
3942 | set_bit(pin, mp_ioapic_routing[ioapic].pin_programmed); | ||
3943 | |||
3944 | return __io_apic_set_pci_routing(dev, irq, irq_attr); | ||
3945 | } | ||
3946 | |||
3903 | /* -------------------------------------------------------------------------- | 3947 | /* -------------------------------------------------------------------------- |
3904 | ACPI-based IOAPIC Configuration | 3948 | ACPI-based IOAPIC Configuration |
3905 | -------------------------------------------------------------------------- */ | 3949 | -------------------------------------------------------------------------- */ |
@@ -3980,6 +4024,7 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id) | |||
3980 | 4024 | ||
3981 | return apic_id; | 4025 | return apic_id; |
3982 | } | 4026 | } |
4027 | #endif | ||
3983 | 4028 | ||
3984 | int __init io_apic_get_version(int ioapic) | 4029 | int __init io_apic_get_version(int ioapic) |
3985 | { | 4030 | { |
@@ -3992,39 +4037,6 @@ int __init io_apic_get_version(int ioapic) | |||
3992 | 4037 | ||
3993 | return reg_01.bits.version; | 4038 | return reg_01.bits.version; |
3994 | } | 4039 | } |
3995 | #endif | ||
3996 | |||
3997 | int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int polarity) | ||
3998 | { | ||
3999 | struct irq_desc *desc; | ||
4000 | struct irq_cfg *cfg; | ||
4001 | int cpu = boot_cpu_id; | ||
4002 | |||
4003 | if (!IO_APIC_IRQ(irq)) { | ||
4004 | apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n", | ||
4005 | ioapic); | ||
4006 | return -EINVAL; | ||
4007 | } | ||
4008 | |||
4009 | desc = irq_to_desc_alloc_cpu(irq, cpu); | ||
4010 | if (!desc) { | ||
4011 | printk(KERN_INFO "can not get irq_desc %d\n", irq); | ||
4012 | return 0; | ||
4013 | } | ||
4014 | |||
4015 | /* | ||
4016 | * IRQs < 16 are already in the irq_2_pin[] map | ||
4017 | */ | ||
4018 | if (irq >= NR_IRQS_LEGACY) { | ||
4019 | cfg = desc->chip_data; | ||
4020 | add_pin_to_irq_cpu(cfg, cpu, ioapic, pin); | ||
4021 | } | ||
4022 | |||
4023 | setup_IO_APIC_irq(ioapic, pin, irq, desc, triggering, polarity); | ||
4024 | |||
4025 | return 0; | ||
4026 | } | ||
4027 | |||
4028 | 4040 | ||
4029 | int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity) | 4041 | int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity) |
4030 | { | 4042 | { |
@@ -4055,51 +4067,44 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity) | |||
4055 | #ifdef CONFIG_SMP | 4067 | #ifdef CONFIG_SMP |
4056 | void __init setup_ioapic_dest(void) | 4068 | void __init setup_ioapic_dest(void) |
4057 | { | 4069 | { |
4058 | int pin, ioapic, irq, irq_entry; | 4070 | int pin, ioapic = 0, irq, irq_entry; |
4059 | struct irq_desc *desc; | 4071 | struct irq_desc *desc; |
4060 | struct irq_cfg *cfg; | ||
4061 | const struct cpumask *mask; | 4072 | const struct cpumask *mask; |
4062 | 4073 | ||
4063 | if (skip_ioapic_setup == 1) | 4074 | if (skip_ioapic_setup == 1) |
4064 | return; | 4075 | return; |
4065 | 4076 | ||
4066 | for (ioapic = 0; ioapic < nr_ioapics; ioapic++) { | 4077 | #ifdef CONFIG_ACPI |
4067 | for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) { | 4078 | if (!acpi_disabled && acpi_ioapic) { |
4068 | irq_entry = find_irq_entry(ioapic, pin, mp_INT); | 4079 | ioapic = mp_find_ioapic(0); |
4069 | if (irq_entry == -1) | 4080 | if (ioapic < 0) |
4070 | continue; | 4081 | ioapic = 0; |
4071 | irq = pin_2_irq(irq_entry, ioapic, pin); | 4082 | } |
4072 | 4083 | #endif | |
4073 | /* setup_IO_APIC_irqs could fail to get vector for some device | ||
4074 | * when you have too many devices, because at that time only boot | ||
4075 | * cpu is online. | ||
4076 | */ | ||
4077 | desc = irq_to_desc(irq); | ||
4078 | cfg = desc->chip_data; | ||
4079 | if (!cfg->vector) { | ||
4080 | setup_IO_APIC_irq(ioapic, pin, irq, desc, | ||
4081 | irq_trigger(irq_entry), | ||
4082 | irq_polarity(irq_entry)); | ||
4083 | continue; | ||
4084 | 4084 | ||
4085 | } | 4085 | for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) { |
4086 | irq_entry = find_irq_entry(ioapic, pin, mp_INT); | ||
4087 | if (irq_entry == -1) | ||
4088 | continue; | ||
4089 | irq = pin_2_irq(irq_entry, ioapic, pin); | ||
4086 | 4090 | ||
4087 | /* | 4091 | desc = irq_to_desc(irq); |
4088 | * Honour affinities which have been set in early boot | ||
4089 | */ | ||
4090 | if (desc->status & | ||
4091 | (IRQ_NO_BALANCING | IRQ_AFFINITY_SET)) | ||
4092 | mask = desc->affinity; | ||
4093 | else | ||
4094 | mask = apic->target_cpus(); | ||
4095 | 4092 | ||
4096 | if (intr_remapping_enabled) | 4093 | /* |
4097 | set_ir_ioapic_affinity_irq_desc(desc, mask); | 4094 | * Honour affinities which have been set in early boot |
4098 | else | 4095 | */ |
4099 | set_ioapic_affinity_irq_desc(desc, mask); | 4096 | if (desc->status & |
4100 | } | 4097 | (IRQ_NO_BALANCING | IRQ_AFFINITY_SET)) |
4098 | mask = desc->affinity; | ||
4099 | else | ||
4100 | mask = apic->target_cpus(); | ||
4101 | 4101 | ||
4102 | if (intr_remapping_enabled) | ||
4103 | set_ir_ioapic_affinity_irq_desc(desc, mask); | ||
4104 | else | ||
4105 | set_ioapic_affinity_irq_desc(desc, mask); | ||
4102 | } | 4106 | } |
4107 | |||
4103 | } | 4108 | } |
4104 | #endif | 4109 | #endif |
4105 | 4110 | ||
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c index ce4fbfa315a1..b3025b43b63a 100644 --- a/arch/x86/kernel/apic/nmi.c +++ b/arch/x86/kernel/apic/nmi.c | |||
@@ -66,7 +66,7 @@ static inline unsigned int get_nmi_count(int cpu) | |||
66 | 66 | ||
67 | static inline int mce_in_progress(void) | 67 | static inline int mce_in_progress(void) |
68 | { | 68 | { |
69 | #if defined(CONFIG_X86_64) && defined(CONFIG_X86_MCE) | 69 | #if defined(CONFIG_X86_NEW_MCE) |
70 | return atomic_read(&mce_entry) > 0; | 70 | return atomic_read(&mce_entry) > 0; |
71 | #endif | 71 | #endif |
72 | return 0; | 72 | return 0; |
@@ -104,7 +104,7 @@ static __init void nmi_cpu_busy(void *data) | |||
104 | } | 104 | } |
105 | #endif | 105 | #endif |
106 | 106 | ||
107 | static void report_broken_nmi(int cpu, int *prev_nmi_count) | 107 | static void report_broken_nmi(int cpu, unsigned int *prev_nmi_count) |
108 | { | 108 | { |
109 | printk(KERN_CONT "\n"); | 109 | printk(KERN_CONT "\n"); |
110 | 110 | ||
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index 01eda2ac65e4..0c0182cc947d 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c | |||
@@ -20,23 +20,12 @@ | |||
20 | #include <asm/apic.h> | 20 | #include <asm/apic.h> |
21 | #include <asm/setup.h> | 21 | #include <asm/setup.h> |
22 | 22 | ||
23 | #include <linux/threads.h> | ||
24 | #include <linux/cpumask.h> | ||
25 | #include <asm/mpspec.h> | ||
26 | #include <asm/fixmap.h> | ||
27 | #include <asm/apicdef.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/string.h> | ||
30 | #include <linux/smp.h> | 23 | #include <linux/smp.h> |
31 | #include <linux/init.h> | ||
32 | #include <asm/ipi.h> | 24 | #include <asm/ipi.h> |
33 | 25 | ||
34 | #include <linux/smp.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
37 | #include <asm/acpi.h> | 27 | #include <asm/acpi.h> |
38 | #include <asm/e820.h> | 28 | #include <asm/e820.h> |
39 | #include <asm/setup.h> | ||
40 | 29 | ||
41 | #ifdef CONFIG_HOTPLUG_CPU | 30 | #ifdef CONFIG_HOTPLUG_CPU |
42 | #define DEFAULT_SEND_IPI (1) | 31 | #define DEFAULT_SEND_IPI (1) |
@@ -160,7 +149,6 @@ extern struct apic apic_summit; | |||
160 | extern struct apic apic_bigsmp; | 149 | extern struct apic apic_bigsmp; |
161 | extern struct apic apic_es7000; | 150 | extern struct apic apic_es7000; |
162 | extern struct apic apic_es7000_cluster; | 151 | extern struct apic apic_es7000_cluster; |
163 | extern struct apic apic_default; | ||
164 | 152 | ||
165 | struct apic *apic = &apic_default; | 153 | struct apic *apic = &apic_default; |
166 | EXPORT_SYMBOL_GPL(apic); | 154 | EXPORT_SYMBOL_GPL(apic); |
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c index 1783652bb0e5..bc3e880f9b82 100644 --- a/arch/x86/kernel/apic/probe_64.c +++ b/arch/x86/kernel/apic/probe_64.c | |||
@@ -50,7 +50,7 @@ static struct apic *apic_probe[] __initdata = { | |||
50 | void __init default_setup_apic_routing(void) | 50 | void __init default_setup_apic_routing(void) |
51 | { | 51 | { |
52 | #ifdef CONFIG_X86_X2APIC | 52 | #ifdef CONFIG_X86_X2APIC |
53 | if (x2apic && (apic != &apic_x2apic_phys && | 53 | if (x2apic_mode && (apic != &apic_x2apic_phys && |
54 | #ifdef CONFIG_X86_UV | 54 | #ifdef CONFIG_X86_UV |
55 | apic != &apic_x2apic_uv_x && | 55 | apic != &apic_x2apic_uv_x && |
56 | #endif | 56 | #endif |
diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index 9cfe1f415d81..eafdfbd1ea95 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c | |||
@@ -44,7 +44,6 @@ | |||
44 | #include <asm/ipi.h> | 44 | #include <asm/ipi.h> |
45 | #include <linux/kernel.h> | 45 | #include <linux/kernel.h> |
46 | #include <linux/string.h> | 46 | #include <linux/string.h> |
47 | #include <linux/init.h> | ||
48 | #include <linux/gfp.h> | 47 | #include <linux/gfp.h> |
49 | #include <linux/smp.h> | 48 | #include <linux/smp.h> |
50 | 49 | ||
@@ -173,13 +172,6 @@ static inline int is_WPEG(struct rio_detail *rio){ | |||
173 | rio->type == LookOutAWPEG || rio->type == LookOutBWPEG); | 172 | rio->type == LookOutAWPEG || rio->type == LookOutBWPEG); |
174 | } | 173 | } |
175 | 174 | ||
176 | |||
177 | /* In clustered mode, the high nibble of APIC ID is a cluster number. | ||
178 | * The low nibble is a 4-bit bitmap. */ | ||
179 | #define XAPIC_DEST_CPUS_SHIFT 4 | ||
180 | #define XAPIC_DEST_CPUS_MASK ((1u << XAPIC_DEST_CPUS_SHIFT) - 1) | ||
181 | #define XAPIC_DEST_CLUSTER_MASK (XAPIC_DEST_CPUS_MASK << XAPIC_DEST_CPUS_SHIFT) | ||
182 | |||
183 | #define SUMMIT_APIC_DFR_VALUE (APIC_DFR_CLUSTER) | 175 | #define SUMMIT_APIC_DFR_VALUE (APIC_DFR_CLUSTER) |
184 | 176 | ||
185 | static const struct cpumask *summit_target_cpus(void) | 177 | static const struct cpumask *summit_target_cpus(void) |
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 4a903e2f0d17..8e4cbb255c38 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #include <asm/apic.h> | 10 | #include <asm/apic.h> |
11 | #include <asm/ipi.h> | 11 | #include <asm/ipi.h> |
12 | 12 | ||
13 | DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid); | 13 | static DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid); |
14 | 14 | ||
15 | static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | 15 | static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) |
16 | { | 16 | { |
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 2bda69352976..096d19aea2f7 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -105,7 +105,7 @@ static void uv_vector_allocation_domain(int cpu, struct cpumask *retmask) | |||
105 | cpumask_set_cpu(cpu, retmask); | 105 | cpumask_set_cpu(cpu, retmask); |
106 | } | 106 | } |
107 | 107 | ||
108 | static int uv_wakeup_secondary(int phys_apicid, unsigned long start_rip) | 108 | static int __cpuinit uv_wakeup_secondary(int phys_apicid, unsigned long start_rip) |
109 | { | 109 | { |
110 | #ifdef CONFIG_SMP | 110 | #ifdef CONFIG_SMP |
111 | unsigned long val; | 111 | unsigned long val; |
@@ -463,7 +463,7 @@ static void uv_heartbeat(unsigned long ignored) | |||
463 | uv_set_scir_bits(bits); | 463 | uv_set_scir_bits(bits); |
464 | 464 | ||
465 | /* enable next timer period */ | 465 | /* enable next timer period */ |
466 | mod_timer(timer, jiffies + SCIR_CPU_HB_INTERVAL); | 466 | mod_timer_pinned(timer, jiffies + SCIR_CPU_HB_INTERVAL); |
467 | } | 467 | } |
468 | 468 | ||
469 | static void __cpuinit uv_heartbeat_enable(int cpu) | 469 | static void __cpuinit uv_heartbeat_enable(int cpu) |
@@ -562,7 +562,7 @@ void __init uv_system_init(void) | |||
562 | union uvh_node_id_u node_id; | 562 | union uvh_node_id_u node_id; |
563 | unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size; | 563 | unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size; |
564 | int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val; | 564 | int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val; |
565 | int max_pnode = 0; | 565 | int gnode_extra, max_pnode = 0; |
566 | unsigned long mmr_base, present, paddr; | 566 | unsigned long mmr_base, present, paddr; |
567 | unsigned short pnode_mask; | 567 | unsigned short pnode_mask; |
568 | 568 | ||
@@ -574,6 +574,13 @@ void __init uv_system_init(void) | |||
574 | mmr_base = | 574 | mmr_base = |
575 | uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) & | 575 | uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) & |
576 | ~UV_MMR_ENABLE; | 576 | ~UV_MMR_ENABLE; |
577 | pnode_mask = (1 << n_val) - 1; | ||
578 | node_id.v = uv_read_local_mmr(UVH_NODE_ID); | ||
579 | gnode_extra = (node_id.s.node_id & ~((1 << n_val) - 1)) >> 1; | ||
580 | gnode_upper = ((unsigned long)gnode_extra << m_val); | ||
581 | printk(KERN_DEBUG "UV: N %d, M %d, gnode_upper 0x%lx, gnode_extra 0x%x\n", | ||
582 | n_val, m_val, gnode_upper, gnode_extra); | ||
583 | |||
577 | printk(KERN_DEBUG "UV: global MMR base 0x%lx\n", mmr_base); | 584 | printk(KERN_DEBUG "UV: global MMR base 0x%lx\n", mmr_base); |
578 | 585 | ||
579 | for(i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++) | 586 | for(i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++) |
@@ -583,15 +590,18 @@ void __init uv_system_init(void) | |||
583 | 590 | ||
584 | bytes = sizeof(struct uv_blade_info) * uv_num_possible_blades(); | 591 | bytes = sizeof(struct uv_blade_info) * uv_num_possible_blades(); |
585 | uv_blade_info = kmalloc(bytes, GFP_KERNEL); | 592 | uv_blade_info = kmalloc(bytes, GFP_KERNEL); |
593 | BUG_ON(!uv_blade_info); | ||
586 | 594 | ||
587 | get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size); | 595 | get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size); |
588 | 596 | ||
589 | bytes = sizeof(uv_node_to_blade[0]) * num_possible_nodes(); | 597 | bytes = sizeof(uv_node_to_blade[0]) * num_possible_nodes(); |
590 | uv_node_to_blade = kmalloc(bytes, GFP_KERNEL); | 598 | uv_node_to_blade = kmalloc(bytes, GFP_KERNEL); |
599 | BUG_ON(!uv_node_to_blade); | ||
591 | memset(uv_node_to_blade, 255, bytes); | 600 | memset(uv_node_to_blade, 255, bytes); |
592 | 601 | ||
593 | bytes = sizeof(uv_cpu_to_blade[0]) * num_possible_cpus(); | 602 | bytes = sizeof(uv_cpu_to_blade[0]) * num_possible_cpus(); |
594 | uv_cpu_to_blade = kmalloc(bytes, GFP_KERNEL); | 603 | uv_cpu_to_blade = kmalloc(bytes, GFP_KERNEL); |
604 | BUG_ON(!uv_cpu_to_blade); | ||
595 | memset(uv_cpu_to_blade, 255, bytes); | 605 | memset(uv_cpu_to_blade, 255, bytes); |
596 | 606 | ||
597 | blade = 0; | 607 | blade = 0; |
@@ -607,11 +617,6 @@ void __init uv_system_init(void) | |||
607 | } | 617 | } |
608 | } | 618 | } |
609 | 619 | ||
610 | pnode_mask = (1 << n_val) - 1; | ||
611 | node_id.v = uv_read_local_mmr(UVH_NODE_ID); | ||
612 | gnode_upper = (((unsigned long)node_id.s.node_id) & | ||
613 | ~((1 << n_val) - 1)) << m_val; | ||
614 | |||
615 | uv_bios_init(); | 620 | uv_bios_init(); |
616 | uv_bios_get_sn_info(0, &uv_type, &sn_partition_id, | 621 | uv_bios_get_sn_info(0, &uv_type, &sn_partition_id, |
617 | &sn_coherency_id, &sn_region_size); | 622 | &sn_coherency_id, &sn_region_size); |
@@ -634,6 +639,7 @@ void __init uv_system_init(void) | |||
634 | uv_cpu_hub_info(cpu)->pnode_mask = pnode_mask; | 639 | uv_cpu_hub_info(cpu)->pnode_mask = pnode_mask; |
635 | uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1; | 640 | uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1; |
636 | uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper; | 641 | uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper; |
642 | uv_cpu_hub_info(cpu)->gnode_extra = gnode_extra; | ||
637 | uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base; | 643 | uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base; |
638 | uv_cpu_hub_info(cpu)->coherency_domain_number = sn_coherency_id; | 644 | uv_cpu_hub_info(cpu)->coherency_domain_number = sn_coherency_id; |
639 | uv_cpu_hub_info(cpu)->scir.offset = SCIR_LOCAL_MMR_BASE + lcpu; | 645 | uv_cpu_hub_info(cpu)->scir.offset = SCIR_LOCAL_MMR_BASE + lcpu; |