diff options
Diffstat (limited to 'arch/x86/kernel/apic')
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 76 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic_flat_64.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic_noop.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic_numachip.c | 8 | ||||
-rw-r--r-- | arch/x86/kernel/apic/bigsmp_32.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/apic/es7000_32.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 383 | ||||
-rw-r--r-- | arch/x86/kernel/apic/numaq_32.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/apic/probe_32.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/apic/summit_32.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/apic/x2apic_cluster.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/apic/x2apic_phys.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/apic/x2apic_uv_x.c | 1 |
13 files changed, 153 insertions, 332 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 11544d8f1e97..39a222e094af 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/smp.h> | 35 | #include <linux/smp.h> |
36 | #include <linux/mm.h> | 36 | #include <linux/mm.h> |
37 | 37 | ||
38 | #include <asm/irq_remapping.h> | ||
38 | #include <asm/perf_event.h> | 39 | #include <asm/perf_event.h> |
39 | #include <asm/x86_init.h> | 40 | #include <asm/x86_init.h> |
40 | #include <asm/pgalloc.h> | 41 | #include <asm/pgalloc.h> |
@@ -1325,11 +1326,13 @@ void __cpuinit setup_local_APIC(void) | |||
1325 | acked); | 1326 | acked); |
1326 | break; | 1327 | break; |
1327 | } | 1328 | } |
1328 | if (cpu_has_tsc) { | 1329 | if (queued) { |
1329 | rdtscll(ntsc); | 1330 | if (cpu_has_tsc) { |
1330 | max_loops = (cpu_khz << 10) - (ntsc - tsc); | 1331 | rdtscll(ntsc); |
1331 | } else | 1332 | max_loops = (cpu_khz << 10) - (ntsc - tsc); |
1332 | max_loops--; | 1333 | } else |
1334 | max_loops--; | ||
1335 | } | ||
1333 | } while (queued && max_loops > 0); | 1336 | } while (queued && max_loops > 0); |
1334 | WARN_ON(max_loops <= 0); | 1337 | WARN_ON(max_loops <= 0); |
1335 | 1338 | ||
@@ -1441,8 +1444,8 @@ void __init bsp_end_local_APIC_setup(void) | |||
1441 | * Now that local APIC setup is completed for BP, configure the fault | 1444 | * Now that local APIC setup is completed for BP, configure the fault |
1442 | * handling for interrupt remapping. | 1445 | * handling for interrupt remapping. |
1443 | */ | 1446 | */ |
1444 | if (intr_remapping_enabled) | 1447 | if (irq_remapping_enabled) |
1445 | enable_drhd_fault_handling(); | 1448 | irq_remap_enable_fault_handling(); |
1446 | 1449 | ||
1447 | } | 1450 | } |
1448 | 1451 | ||
@@ -1517,7 +1520,7 @@ void enable_x2apic(void) | |||
1517 | int __init enable_IR(void) | 1520 | int __init enable_IR(void) |
1518 | { | 1521 | { |
1519 | #ifdef CONFIG_IRQ_REMAP | 1522 | #ifdef CONFIG_IRQ_REMAP |
1520 | if (!intr_remapping_supported()) { | 1523 | if (!irq_remapping_supported()) { |
1521 | pr_debug("intr-remapping not supported\n"); | 1524 | pr_debug("intr-remapping not supported\n"); |
1522 | return -1; | 1525 | return -1; |
1523 | } | 1526 | } |
@@ -1528,7 +1531,7 @@ int __init enable_IR(void) | |||
1528 | return -1; | 1531 | return -1; |
1529 | } | 1532 | } |
1530 | 1533 | ||
1531 | return enable_intr_remapping(); | 1534 | return irq_remapping_enable(); |
1532 | #endif | 1535 | #endif |
1533 | return -1; | 1536 | return -1; |
1534 | } | 1537 | } |
@@ -1537,10 +1540,13 @@ void __init enable_IR_x2apic(void) | |||
1537 | { | 1540 | { |
1538 | unsigned long flags; | 1541 | unsigned long flags; |
1539 | int ret, x2apic_enabled = 0; | 1542 | int ret, x2apic_enabled = 0; |
1540 | int dmar_table_init_ret; | 1543 | int hardware_init_ret; |
1544 | |||
1545 | /* Make sure irq_remap_ops are initialized */ | ||
1546 | setup_irq_remapping_ops(); | ||
1541 | 1547 | ||
1542 | dmar_table_init_ret = dmar_table_init(); | 1548 | hardware_init_ret = irq_remapping_prepare(); |
1543 | if (dmar_table_init_ret && !x2apic_supported()) | 1549 | if (hardware_init_ret && !x2apic_supported()) |
1544 | return; | 1550 | return; |
1545 | 1551 | ||
1546 | ret = save_ioapic_entries(); | 1552 | ret = save_ioapic_entries(); |
@@ -1556,7 +1562,7 @@ void __init enable_IR_x2apic(void) | |||
1556 | if (x2apic_preenabled && nox2apic) | 1562 | if (x2apic_preenabled && nox2apic) |
1557 | disable_x2apic(); | 1563 | disable_x2apic(); |
1558 | 1564 | ||
1559 | if (dmar_table_init_ret) | 1565 | if (hardware_init_ret) |
1560 | ret = -1; | 1566 | ret = -1; |
1561 | else | 1567 | else |
1562 | ret = enable_IR(); | 1568 | ret = enable_IR(); |
@@ -1637,9 +1643,11 @@ static int __init apic_verify(void) | |||
1637 | mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; | 1643 | mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; |
1638 | 1644 | ||
1639 | /* The BIOS may have set up the APIC at some other address */ | 1645 | /* The BIOS may have set up the APIC at some other address */ |
1640 | rdmsr(MSR_IA32_APICBASE, l, h); | 1646 | if (boot_cpu_data.x86 >= 6) { |
1641 | if (l & MSR_IA32_APICBASE_ENABLE) | 1647 | rdmsr(MSR_IA32_APICBASE, l, h); |
1642 | mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; | 1648 | if (l & MSR_IA32_APICBASE_ENABLE) |
1649 | mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; | ||
1650 | } | ||
1643 | 1651 | ||
1644 | pr_info("Found and enabled local APIC!\n"); | 1652 | pr_info("Found and enabled local APIC!\n"); |
1645 | return 0; | 1653 | return 0; |
@@ -1657,13 +1665,15 @@ int __init apic_force_enable(unsigned long addr) | |||
1657 | * MSR. This can only be done in software for Intel P6 or later | 1665 | * MSR. This can only be done in software for Intel P6 or later |
1658 | * and AMD K7 (Model > 1) or later. | 1666 | * and AMD K7 (Model > 1) or later. |
1659 | */ | 1667 | */ |
1660 | rdmsr(MSR_IA32_APICBASE, l, h); | 1668 | if (boot_cpu_data.x86 >= 6) { |
1661 | if (!(l & MSR_IA32_APICBASE_ENABLE)) { | 1669 | rdmsr(MSR_IA32_APICBASE, l, h); |
1662 | pr_info("Local APIC disabled by BIOS -- reenabling.\n"); | 1670 | if (!(l & MSR_IA32_APICBASE_ENABLE)) { |
1663 | l &= ~MSR_IA32_APICBASE_BASE; | 1671 | pr_info("Local APIC disabled by BIOS -- reenabling.\n"); |
1664 | l |= MSR_IA32_APICBASE_ENABLE | addr; | 1672 | l &= ~MSR_IA32_APICBASE_BASE; |
1665 | wrmsr(MSR_IA32_APICBASE, l, h); | 1673 | l |= MSR_IA32_APICBASE_ENABLE | addr; |
1666 | enabled_via_apicbase = 1; | 1674 | wrmsr(MSR_IA32_APICBASE, l, h); |
1675 | enabled_via_apicbase = 1; | ||
1676 | } | ||
1667 | } | 1677 | } |
1668 | return apic_verify(); | 1678 | return apic_verify(); |
1669 | } | 1679 | } |
@@ -2172,8 +2182,8 @@ static int lapic_suspend(void) | |||
2172 | local_irq_save(flags); | 2182 | local_irq_save(flags); |
2173 | disable_local_APIC(); | 2183 | disable_local_APIC(); |
2174 | 2184 | ||
2175 | if (intr_remapping_enabled) | 2185 | if (irq_remapping_enabled) |
2176 | disable_intr_remapping(); | 2186 | irq_remapping_disable(); |
2177 | 2187 | ||
2178 | local_irq_restore(flags); | 2188 | local_irq_restore(flags); |
2179 | return 0; | 2189 | return 0; |
@@ -2189,7 +2199,7 @@ static void lapic_resume(void) | |||
2189 | return; | 2199 | return; |
2190 | 2200 | ||
2191 | local_irq_save(flags); | 2201 | local_irq_save(flags); |
2192 | if (intr_remapping_enabled) { | 2202 | if (irq_remapping_enabled) { |
2193 | /* | 2203 | /* |
2194 | * IO-APIC and PIC have their own resume routines. | 2204 | * IO-APIC and PIC have their own resume routines. |
2195 | * We just mask them here to make sure the interrupt | 2205 | * We just mask them here to make sure the interrupt |
@@ -2209,10 +2219,12 @@ static void lapic_resume(void) | |||
2209 | * FIXME! This will be wrong if we ever support suspend on | 2219 | * FIXME! This will be wrong if we ever support suspend on |
2210 | * SMP! We'll need to do this as part of the CPU restore! | 2220 | * SMP! We'll need to do this as part of the CPU restore! |
2211 | */ | 2221 | */ |
2212 | rdmsr(MSR_IA32_APICBASE, l, h); | 2222 | if (boot_cpu_data.x86 >= 6) { |
2213 | l &= ~MSR_IA32_APICBASE_BASE; | 2223 | rdmsr(MSR_IA32_APICBASE, l, h); |
2214 | l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; | 2224 | l &= ~MSR_IA32_APICBASE_BASE; |
2215 | wrmsr(MSR_IA32_APICBASE, l, h); | 2225 | l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; |
2226 | wrmsr(MSR_IA32_APICBASE, l, h); | ||
2227 | } | ||
2216 | } | 2228 | } |
2217 | 2229 | ||
2218 | maxlvt = lapic_get_maxlvt(); | 2230 | maxlvt = lapic_get_maxlvt(); |
@@ -2239,8 +2251,8 @@ static void lapic_resume(void) | |||
2239 | apic_write(APIC_ESR, 0); | 2251 | apic_write(APIC_ESR, 0); |
2240 | apic_read(APIC_ESR); | 2252 | apic_read(APIC_ESR); |
2241 | 2253 | ||
2242 | if (intr_remapping_enabled) | 2254 | if (irq_remapping_enabled) |
2243 | reenable_intr_remapping(x2apic_mode); | 2255 | irq_remapping_reenable(x2apic_mode); |
2244 | 2256 | ||
2245 | local_irq_restore(flags); | 2257 | local_irq_restore(flags); |
2246 | } | 2258 | } |
diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index 359b6899a36c..0e881c46e8c8 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c | |||
@@ -227,6 +227,7 @@ static struct apic apic_flat = { | |||
227 | 227 | ||
228 | .read = native_apic_mem_read, | 228 | .read = native_apic_mem_read, |
229 | .write = native_apic_mem_write, | 229 | .write = native_apic_mem_write, |
230 | .eoi_write = native_apic_mem_write, | ||
230 | .icr_read = native_apic_icr_read, | 231 | .icr_read = native_apic_icr_read, |
231 | .icr_write = native_apic_icr_write, | 232 | .icr_write = native_apic_icr_write, |
232 | .wait_icr_idle = native_apic_wait_icr_idle, | 233 | .wait_icr_idle = native_apic_wait_icr_idle, |
@@ -386,6 +387,7 @@ static struct apic apic_physflat = { | |||
386 | 387 | ||
387 | .read = native_apic_mem_read, | 388 | .read = native_apic_mem_read, |
388 | .write = native_apic_mem_write, | 389 | .write = native_apic_mem_write, |
390 | .eoi_write = native_apic_mem_write, | ||
389 | .icr_read = native_apic_icr_read, | 391 | .icr_read = native_apic_icr_read, |
390 | .icr_write = native_apic_icr_write, | 392 | .icr_write = native_apic_icr_write, |
391 | .wait_icr_idle = native_apic_wait_icr_idle, | 393 | .wait_icr_idle = native_apic_wait_icr_idle, |
diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c index 634ae6cdd5c9..a6e4c6e06c08 100644 --- a/arch/x86/kernel/apic/apic_noop.c +++ b/arch/x86/kernel/apic/apic_noop.c | |||
@@ -181,6 +181,7 @@ struct apic apic_noop = { | |||
181 | 181 | ||
182 | .read = noop_apic_read, | 182 | .read = noop_apic_read, |
183 | .write = noop_apic_write, | 183 | .write = noop_apic_write, |
184 | .eoi_write = noop_apic_write, | ||
184 | .icr_read = noop_apic_icr_read, | 185 | .icr_read = noop_apic_icr_read, |
185 | .icr_write = noop_apic_icr_write, | 186 | .icr_write = noop_apic_icr_write, |
186 | .wait_icr_idle = noop_apic_wait_icr_idle, | 187 | .wait_icr_idle = noop_apic_wait_icr_idle, |
diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c index 899803e03214..6ec6d5d297c3 100644 --- a/arch/x86/kernel/apic/apic_numachip.c +++ b/arch/x86/kernel/apic/apic_numachip.c | |||
@@ -207,8 +207,11 @@ static void __init map_csrs(void) | |||
207 | 207 | ||
208 | static void fixup_cpu_id(struct cpuinfo_x86 *c, int node) | 208 | static void fixup_cpu_id(struct cpuinfo_x86 *c, int node) |
209 | { | 209 | { |
210 | c->phys_proc_id = node; | 210 | |
211 | per_cpu(cpu_llc_id, smp_processor_id()) = node; | 211 | if (c->phys_proc_id != node) { |
212 | c->phys_proc_id = node; | ||
213 | per_cpu(cpu_llc_id, smp_processor_id()) = node; | ||
214 | } | ||
212 | } | 215 | } |
213 | 216 | ||
214 | static int __init numachip_system_init(void) | 217 | static int __init numachip_system_init(void) |
@@ -292,6 +295,7 @@ static struct apic apic_numachip __refconst = { | |||
292 | 295 | ||
293 | .read = native_apic_mem_read, | 296 | .read = native_apic_mem_read, |
294 | .write = native_apic_mem_write, | 297 | .write = native_apic_mem_write, |
298 | .eoi_write = native_apic_mem_write, | ||
295 | .icr_read = native_apic_icr_read, | 299 | .icr_read = native_apic_icr_read, |
296 | .icr_write = native_apic_icr_write, | 300 | .icr_write = native_apic_icr_write, |
297 | .wait_icr_idle = native_apic_wait_icr_idle, | 301 | .wait_icr_idle = native_apic_wait_icr_idle, |
diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c index 0cdec7065aff..31fbdbfbf960 100644 --- a/arch/x86/kernel/apic/bigsmp_32.c +++ b/arch/x86/kernel/apic/bigsmp_32.c | |||
@@ -248,6 +248,7 @@ static struct apic apic_bigsmp = { | |||
248 | 248 | ||
249 | .read = native_apic_mem_read, | 249 | .read = native_apic_mem_read, |
250 | .write = native_apic_mem_write, | 250 | .write = native_apic_mem_write, |
251 | .eoi_write = native_apic_mem_write, | ||
251 | .icr_read = native_apic_icr_read, | 252 | .icr_read = native_apic_icr_read, |
252 | .icr_write = native_apic_icr_write, | 253 | .icr_write = native_apic_icr_write, |
253 | .wait_icr_idle = native_apic_wait_icr_idle, | 254 | .wait_icr_idle = native_apic_wait_icr_idle, |
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index e42d1d3b9134..db4ab1be3c79 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c | |||
@@ -678,6 +678,7 @@ static struct apic __refdata apic_es7000_cluster = { | |||
678 | 678 | ||
679 | .read = native_apic_mem_read, | 679 | .read = native_apic_mem_read, |
680 | .write = native_apic_mem_write, | 680 | .write = native_apic_mem_write, |
681 | .eoi_write = native_apic_mem_write, | ||
681 | .icr_read = native_apic_icr_read, | 682 | .icr_read = native_apic_icr_read, |
682 | .icr_write = native_apic_icr_write, | 683 | .icr_write = native_apic_icr_write, |
683 | .wait_icr_idle = native_apic_wait_icr_idle, | 684 | .wait_icr_idle = native_apic_wait_icr_idle, |
@@ -742,6 +743,7 @@ static struct apic __refdata apic_es7000 = { | |||
742 | 743 | ||
743 | .read = native_apic_mem_read, | 744 | .read = native_apic_mem_read, |
744 | .write = native_apic_mem_write, | 745 | .write = native_apic_mem_write, |
746 | .eoi_write = native_apic_mem_write, | ||
745 | .icr_read = native_apic_icr_read, | 747 | .icr_read = native_apic_icr_read, |
746 | .icr_write = native_apic_icr_write, | 748 | .icr_write = native_apic_icr_write, |
747 | .wait_icr_idle = native_apic_wait_icr_idle, | 749 | .wait_icr_idle = native_apic_wait_icr_idle, |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index e88300d8e80a..ffdc152e507d 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -68,23 +68,21 @@ | |||
68 | #define for_each_irq_pin(entry, head) \ | 68 | #define for_each_irq_pin(entry, head) \ |
69 | for (entry = head; entry; entry = entry->next) | 69 | for (entry = head; entry; entry = entry->next) |
70 | 70 | ||
71 | static void __init __ioapic_init_mappings(void); | 71 | #ifdef CONFIG_IRQ_REMAP |
72 | 72 | static void irq_remap_modify_chip_defaults(struct irq_chip *chip); | |
73 | static unsigned int __io_apic_read (unsigned int apic, unsigned int reg); | 73 | static inline bool irq_remapped(struct irq_cfg *cfg) |
74 | static void __io_apic_write (unsigned int apic, unsigned int reg, unsigned int val); | 74 | { |
75 | static void __io_apic_modify(unsigned int apic, unsigned int reg, unsigned int val); | 75 | return cfg->irq_2_iommu.iommu != NULL; |
76 | 76 | } | |
77 | static struct io_apic_ops io_apic_ops = { | 77 | #else |
78 | .init = __ioapic_init_mappings, | 78 | static inline bool irq_remapped(struct irq_cfg *cfg) |
79 | .read = __io_apic_read, | 79 | { |
80 | .write = __io_apic_write, | 80 | return false; |
81 | .modify = __io_apic_modify, | 81 | } |
82 | }; | 82 | static inline void irq_remap_modify_chip_defaults(struct irq_chip *chip) |
83 | |||
84 | void __init set_io_apic_ops(const struct io_apic_ops *ops) | ||
85 | { | 83 | { |
86 | io_apic_ops = *ops; | ||
87 | } | 84 | } |
85 | #endif | ||
88 | 86 | ||
89 | /* | 87 | /* |
90 | * Is the SiS APIC rmw bug present ? | 88 | * Is the SiS APIC rmw bug present ? |
@@ -313,21 +311,6 @@ static void free_irq_at(unsigned int at, struct irq_cfg *cfg) | |||
313 | irq_free_desc(at); | 311 | irq_free_desc(at); |
314 | } | 312 | } |
315 | 313 | ||
316 | static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) | ||
317 | { | ||
318 | return io_apic_ops.read(apic, reg); | ||
319 | } | ||
320 | |||
321 | static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) | ||
322 | { | ||
323 | io_apic_ops.write(apic, reg, value); | ||
324 | } | ||
325 | |||
326 | static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value) | ||
327 | { | ||
328 | io_apic_ops.modify(apic, reg, value); | ||
329 | } | ||
330 | |||
331 | 314 | ||
332 | struct io_apic { | 315 | struct io_apic { |
333 | unsigned int index; | 316 | unsigned int index; |
@@ -349,14 +332,14 @@ static inline void io_apic_eoi(unsigned int apic, unsigned int vector) | |||
349 | writel(vector, &io_apic->eoi); | 332 | writel(vector, &io_apic->eoi); |
350 | } | 333 | } |
351 | 334 | ||
352 | static unsigned int __io_apic_read(unsigned int apic, unsigned int reg) | 335 | unsigned int native_io_apic_read(unsigned int apic, unsigned int reg) |
353 | { | 336 | { |
354 | struct io_apic __iomem *io_apic = io_apic_base(apic); | 337 | struct io_apic __iomem *io_apic = io_apic_base(apic); |
355 | writel(reg, &io_apic->index); | 338 | writel(reg, &io_apic->index); |
356 | return readl(&io_apic->data); | 339 | return readl(&io_apic->data); |
357 | } | 340 | } |
358 | 341 | ||
359 | static void __io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) | 342 | void native_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) |
360 | { | 343 | { |
361 | struct io_apic __iomem *io_apic = io_apic_base(apic); | 344 | struct io_apic __iomem *io_apic = io_apic_base(apic); |
362 | 345 | ||
@@ -370,7 +353,7 @@ static void __io_apic_write(unsigned int apic, unsigned int reg, unsigned int va | |||
370 | * | 353 | * |
371 | * Older SiS APIC requires we rewrite the index register | 354 | * Older SiS APIC requires we rewrite the index register |
372 | */ | 355 | */ |
373 | static void __io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value) | 356 | void native_io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value) |
374 | { | 357 | { |
375 | struct io_apic __iomem *io_apic = io_apic_base(apic); | 358 | struct io_apic __iomem *io_apic = io_apic_base(apic); |
376 | 359 | ||
@@ -379,29 +362,6 @@ static void __io_apic_modify(unsigned int apic, unsigned int reg, unsigned int v | |||
379 | writel(value, &io_apic->data); | 362 | writel(value, &io_apic->data); |
380 | } | 363 | } |
381 | 364 | ||
382 | static bool io_apic_level_ack_pending(struct irq_cfg *cfg) | ||
383 | { | ||
384 | struct irq_pin_list *entry; | ||
385 | unsigned long flags; | ||
386 | |||
387 | raw_spin_lock_irqsave(&ioapic_lock, flags); | ||
388 | for_each_irq_pin(entry, cfg->irq_2_pin) { | ||
389 | unsigned int reg; | ||
390 | int pin; | ||
391 | |||
392 | pin = entry->pin; | ||
393 | reg = io_apic_read(entry->apic, 0x10 + pin*2); | ||
394 | /* Is the remote IRR bit set? */ | ||
395 | if (reg & IO_APIC_REDIR_REMOTE_IRR) { | ||
396 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | ||
397 | return true; | ||
398 | } | ||
399 | } | ||
400 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | ||
401 | |||
402 | return false; | ||
403 | } | ||
404 | |||
405 | union entry_union { | 365 | union entry_union { |
406 | struct { u32 w1, w2; }; | 366 | struct { u32 w1, w2; }; |
407 | struct IO_APIC_route_entry entry; | 367 | struct IO_APIC_route_entry entry; |
@@ -1361,77 +1321,13 @@ static void ioapic_register_intr(unsigned int irq, struct irq_cfg *cfg, | |||
1361 | fasteoi ? "fasteoi" : "edge"); | 1321 | fasteoi ? "fasteoi" : "edge"); |
1362 | } | 1322 | } |
1363 | 1323 | ||
1364 | |||
1365 | static int setup_ir_ioapic_entry(int irq, | ||
1366 | struct IR_IO_APIC_route_entry *entry, | ||
1367 | unsigned int destination, int vector, | ||
1368 | struct io_apic_irq_attr *attr) | ||
1369 | { | ||
1370 | int index; | ||
1371 | struct irte irte; | ||
1372 | int ioapic_id = mpc_ioapic_id(attr->ioapic); | ||
1373 | struct intel_iommu *iommu = map_ioapic_to_ir(ioapic_id); | ||
1374 | |||
1375 | if (!iommu) { | ||
1376 | pr_warn("No mapping iommu for ioapic %d\n", ioapic_id); | ||
1377 | return -ENODEV; | ||
1378 | } | ||
1379 | |||
1380 | index = alloc_irte(iommu, irq, 1); | ||
1381 | if (index < 0) { | ||
1382 | pr_warn("Failed to allocate IRTE for ioapic %d\n", ioapic_id); | ||
1383 | return -ENOMEM; | ||
1384 | } | ||
1385 | |||
1386 | prepare_irte(&irte, vector, destination); | ||
1387 | |||
1388 | /* Set source-id of interrupt request */ | ||
1389 | set_ioapic_sid(&irte, ioapic_id); | ||
1390 | |||
1391 | modify_irte(irq, &irte); | ||
1392 | |||
1393 | apic_printk(APIC_VERBOSE, KERN_DEBUG "IOAPIC[%d]: " | ||
1394 | "Set IRTE entry (P:%d FPD:%d Dst_Mode:%d " | ||
1395 | "Redir_hint:%d Trig_Mode:%d Dlvry_Mode:%X " | ||
1396 | "Avail:%X Vector:%02X Dest:%08X " | ||
1397 | "SID:%04X SQ:%X SVT:%X)\n", | ||
1398 | attr->ioapic, irte.present, irte.fpd, irte.dst_mode, | ||
1399 | irte.redir_hint, irte.trigger_mode, irte.dlvry_mode, | ||
1400 | irte.avail, irte.vector, irte.dest_id, | ||
1401 | irte.sid, irte.sq, irte.svt); | ||
1402 | |||
1403 | memset(entry, 0, sizeof(*entry)); | ||
1404 | |||
1405 | entry->index2 = (index >> 15) & 0x1; | ||
1406 | entry->zero = 0; | ||
1407 | entry->format = 1; | ||
1408 | entry->index = (index & 0x7fff); | ||
1409 | /* | ||
1410 | * IO-APIC RTE will be configured with virtual vector. | ||
1411 | * irq handler will do the explicit EOI to the io-apic. | ||
1412 | */ | ||
1413 | entry->vector = attr->ioapic_pin; | ||
1414 | entry->mask = 0; /* enable IRQ */ | ||
1415 | entry->trigger = attr->trigger; | ||
1416 | entry->polarity = attr->polarity; | ||
1417 | |||
1418 | /* Mask level triggered irqs. | ||
1419 | * Use IRQ_DELAYED_DISABLE for edge triggered irqs. | ||
1420 | */ | ||
1421 | if (attr->trigger) | ||
1422 | entry->mask = 1; | ||
1423 | |||
1424 | return 0; | ||
1425 | } | ||
1426 | |||
1427 | static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry, | 1324 | static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry, |
1428 | unsigned int destination, int vector, | 1325 | unsigned int destination, int vector, |
1429 | struct io_apic_irq_attr *attr) | 1326 | struct io_apic_irq_attr *attr) |
1430 | { | 1327 | { |
1431 | if (intr_remapping_enabled) | 1328 | if (irq_remapping_enabled) |
1432 | return setup_ir_ioapic_entry(irq, | 1329 | return setup_ioapic_remapped_entry(irq, entry, destination, |
1433 | (struct IR_IO_APIC_route_entry *)entry, | 1330 | vector, attr); |
1434 | destination, vector, attr); | ||
1435 | 1331 | ||
1436 | memset(entry, 0, sizeof(*entry)); | 1332 | memset(entry, 0, sizeof(*entry)); |
1437 | 1333 | ||
@@ -1588,7 +1484,7 @@ static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx, | |||
1588 | { | 1484 | { |
1589 | struct IO_APIC_route_entry entry; | 1485 | struct IO_APIC_route_entry entry; |
1590 | 1486 | ||
1591 | if (intr_remapping_enabled) | 1487 | if (irq_remapping_enabled) |
1592 | return; | 1488 | return; |
1593 | 1489 | ||
1594 | memset(&entry, 0, sizeof(entry)); | 1490 | memset(&entry, 0, sizeof(entry)); |
@@ -1674,7 +1570,7 @@ __apicdebuginit(void) print_IO_APIC(int ioapic_idx) | |||
1674 | 1570 | ||
1675 | printk(KERN_DEBUG ".... IRQ redirection table:\n"); | 1571 | printk(KERN_DEBUG ".... IRQ redirection table:\n"); |
1676 | 1572 | ||
1677 | if (intr_remapping_enabled) { | 1573 | if (irq_remapping_enabled) { |
1678 | printk(KERN_DEBUG " NR Indx Fmt Mask Trig IRR" | 1574 | printk(KERN_DEBUG " NR Indx Fmt Mask Trig IRR" |
1679 | " Pol Stat Indx2 Zero Vect:\n"); | 1575 | " Pol Stat Indx2 Zero Vect:\n"); |
1680 | } else { | 1576 | } else { |
@@ -1683,7 +1579,7 @@ __apicdebuginit(void) print_IO_APIC(int ioapic_idx) | |||
1683 | } | 1579 | } |
1684 | 1580 | ||
1685 | for (i = 0; i <= reg_01.bits.entries; i++) { | 1581 | for (i = 0; i <= reg_01.bits.entries; i++) { |
1686 | if (intr_remapping_enabled) { | 1582 | if (irq_remapping_enabled) { |
1687 | struct IO_APIC_route_entry entry; | 1583 | struct IO_APIC_route_entry entry; |
1688 | struct IR_IO_APIC_route_entry *ir_entry; | 1584 | struct IR_IO_APIC_route_entry *ir_entry; |
1689 | 1585 | ||
@@ -2050,7 +1946,7 @@ void disable_IO_APIC(void) | |||
2050 | * IOAPIC RTE as well as interrupt-remapping table entry). | 1946 | * IOAPIC RTE as well as interrupt-remapping table entry). |
2051 | * As this gets called during crash dump, keep this simple for now. | 1947 | * As this gets called during crash dump, keep this simple for now. |
2052 | */ | 1948 | */ |
2053 | if (ioapic_i8259.pin != -1 && !intr_remapping_enabled) { | 1949 | if (ioapic_i8259.pin != -1 && !irq_remapping_enabled) { |
2054 | struct IO_APIC_route_entry entry; | 1950 | struct IO_APIC_route_entry entry; |
2055 | 1951 | ||
2056 | memset(&entry, 0, sizeof(entry)); | 1952 | memset(&entry, 0, sizeof(entry)); |
@@ -2074,7 +1970,7 @@ void disable_IO_APIC(void) | |||
2074 | * Use virtual wire A mode when interrupt remapping is enabled. | 1970 | * Use virtual wire A mode when interrupt remapping is enabled. |
2075 | */ | 1971 | */ |
2076 | if (cpu_has_apic || apic_from_smp_config()) | 1972 | if (cpu_has_apic || apic_from_smp_config()) |
2077 | disconnect_bsp_APIC(!intr_remapping_enabled && | 1973 | disconnect_bsp_APIC(!irq_remapping_enabled && |
2078 | ioapic_i8259.pin != -1); | 1974 | ioapic_i8259.pin != -1); |
2079 | } | 1975 | } |
2080 | 1976 | ||
@@ -2390,71 +2286,6 @@ ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, | |||
2390 | return ret; | 2286 | return ret; |
2391 | } | 2287 | } |
2392 | 2288 | ||
2393 | #ifdef CONFIG_IRQ_REMAP | ||
2394 | |||
2395 | /* | ||
2396 | * Migrate the IO-APIC irq in the presence of intr-remapping. | ||
2397 | * | ||
2398 | * For both level and edge triggered, irq migration is a simple atomic | ||
2399 | * update(of vector and cpu destination) of IRTE and flush the hardware cache. | ||
2400 | * | ||
2401 | * For level triggered, we eliminate the io-apic RTE modification (with the | ||
2402 | * updated vector information), by using a virtual vector (io-apic pin number). | ||
2403 | * Real vector that is used for interrupting cpu will be coming from | ||
2404 | * the interrupt-remapping table entry. | ||
2405 | * | ||
2406 | * As the migration is a simple atomic update of IRTE, the same mechanism | ||
2407 | * is used to migrate MSI irq's in the presence of interrupt-remapping. | ||
2408 | */ | ||
2409 | static int | ||
2410 | ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, | ||
2411 | bool force) | ||
2412 | { | ||
2413 | struct irq_cfg *cfg = data->chip_data; | ||
2414 | unsigned int dest, irq = data->irq; | ||
2415 | struct irte irte; | ||
2416 | |||
2417 | if (!cpumask_intersects(mask, cpu_online_mask)) | ||
2418 | return -EINVAL; | ||
2419 | |||
2420 | if (get_irte(irq, &irte)) | ||
2421 | return -EBUSY; | ||
2422 | |||
2423 | if (assign_irq_vector(irq, cfg, mask)) | ||
2424 | return -EBUSY; | ||
2425 | |||
2426 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask); | ||
2427 | |||
2428 | irte.vector = cfg->vector; | ||
2429 | irte.dest_id = IRTE_DEST(dest); | ||
2430 | |||
2431 | /* | ||
2432 | * Atomically updates the IRTE with the new destination, vector | ||
2433 | * and flushes the interrupt entry cache. | ||
2434 | */ | ||
2435 | modify_irte(irq, &irte); | ||
2436 | |||
2437 | /* | ||
2438 | * After this point, all the interrupts will start arriving | ||
2439 | * at the new destination. So, time to cleanup the previous | ||
2440 | * vector allocation. | ||
2441 | */ | ||
2442 | if (cfg->move_in_progress) | ||
2443 | send_cleanup_vector(cfg); | ||
2444 | |||
2445 | cpumask_copy(data->affinity, mask); | ||
2446 | return 0; | ||
2447 | } | ||
2448 | |||
2449 | #else | ||
2450 | static inline int | ||
2451 | ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, | ||
2452 | bool force) | ||
2453 | { | ||
2454 | return 0; | ||
2455 | } | ||
2456 | #endif | ||
2457 | |||
2458 | asmlinkage void smp_irq_move_cleanup_interrupt(void) | 2289 | asmlinkage void smp_irq_move_cleanup_interrupt(void) |
2459 | { | 2290 | { |
2460 | unsigned vector, me; | 2291 | unsigned vector, me; |
@@ -2552,6 +2383,29 @@ static void ack_apic_edge(struct irq_data *data) | |||
2552 | atomic_t irq_mis_count; | 2383 | atomic_t irq_mis_count; |
2553 | 2384 | ||
2554 | #ifdef CONFIG_GENERIC_PENDING_IRQ | 2385 | #ifdef CONFIG_GENERIC_PENDING_IRQ |
2386 | static bool io_apic_level_ack_pending(struct irq_cfg *cfg) | ||
2387 | { | ||
2388 | struct irq_pin_list *entry; | ||
2389 | unsigned long flags; | ||
2390 | |||
2391 | raw_spin_lock_irqsave(&ioapic_lock, flags); | ||
2392 | for_each_irq_pin(entry, cfg->irq_2_pin) { | ||
2393 | unsigned int reg; | ||
2394 | int pin; | ||
2395 | |||
2396 | pin = entry->pin; | ||
2397 | reg = io_apic_read(entry->apic, 0x10 + pin*2); | ||
2398 | /* Is the remote IRR bit set? */ | ||
2399 | if (reg & IO_APIC_REDIR_REMOTE_IRR) { | ||
2400 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | ||
2401 | return true; | ||
2402 | } | ||
2403 | } | ||
2404 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | ||
2405 | |||
2406 | return false; | ||
2407 | } | ||
2408 | |||
2555 | static inline bool ioapic_irqd_mask(struct irq_data *data, struct irq_cfg *cfg) | 2409 | static inline bool ioapic_irqd_mask(struct irq_data *data, struct irq_cfg *cfg) |
2556 | { | 2410 | { |
2557 | /* If we are moving the irq we need to mask it */ | 2411 | /* If we are moving the irq we need to mask it */ |
@@ -2699,7 +2553,7 @@ static void irq_remap_modify_chip_defaults(struct irq_chip *chip) | |||
2699 | chip->irq_eoi = ir_ack_apic_level; | 2553 | chip->irq_eoi = ir_ack_apic_level; |
2700 | 2554 | ||
2701 | #ifdef CONFIG_SMP | 2555 | #ifdef CONFIG_SMP |
2702 | chip->irq_set_affinity = ir_ioapic_set_affinity; | 2556 | chip->irq_set_affinity = set_remapped_irq_affinity; |
2703 | #endif | 2557 | #endif |
2704 | } | 2558 | } |
2705 | #endif /* CONFIG_IRQ_REMAP */ | 2559 | #endif /* CONFIG_IRQ_REMAP */ |
@@ -2912,7 +2766,7 @@ static inline void __init check_timer(void) | |||
2912 | * 8259A. | 2766 | * 8259A. |
2913 | */ | 2767 | */ |
2914 | if (pin1 == -1) { | 2768 | if (pin1 == -1) { |
2915 | if (intr_remapping_enabled) | 2769 | if (irq_remapping_enabled) |
2916 | panic("BIOS bug: timer not connected to IO-APIC"); | 2770 | panic("BIOS bug: timer not connected to IO-APIC"); |
2917 | pin1 = pin2; | 2771 | pin1 = pin2; |
2918 | apic1 = apic2; | 2772 | apic1 = apic2; |
@@ -2945,7 +2799,7 @@ static inline void __init check_timer(void) | |||
2945 | clear_IO_APIC_pin(0, pin1); | 2799 | clear_IO_APIC_pin(0, pin1); |
2946 | goto out; | 2800 | goto out; |
2947 | } | 2801 | } |
2948 | if (intr_remapping_enabled) | 2802 | if (irq_remapping_enabled) |
2949 | panic("timer doesn't work through Interrupt-remapped IO-APIC"); | 2803 | panic("timer doesn't work through Interrupt-remapped IO-APIC"); |
2950 | local_irq_disable(); | 2804 | local_irq_disable(); |
2951 | clear_IO_APIC_pin(apic1, pin1); | 2805 | clear_IO_APIC_pin(apic1, pin1); |
@@ -3169,7 +3023,7 @@ void destroy_irq(unsigned int irq) | |||
3169 | irq_set_status_flags(irq, IRQ_NOREQUEST|IRQ_NOPROBE); | 3023 | irq_set_status_flags(irq, IRQ_NOREQUEST|IRQ_NOPROBE); |
3170 | 3024 | ||
3171 | if (irq_remapped(cfg)) | 3025 | if (irq_remapped(cfg)) |
3172 | free_irte(irq); | 3026 | free_remapped_irq(irq); |
3173 | raw_spin_lock_irqsave(&vector_lock, flags); | 3027 | raw_spin_lock_irqsave(&vector_lock, flags); |
3174 | __clear_irq_vector(irq, cfg); | 3028 | __clear_irq_vector(irq, cfg); |
3175 | raw_spin_unlock_irqrestore(&vector_lock, flags); | 3029 | raw_spin_unlock_irqrestore(&vector_lock, flags); |
@@ -3198,54 +3052,34 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, | |||
3198 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); | 3052 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); |
3199 | 3053 | ||
3200 | if (irq_remapped(cfg)) { | 3054 | if (irq_remapped(cfg)) { |
3201 | struct irte irte; | 3055 | compose_remapped_msi_msg(pdev, irq, dest, msg, hpet_id); |
3202 | int ir_index; | 3056 | return err; |
3203 | u16 sub_handle; | 3057 | } |
3204 | |||
3205 | ir_index = map_irq_to_irte_handle(irq, &sub_handle); | ||
3206 | BUG_ON(ir_index == -1); | ||
3207 | |||
3208 | prepare_irte(&irte, cfg->vector, dest); | ||
3209 | |||
3210 | /* Set source-id of interrupt request */ | ||
3211 | if (pdev) | ||
3212 | set_msi_sid(&irte, pdev); | ||
3213 | else | ||
3214 | set_hpet_sid(&irte, hpet_id); | ||
3215 | |||
3216 | modify_irte(irq, &irte); | ||
3217 | 3058 | ||
3059 | if (x2apic_enabled()) | ||
3060 | msg->address_hi = MSI_ADDR_BASE_HI | | ||
3061 | MSI_ADDR_EXT_DEST_ID(dest); | ||
3062 | else | ||
3218 | msg->address_hi = MSI_ADDR_BASE_HI; | 3063 | msg->address_hi = MSI_ADDR_BASE_HI; |
3219 | msg->data = sub_handle; | ||
3220 | msg->address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_IR_EXT_INT | | ||
3221 | MSI_ADDR_IR_SHV | | ||
3222 | MSI_ADDR_IR_INDEX1(ir_index) | | ||
3223 | MSI_ADDR_IR_INDEX2(ir_index); | ||
3224 | } else { | ||
3225 | if (x2apic_enabled()) | ||
3226 | msg->address_hi = MSI_ADDR_BASE_HI | | ||
3227 | MSI_ADDR_EXT_DEST_ID(dest); | ||
3228 | else | ||
3229 | msg->address_hi = MSI_ADDR_BASE_HI; | ||
3230 | 3064 | ||
3231 | msg->address_lo = | 3065 | msg->address_lo = |
3232 | MSI_ADDR_BASE_LO | | 3066 | MSI_ADDR_BASE_LO | |
3233 | ((apic->irq_dest_mode == 0) ? | 3067 | ((apic->irq_dest_mode == 0) ? |
3234 | MSI_ADDR_DEST_MODE_PHYSICAL: | 3068 | MSI_ADDR_DEST_MODE_PHYSICAL: |
3235 | MSI_ADDR_DEST_MODE_LOGICAL) | | 3069 | MSI_ADDR_DEST_MODE_LOGICAL) | |
3236 | ((apic->irq_delivery_mode != dest_LowestPrio) ? | 3070 | ((apic->irq_delivery_mode != dest_LowestPrio) ? |
3237 | MSI_ADDR_REDIRECTION_CPU: | 3071 | MSI_ADDR_REDIRECTION_CPU: |
3238 | MSI_ADDR_REDIRECTION_LOWPRI) | | 3072 | MSI_ADDR_REDIRECTION_LOWPRI) | |
3239 | MSI_ADDR_DEST_ID(dest); | 3073 | MSI_ADDR_DEST_ID(dest); |
3074 | |||
3075 | msg->data = | ||
3076 | MSI_DATA_TRIGGER_EDGE | | ||
3077 | MSI_DATA_LEVEL_ASSERT | | ||
3078 | ((apic->irq_delivery_mode != dest_LowestPrio) ? | ||
3079 | MSI_DATA_DELIVERY_FIXED: | ||
3080 | MSI_DATA_DELIVERY_LOWPRI) | | ||
3081 | MSI_DATA_VECTOR(cfg->vector); | ||
3240 | 3082 | ||
3241 | msg->data = | ||
3242 | MSI_DATA_TRIGGER_EDGE | | ||
3243 | MSI_DATA_LEVEL_ASSERT | | ||
3244 | ((apic->irq_delivery_mode != dest_LowestPrio) ? | ||
3245 | MSI_DATA_DELIVERY_FIXED: | ||
3246 | MSI_DATA_DELIVERY_LOWPRI) | | ||
3247 | MSI_DATA_VECTOR(cfg->vector); | ||
3248 | } | ||
3249 | return err; | 3083 | return err; |
3250 | } | 3084 | } |
3251 | 3085 | ||
@@ -3288,33 +3122,6 @@ static struct irq_chip msi_chip = { | |||
3288 | .irq_retrigger = ioapic_retrigger_irq, | 3122 | .irq_retrigger = ioapic_retrigger_irq, |
3289 | }; | 3123 | }; |
3290 | 3124 | ||
3291 | /* | ||
3292 | * Map the PCI dev to the corresponding remapping hardware unit | ||
3293 | * and allocate 'nvec' consecutive interrupt-remapping table entries | ||
3294 | * in it. | ||
3295 | */ | ||
3296 | static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec) | ||
3297 | { | ||
3298 | struct intel_iommu *iommu; | ||
3299 | int index; | ||
3300 | |||
3301 | iommu = map_dev_to_ir(dev); | ||
3302 | if (!iommu) { | ||
3303 | printk(KERN_ERR | ||
3304 | "Unable to map PCI %s to iommu\n", pci_name(dev)); | ||
3305 | return -ENOENT; | ||
3306 | } | ||
3307 | |||
3308 | index = alloc_irte(iommu, irq, nvec); | ||
3309 | if (index < 0) { | ||
3310 | printk(KERN_ERR | ||
3311 | "Unable to allocate %d IRTE for PCI %s\n", nvec, | ||
3312 | pci_name(dev)); | ||
3313 | return -ENOSPC; | ||
3314 | } | ||
3315 | return index; | ||
3316 | } | ||
3317 | |||
3318 | static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) | 3125 | static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) |
3319 | { | 3126 | { |
3320 | struct irq_chip *chip = &msi_chip; | 3127 | struct irq_chip *chip = &msi_chip; |
@@ -3345,7 +3152,6 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
3345 | int node, ret, sub_handle, index = 0; | 3152 | int node, ret, sub_handle, index = 0; |
3346 | unsigned int irq, irq_want; | 3153 | unsigned int irq, irq_want; |
3347 | struct msi_desc *msidesc; | 3154 | struct msi_desc *msidesc; |
3348 | struct intel_iommu *iommu = NULL; | ||
3349 | 3155 | ||
3350 | /* x86 doesn't support multiple MSI yet */ | 3156 | /* x86 doesn't support multiple MSI yet */ |
3351 | if (type == PCI_CAP_ID_MSI && nvec > 1) | 3157 | if (type == PCI_CAP_ID_MSI && nvec > 1) |
@@ -3359,7 +3165,7 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
3359 | if (irq == 0) | 3165 | if (irq == 0) |
3360 | return -1; | 3166 | return -1; |
3361 | irq_want = irq + 1; | 3167 | irq_want = irq + 1; |
3362 | if (!intr_remapping_enabled) | 3168 | if (!irq_remapping_enabled) |
3363 | goto no_ir; | 3169 | goto no_ir; |
3364 | 3170 | ||
3365 | if (!sub_handle) { | 3171 | if (!sub_handle) { |
@@ -3367,23 +3173,16 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
3367 | * allocate the consecutive block of IRTE's | 3173 | * allocate the consecutive block of IRTE's |
3368 | * for 'nvec' | 3174 | * for 'nvec' |
3369 | */ | 3175 | */ |
3370 | index = msi_alloc_irte(dev, irq, nvec); | 3176 | index = msi_alloc_remapped_irq(dev, irq, nvec); |
3371 | if (index < 0) { | 3177 | if (index < 0) { |
3372 | ret = index; | 3178 | ret = index; |
3373 | goto error; | 3179 | goto error; |
3374 | } | 3180 | } |
3375 | } else { | 3181 | } else { |
3376 | iommu = map_dev_to_ir(dev); | 3182 | ret = msi_setup_remapped_irq(dev, irq, index, |
3377 | if (!iommu) { | 3183 | sub_handle); |
3378 | ret = -ENOENT; | 3184 | if (ret < 0) |
3379 | goto error; | 3185 | goto error; |
3380 | } | ||
3381 | /* | ||
3382 | * setup the mapping between the irq and the IRTE | ||
3383 | * base index, the sub_handle pointing to the | ||
3384 | * appropriate interrupt remap table entry. | ||
3385 | */ | ||
3386 | set_irte_irq(irq, iommu, index, sub_handle); | ||
3387 | } | 3186 | } |
3388 | no_ir: | 3187 | no_ir: |
3389 | ret = setup_msi_irq(dev, msidesc, irq); | 3188 | ret = setup_msi_irq(dev, msidesc, irq); |
@@ -3501,15 +3300,8 @@ int arch_setup_hpet_msi(unsigned int irq, unsigned int id) | |||
3501 | struct msi_msg msg; | 3300 | struct msi_msg msg; |
3502 | int ret; | 3301 | int ret; |
3503 | 3302 | ||
3504 | if (intr_remapping_enabled) { | 3303 | if (irq_remapping_enabled) { |
3505 | struct intel_iommu *iommu = map_hpet_to_ir(id); | 3304 | if (!setup_hpet_msi_remapped(irq, id)) |
3506 | int index; | ||
3507 | |||
3508 | if (!iommu) | ||
3509 | return -1; | ||
3510 | |||
3511 | index = alloc_irte(iommu, irq, 1); | ||
3512 | if (index < 0) | ||
3513 | return -1; | 3305 | return -1; |
3514 | } | 3306 | } |
3515 | 3307 | ||
@@ -3888,8 +3680,8 @@ void __init setup_ioapic_dest(void) | |||
3888 | else | 3680 | else |
3889 | mask = apic->target_cpus(); | 3681 | mask = apic->target_cpus(); |
3890 | 3682 | ||
3891 | if (intr_remapping_enabled) | 3683 | if (irq_remapping_enabled) |
3892 | ir_ioapic_set_affinity(idata, mask, false); | 3684 | set_remapped_irq_affinity(idata, mask, false); |
3893 | else | 3685 | else |
3894 | ioapic_set_affinity(idata, mask, false); | 3686 | ioapic_set_affinity(idata, mask, false); |
3895 | } | 3687 | } |
@@ -3931,12 +3723,7 @@ static struct resource * __init ioapic_setup_resources(int nr_ioapics) | |||
3931 | return res; | 3723 | return res; |
3932 | } | 3724 | } |
3933 | 3725 | ||
3934 | void __init ioapic_and_gsi_init(void) | 3726 | void __init native_io_apic_init_mappings(void) |
3935 | { | ||
3936 | io_apic_ops.init(); | ||
3937 | } | ||
3938 | |||
3939 | static void __init __ioapic_init_mappings(void) | ||
3940 | { | 3727 | { |
3941 | unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; | 3728 | unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; |
3942 | struct resource *ioapic_res; | 3729 | struct resource *ioapic_res; |
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c index 00d2422ca7c9..f00a68cca37a 100644 --- a/arch/x86/kernel/apic/numaq_32.c +++ b/arch/x86/kernel/apic/numaq_32.c | |||
@@ -530,6 +530,7 @@ static struct apic __refdata apic_numaq = { | |||
530 | 530 | ||
531 | .read = native_apic_mem_read, | 531 | .read = native_apic_mem_read, |
532 | .write = native_apic_mem_write, | 532 | .write = native_apic_mem_write, |
533 | .eoi_write = native_apic_mem_write, | ||
533 | .icr_read = native_apic_icr_read, | 534 | .icr_read = native_apic_icr_read, |
534 | .icr_write = native_apic_icr_write, | 535 | .icr_write = native_apic_icr_write, |
535 | .wait_icr_idle = native_apic_wait_icr_idle, | 536 | .wait_icr_idle = native_apic_wait_icr_idle, |
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index ff2c1b9aac4d..1b291da09e60 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c | |||
@@ -142,6 +142,7 @@ static struct apic apic_default = { | |||
142 | 142 | ||
143 | .read = native_apic_mem_read, | 143 | .read = native_apic_mem_read, |
144 | .write = native_apic_mem_write, | 144 | .write = native_apic_mem_write, |
145 | .eoi_write = native_apic_mem_write, | ||
145 | .icr_read = native_apic_icr_read, | 146 | .icr_read = native_apic_icr_read, |
146 | .icr_write = native_apic_icr_write, | 147 | .icr_write = native_apic_icr_write, |
147 | .wait_icr_idle = native_apic_wait_icr_idle, | 148 | .wait_icr_idle = native_apic_wait_icr_idle, |
diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index fea000b27f07..659897c00755 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c | |||
@@ -546,6 +546,7 @@ static struct apic apic_summit = { | |||
546 | 546 | ||
547 | .read = native_apic_mem_read, | 547 | .read = native_apic_mem_read, |
548 | .write = native_apic_mem_write, | 548 | .write = native_apic_mem_write, |
549 | .eoi_write = native_apic_mem_write, | ||
549 | .icr_read = native_apic_icr_read, | 550 | .icr_read = native_apic_icr_read, |
550 | .icr_write = native_apic_icr_write, | 551 | .icr_write = native_apic_icr_write, |
551 | .wait_icr_idle = native_apic_wait_icr_idle, | 552 | .wait_icr_idle = native_apic_wait_icr_idle, |
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 48f3103b3c93..ff35cff0e1a7 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c | |||
@@ -260,6 +260,7 @@ static struct apic apic_x2apic_cluster = { | |||
260 | 260 | ||
261 | .read = native_apic_msr_read, | 261 | .read = native_apic_msr_read, |
262 | .write = native_apic_msr_write, | 262 | .write = native_apic_msr_write, |
263 | .eoi_write = native_apic_msr_eoi_write, | ||
263 | .icr_read = native_x2apic_icr_read, | 264 | .icr_read = native_x2apic_icr_read, |
264 | .icr_write = native_x2apic_icr_write, | 265 | .icr_write = native_x2apic_icr_write, |
265 | .wait_icr_idle = native_x2apic_wait_icr_idle, | 266 | .wait_icr_idle = native_x2apic_wait_icr_idle, |
diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index 8a778db45e3a..c17e982db275 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c | |||
@@ -24,6 +24,12 @@ static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |||
24 | { | 24 | { |
25 | if (x2apic_phys) | 25 | if (x2apic_phys) |
26 | return x2apic_enabled(); | 26 | return x2apic_enabled(); |
27 | else if ((acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) && | ||
28 | (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL) && | ||
29 | x2apic_enabled()) { | ||
30 | printk(KERN_DEBUG "System requires x2apic physical mode\n"); | ||
31 | return 1; | ||
32 | } | ||
27 | else | 33 | else |
28 | return 0; | 34 | return 0; |
29 | } | 35 | } |
@@ -166,6 +172,7 @@ static struct apic apic_x2apic_phys = { | |||
166 | 172 | ||
167 | .read = native_apic_msr_read, | 173 | .read = native_apic_msr_read, |
168 | .write = native_apic_msr_write, | 174 | .write = native_apic_msr_write, |
175 | .eoi_write = native_apic_msr_eoi_write, | ||
169 | .icr_read = native_x2apic_icr_read, | 176 | .icr_read = native_x2apic_icr_read, |
170 | .icr_write = native_x2apic_icr_write, | 177 | .icr_write = native_x2apic_icr_write, |
171 | .wait_icr_idle = native_x2apic_wait_icr_idle, | 178 | .wait_icr_idle = native_x2apic_wait_icr_idle, |
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 87bfa69e216e..c6d03f7a4401 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -404,6 +404,7 @@ static struct apic __refdata apic_x2apic_uv_x = { | |||
404 | 404 | ||
405 | .read = native_apic_msr_read, | 405 | .read = native_apic_msr_read, |
406 | .write = native_apic_msr_write, | 406 | .write = native_apic_msr_write, |
407 | .eoi_write = native_apic_msr_eoi_write, | ||
407 | .icr_read = native_x2apic_icr_read, | 408 | .icr_read = native_x2apic_icr_read, |
408 | .icr_write = native_x2apic_icr_write, | 409 | .icr_write = native_x2apic_icr_write, |
409 | .wait_icr_idle = native_x2apic_wait_icr_idle, | 410 | .wait_icr_idle = native_x2apic_wait_icr_idle, |