aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-21 22:23:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-21 22:23:41 -0400
commitabd209b7083b2f3a2a19e522f688e7569f284e5d (patch)
tree51b0d86562c2293df27ba8b6effc7a5ddd7c30f0 /arch
parent513de477a09f770e42ad042bf830565d9c73a158 (diff)
parentfefe1ed1398b81e3fadc92d11d91162d343c8836 (diff)
Merge branch 'core-iommu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull iommu core changes from Ingo Molnar: "The IOMMU changes in this cycle are mostly about factoring out Intel-VT-d specific IRQ remapping details and introducing struct irq_remap_ops, in preparation for AMD specific hardware." * 'core-iommu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: iommu: Fix off by one in dmar_get_fault_reason() irq_remap: Fix the 'sub_handle' uninitialized warning irq_remap: Fix UP build failure irq_remap: Fix compiler warning with CONFIG_IRQ_REMAP=y iommu: rename intr_remapping.[ch] to irq_remapping.[ch] iommu: rename intr_remapping references to irq_remapping x86, iommu/vt-d: Clean up interfaces for interrupt remapping iommu/vt-d: Convert MSI remapping setup to remap_ops iommu/vt-d: Convert free_irte into a remap_ops callback iommu/vt-d: Convert IR set_affinity function to remap_ops iommu/vt-d: Convert IR ioapic-setup to use remap_ops iommu/vt-d: Convert missing apic.c intr-remapping call to remap_ops iommu/vt-d: Make intr-remapping initialization generic iommu: Rename intr_remapping files to intel_intr_remapping
Diffstat (limited to 'arch')
-rw-r--r--arch/ia64/include/asm/irq_remapping.h4
-rw-r--r--arch/x86/include/asm/irq_remapping.h118
-rw-r--r--arch/x86/kernel/apic/apic.c30
-rw-r--r--arch/x86/kernel/apic/io_apic.c297
4 files changed, 169 insertions, 280 deletions
diff --git a/arch/ia64/include/asm/irq_remapping.h b/arch/ia64/include/asm/irq_remapping.h
new file mode 100644
index 000000000000..a8687b1d8906
--- /dev/null
+++ b/arch/ia64/include/asm/irq_remapping.h
@@ -0,0 +1,4 @@
1#ifndef __IA64_INTR_REMAPPING_H
2#define __IA64_INTR_REMAPPING_H
3#define irq_remapping_enabled 0
4#endif
diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h
index 47d99934580f..5fb9bbbd2f14 100644
--- a/arch/x86/include/asm/irq_remapping.h
+++ b/arch/x86/include/asm/irq_remapping.h
@@ -1,45 +1,101 @@
1#ifndef _ASM_X86_IRQ_REMAPPING_H 1/*
2#define _ASM_X86_IRQ_REMAPPING_H 2 * Copyright (C) 2012 Advanced Micro Devices, Inc.
3 * Author: Joerg Roedel <joerg.roedel@amd.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published
7 * by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * This header file contains the interface of the interrupt remapping code to
19 * the x86 interrupt management code.
20 */
3 21
4#define IRTE_DEST(dest) ((x2apic_mode) ? dest : dest << 8) 22#ifndef __X86_IRQ_REMAPPING_H
23#define __X86_IRQ_REMAPPING_H
24
25#include <asm/io_apic.h>
5 26
6#ifdef CONFIG_IRQ_REMAP 27#ifdef CONFIG_IRQ_REMAP
7static void irq_remap_modify_chip_defaults(struct irq_chip *chip); 28
8static inline void prepare_irte(struct irte *irte, int vector, 29extern int irq_remapping_enabled;
9 unsigned int dest) 30
31extern void setup_irq_remapping_ops(void);
32extern int irq_remapping_supported(void);
33extern int irq_remapping_prepare(void);
34extern int irq_remapping_enable(void);
35extern void irq_remapping_disable(void);
36extern int irq_remapping_reenable(int);
37extern int irq_remap_enable_fault_handling(void);
38extern int setup_ioapic_remapped_entry(int irq,
39 struct IO_APIC_route_entry *entry,
40 unsigned int destination,
41 int vector,
42 struct io_apic_irq_attr *attr);
43extern int set_remapped_irq_affinity(struct irq_data *data,
44 const struct cpumask *mask,
45 bool force);
46extern void free_remapped_irq(int irq);
47extern void compose_remapped_msi_msg(struct pci_dev *pdev,
48 unsigned int irq, unsigned int dest,
49 struct msi_msg *msg, u8 hpet_id);
50extern int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec);
51extern int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq,
52 int index, int sub_handle);
53extern int setup_hpet_msi_remapped(unsigned int irq, unsigned int id);
54
55#else /* CONFIG_IRQ_REMAP */
56
57#define irq_remapping_enabled 0
58
59static inline void setup_irq_remapping_ops(void) { }
60static inline int irq_remapping_supported(void) { return 0; }
61static inline int irq_remapping_prepare(void) { return -ENODEV; }
62static inline int irq_remapping_enable(void) { return -ENODEV; }
63static inline void irq_remapping_disable(void) { }
64static inline int irq_remapping_reenable(int eim) { return -ENODEV; }
65static inline int irq_remap_enable_fault_handling(void) { return -ENODEV; }
66static inline int setup_ioapic_remapped_entry(int irq,
67 struct IO_APIC_route_entry *entry,
68 unsigned int destination,
69 int vector,
70 struct io_apic_irq_attr *attr)
71{
72 return -ENODEV;
73}
74static inline int set_remapped_irq_affinity(struct irq_data *data,
75 const struct cpumask *mask,
76 bool force)
10{ 77{
11 memset(irte, 0, sizeof(*irte)); 78 return 0;
12
13 irte->present = 1;
14 irte->dst_mode = apic->irq_dest_mode;
15 /*
16 * Trigger mode in the IRTE will always be edge, and for IO-APIC, the
17 * actual level or edge trigger will be setup in the IO-APIC
18 * RTE. This will help simplify level triggered irq migration.
19 * For more details, see the comments (in io_apic.c) explainig IO-APIC
20 * irq migration in the presence of interrupt-remapping.
21 */
22 irte->trigger_mode = 0;
23 irte->dlvry_mode = apic->irq_delivery_mode;
24 irte->vector = vector;
25 irte->dest_id = IRTE_DEST(dest);
26 irte->redir_hint = 1;
27} 79}
28static inline bool irq_remapped(struct irq_cfg *cfg) 80static inline void free_remapped_irq(int irq) { }
81static inline void compose_remapped_msi_msg(struct pci_dev *pdev,
82 unsigned int irq, unsigned int dest,
83 struct msi_msg *msg, u8 hpet_id)
29{ 84{
30 return cfg->irq_2_iommu.iommu != NULL;
31} 85}
32#else 86static inline int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec)
33static void prepare_irte(struct irte *irte, int vector, unsigned int dest)
34{ 87{
88 return -ENODEV;
35} 89}
36static inline bool irq_remapped(struct irq_cfg *cfg) 90static inline int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq,
91 int index, int sub_handle)
37{ 92{
38 return false; 93 return -ENODEV;
39} 94}
40static inline void irq_remap_modify_chip_defaults(struct irq_chip *chip) 95static inline int setup_hpet_msi_remapped(unsigned int irq, unsigned int id)
41{ 96{
97 return -ENODEV;
42} 98}
43#endif 99#endif /* CONFIG_IRQ_REMAP */
44 100
45#endif /* _ASM_X86_IRQ_REMAPPING_H */ 101#endif /* __X86_IRQ_REMAPPING_H */
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index edc24480469f..3722179a49db 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>
@@ -1441,8 +1442,8 @@ void __init bsp_end_local_APIC_setup(void)
1441 * Now that local APIC setup is completed for BP, configure the fault 1442 * Now that local APIC setup is completed for BP, configure the fault
1442 * handling for interrupt remapping. 1443 * handling for interrupt remapping.
1443 */ 1444 */
1444 if (intr_remapping_enabled) 1445 if (irq_remapping_enabled)
1445 enable_drhd_fault_handling(); 1446 irq_remap_enable_fault_handling();
1446 1447
1447} 1448}
1448 1449
@@ -1517,7 +1518,7 @@ void enable_x2apic(void)
1517int __init enable_IR(void) 1518int __init enable_IR(void)
1518{ 1519{
1519#ifdef CONFIG_IRQ_REMAP 1520#ifdef CONFIG_IRQ_REMAP
1520 if (!intr_remapping_supported()) { 1521 if (!irq_remapping_supported()) {
1521 pr_debug("intr-remapping not supported\n"); 1522 pr_debug("intr-remapping not supported\n");
1522 return -1; 1523 return -1;
1523 } 1524 }
@@ -1528,7 +1529,7 @@ int __init enable_IR(void)
1528 return -1; 1529 return -1;
1529 } 1530 }
1530 1531
1531 return enable_intr_remapping(); 1532 return irq_remapping_enable();
1532#endif 1533#endif
1533 return -1; 1534 return -1;
1534} 1535}
@@ -1537,10 +1538,13 @@ void __init enable_IR_x2apic(void)
1537{ 1538{
1538 unsigned long flags; 1539 unsigned long flags;
1539 int ret, x2apic_enabled = 0; 1540 int ret, x2apic_enabled = 0;
1540 int dmar_table_init_ret; 1541 int hardware_init_ret;
1541 1542
1542 dmar_table_init_ret = dmar_table_init(); 1543 /* Make sure irq_remap_ops are initialized */
1543 if (dmar_table_init_ret && !x2apic_supported()) 1544 setup_irq_remapping_ops();
1545
1546 hardware_init_ret = irq_remapping_prepare();
1547 if (hardware_init_ret && !x2apic_supported())
1544 return; 1548 return;
1545 1549
1546 ret = save_ioapic_entries(); 1550 ret = save_ioapic_entries();
@@ -1556,7 +1560,7 @@ void __init enable_IR_x2apic(void)
1556 if (x2apic_preenabled && nox2apic) 1560 if (x2apic_preenabled && nox2apic)
1557 disable_x2apic(); 1561 disable_x2apic();
1558 1562
1559 if (dmar_table_init_ret) 1563 if (hardware_init_ret)
1560 ret = -1; 1564 ret = -1;
1561 else 1565 else
1562 ret = enable_IR(); 1566 ret = enable_IR();
@@ -2176,8 +2180,8 @@ static int lapic_suspend(void)
2176 local_irq_save(flags); 2180 local_irq_save(flags);
2177 disable_local_APIC(); 2181 disable_local_APIC();
2178 2182
2179 if (intr_remapping_enabled) 2183 if (irq_remapping_enabled)
2180 disable_intr_remapping(); 2184 irq_remapping_disable();
2181 2185
2182 local_irq_restore(flags); 2186 local_irq_restore(flags);
2183 return 0; 2187 return 0;
@@ -2193,7 +2197,7 @@ static void lapic_resume(void)
2193 return; 2197 return;
2194 2198
2195 local_irq_save(flags); 2199 local_irq_save(flags);
2196 if (intr_remapping_enabled) { 2200 if (irq_remapping_enabled) {
2197 /* 2201 /*
2198 * IO-APIC and PIC have their own resume routines. 2202 * IO-APIC and PIC have their own resume routines.
2199 * We just mask them here to make sure the interrupt 2203 * We just mask them here to make sure the interrupt
@@ -2245,8 +2249,8 @@ static void lapic_resume(void)
2245 apic_write(APIC_ESR, 0); 2249 apic_write(APIC_ESR, 0);
2246 apic_read(APIC_ESR); 2250 apic_read(APIC_ESR);
2247 2251
2248 if (intr_remapping_enabled) 2252 if (irq_remapping_enabled)
2249 reenable_intr_remapping(x2apic_mode); 2253 irq_remapping_reenable(x2apic_mode);
2250 2254
2251 local_irq_restore(flags); 2255 local_irq_restore(flags);
2252} 2256}
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index e88300d8e80a..ef0648cd7084 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -86,6 +86,22 @@ void __init set_io_apic_ops(const struct io_apic_ops *ops)
86 io_apic_ops = *ops; 86 io_apic_ops = *ops;
87} 87}
88 88
89#ifdef CONFIG_IRQ_REMAP
90static void irq_remap_modify_chip_defaults(struct irq_chip *chip);
91static inline bool irq_remapped(struct irq_cfg *cfg)
92{
93 return cfg->irq_2_iommu.iommu != NULL;
94}
95#else
96static inline bool irq_remapped(struct irq_cfg *cfg)
97{
98 return false;
99}
100static inline void irq_remap_modify_chip_defaults(struct irq_chip *chip)
101{
102}
103#endif
104
89/* 105/*
90 * Is the SiS APIC rmw bug present ? 106 * Is the SiS APIC rmw bug present ?
91 * -1 = don't know, 0 = no, 1 = yes 107 * -1 = don't know, 0 = no, 1 = yes
@@ -1361,77 +1377,13 @@ static void ioapic_register_intr(unsigned int irq, struct irq_cfg *cfg,
1361 fasteoi ? "fasteoi" : "edge"); 1377 fasteoi ? "fasteoi" : "edge");
1362} 1378}
1363 1379
1364
1365static 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
1427static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry, 1380static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry,
1428 unsigned int destination, int vector, 1381 unsigned int destination, int vector,
1429 struct io_apic_irq_attr *attr) 1382 struct io_apic_irq_attr *attr)
1430{ 1383{
1431 if (intr_remapping_enabled) 1384 if (irq_remapping_enabled)
1432 return setup_ir_ioapic_entry(irq, 1385 return setup_ioapic_remapped_entry(irq, entry, destination,
1433 (struct IR_IO_APIC_route_entry *)entry, 1386 vector, attr);
1434 destination, vector, attr);
1435 1387
1436 memset(entry, 0, sizeof(*entry)); 1388 memset(entry, 0, sizeof(*entry));
1437 1389
@@ -1588,7 +1540,7 @@ static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx,
1588{ 1540{
1589 struct IO_APIC_route_entry entry; 1541 struct IO_APIC_route_entry entry;
1590 1542
1591 if (intr_remapping_enabled) 1543 if (irq_remapping_enabled)
1592 return; 1544 return;
1593 1545
1594 memset(&entry, 0, sizeof(entry)); 1546 memset(&entry, 0, sizeof(entry));
@@ -1674,7 +1626,7 @@ __apicdebuginit(void) print_IO_APIC(int ioapic_idx)
1674 1626
1675 printk(KERN_DEBUG ".... IRQ redirection table:\n"); 1627 printk(KERN_DEBUG ".... IRQ redirection table:\n");
1676 1628
1677 if (intr_remapping_enabled) { 1629 if (irq_remapping_enabled) {
1678 printk(KERN_DEBUG " NR Indx Fmt Mask Trig IRR" 1630 printk(KERN_DEBUG " NR Indx Fmt Mask Trig IRR"
1679 " Pol Stat Indx2 Zero Vect:\n"); 1631 " Pol Stat Indx2 Zero Vect:\n");
1680 } else { 1632 } else {
@@ -1683,7 +1635,7 @@ __apicdebuginit(void) print_IO_APIC(int ioapic_idx)
1683 } 1635 }
1684 1636
1685 for (i = 0; i <= reg_01.bits.entries; i++) { 1637 for (i = 0; i <= reg_01.bits.entries; i++) {
1686 if (intr_remapping_enabled) { 1638 if (irq_remapping_enabled) {
1687 struct IO_APIC_route_entry entry; 1639 struct IO_APIC_route_entry entry;
1688 struct IR_IO_APIC_route_entry *ir_entry; 1640 struct IR_IO_APIC_route_entry *ir_entry;
1689 1641
@@ -2050,7 +2002,7 @@ void disable_IO_APIC(void)
2050 * IOAPIC RTE as well as interrupt-remapping table entry). 2002 * IOAPIC RTE as well as interrupt-remapping table entry).
2051 * As this gets called during crash dump, keep this simple for now. 2003 * As this gets called during crash dump, keep this simple for now.
2052 */ 2004 */
2053 if (ioapic_i8259.pin != -1 && !intr_remapping_enabled) { 2005 if (ioapic_i8259.pin != -1 && !irq_remapping_enabled) {
2054 struct IO_APIC_route_entry entry; 2006 struct IO_APIC_route_entry entry;
2055 2007
2056 memset(&entry, 0, sizeof(entry)); 2008 memset(&entry, 0, sizeof(entry));
@@ -2074,7 +2026,7 @@ void disable_IO_APIC(void)
2074 * Use virtual wire A mode when interrupt remapping is enabled. 2026 * Use virtual wire A mode when interrupt remapping is enabled.
2075 */ 2027 */
2076 if (cpu_has_apic || apic_from_smp_config()) 2028 if (cpu_has_apic || apic_from_smp_config())
2077 disconnect_bsp_APIC(!intr_remapping_enabled && 2029 disconnect_bsp_APIC(!irq_remapping_enabled &&
2078 ioapic_i8259.pin != -1); 2030 ioapic_i8259.pin != -1);
2079} 2031}
2080 2032
@@ -2390,71 +2342,6 @@ ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
2390 return ret; 2342 return ret;
2391} 2343}
2392 2344
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 */
2409static int
2410ir_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
2450static inline int
2451ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
2452 bool force)
2453{
2454 return 0;
2455}
2456#endif
2457
2458asmlinkage void smp_irq_move_cleanup_interrupt(void) 2345asmlinkage void smp_irq_move_cleanup_interrupt(void)
2459{ 2346{
2460 unsigned vector, me; 2347 unsigned vector, me;
@@ -2699,7 +2586,7 @@ static void irq_remap_modify_chip_defaults(struct irq_chip *chip)
2699 chip->irq_eoi = ir_ack_apic_level; 2586 chip->irq_eoi = ir_ack_apic_level;
2700 2587
2701#ifdef CONFIG_SMP 2588#ifdef CONFIG_SMP
2702 chip->irq_set_affinity = ir_ioapic_set_affinity; 2589 chip->irq_set_affinity = set_remapped_irq_affinity;
2703#endif 2590#endif
2704} 2591}
2705#endif /* CONFIG_IRQ_REMAP */ 2592#endif /* CONFIG_IRQ_REMAP */
@@ -2912,7 +2799,7 @@ static inline void __init check_timer(void)
2912 * 8259A. 2799 * 8259A.
2913 */ 2800 */
2914 if (pin1 == -1) { 2801 if (pin1 == -1) {
2915 if (intr_remapping_enabled) 2802 if (irq_remapping_enabled)
2916 panic("BIOS bug: timer not connected to IO-APIC"); 2803 panic("BIOS bug: timer not connected to IO-APIC");
2917 pin1 = pin2; 2804 pin1 = pin2;
2918 apic1 = apic2; 2805 apic1 = apic2;
@@ -2945,7 +2832,7 @@ static inline void __init check_timer(void)
2945 clear_IO_APIC_pin(0, pin1); 2832 clear_IO_APIC_pin(0, pin1);
2946 goto out; 2833 goto out;
2947 } 2834 }
2948 if (intr_remapping_enabled) 2835 if (irq_remapping_enabled)
2949 panic("timer doesn't work through Interrupt-remapped IO-APIC"); 2836 panic("timer doesn't work through Interrupt-remapped IO-APIC");
2950 local_irq_disable(); 2837 local_irq_disable();
2951 clear_IO_APIC_pin(apic1, pin1); 2838 clear_IO_APIC_pin(apic1, pin1);
@@ -3169,7 +3056,7 @@ void destroy_irq(unsigned int irq)
3169 irq_set_status_flags(irq, IRQ_NOREQUEST|IRQ_NOPROBE); 3056 irq_set_status_flags(irq, IRQ_NOREQUEST|IRQ_NOPROBE);
3170 3057
3171 if (irq_remapped(cfg)) 3058 if (irq_remapped(cfg))
3172 free_irte(irq); 3059 free_remapped_irq(irq);
3173 raw_spin_lock_irqsave(&vector_lock, flags); 3060 raw_spin_lock_irqsave(&vector_lock, flags);
3174 __clear_irq_vector(irq, cfg); 3061 __clear_irq_vector(irq, cfg);
3175 raw_spin_unlock_irqrestore(&vector_lock, flags); 3062 raw_spin_unlock_irqrestore(&vector_lock, flags);
@@ -3198,54 +3085,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()); 3085 dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus());
3199 3086
3200 if (irq_remapped(cfg)) { 3087 if (irq_remapped(cfg)) {
3201 struct irte irte; 3088 compose_remapped_msi_msg(pdev, irq, dest, msg, hpet_id);
3202 int ir_index; 3089 return err;
3203 u16 sub_handle; 3090 }
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 3091
3092 if (x2apic_enabled())
3093 msg->address_hi = MSI_ADDR_BASE_HI |
3094 MSI_ADDR_EXT_DEST_ID(dest);
3095 else
3218 msg->address_hi = MSI_ADDR_BASE_HI; 3096 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 3097
3231 msg->address_lo = 3098 msg->address_lo =
3232 MSI_ADDR_BASE_LO | 3099 MSI_ADDR_BASE_LO |
3233 ((apic->irq_dest_mode == 0) ? 3100 ((apic->irq_dest_mode == 0) ?
3234 MSI_ADDR_DEST_MODE_PHYSICAL: 3101 MSI_ADDR_DEST_MODE_PHYSICAL:
3235 MSI_ADDR_DEST_MODE_LOGICAL) | 3102 MSI_ADDR_DEST_MODE_LOGICAL) |
3236 ((apic->irq_delivery_mode != dest_LowestPrio) ? 3103 ((apic->irq_delivery_mode != dest_LowestPrio) ?
3237 MSI_ADDR_REDIRECTION_CPU: 3104 MSI_ADDR_REDIRECTION_CPU:
3238 MSI_ADDR_REDIRECTION_LOWPRI) | 3105 MSI_ADDR_REDIRECTION_LOWPRI) |
3239 MSI_ADDR_DEST_ID(dest); 3106 MSI_ADDR_DEST_ID(dest);
3107
3108 msg->data =
3109 MSI_DATA_TRIGGER_EDGE |
3110 MSI_DATA_LEVEL_ASSERT |
3111 ((apic->irq_delivery_mode != dest_LowestPrio) ?
3112 MSI_DATA_DELIVERY_FIXED:
3113 MSI_DATA_DELIVERY_LOWPRI) |
3114 MSI_DATA_VECTOR(cfg->vector);
3240 3115
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; 3116 return err;
3250} 3117}
3251 3118
@@ -3288,33 +3155,6 @@ static struct irq_chip msi_chip = {
3288 .irq_retrigger = ioapic_retrigger_irq, 3155 .irq_retrigger = ioapic_retrigger_irq,
3289}; 3156};
3290 3157
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 */
3296static 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
3318static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) 3158static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
3319{ 3159{
3320 struct irq_chip *chip = &msi_chip; 3160 struct irq_chip *chip = &msi_chip;
@@ -3345,7 +3185,6 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
3345 int node, ret, sub_handle, index = 0; 3185 int node, ret, sub_handle, index = 0;
3346 unsigned int irq, irq_want; 3186 unsigned int irq, irq_want;
3347 struct msi_desc *msidesc; 3187 struct msi_desc *msidesc;
3348 struct intel_iommu *iommu = NULL;
3349 3188
3350 /* x86 doesn't support multiple MSI yet */ 3189 /* x86 doesn't support multiple MSI yet */
3351 if (type == PCI_CAP_ID_MSI && nvec > 1) 3190 if (type == PCI_CAP_ID_MSI && nvec > 1)
@@ -3359,7 +3198,7 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
3359 if (irq == 0) 3198 if (irq == 0)
3360 return -1; 3199 return -1;
3361 irq_want = irq + 1; 3200 irq_want = irq + 1;
3362 if (!intr_remapping_enabled) 3201 if (!irq_remapping_enabled)
3363 goto no_ir; 3202 goto no_ir;
3364 3203
3365 if (!sub_handle) { 3204 if (!sub_handle) {
@@ -3367,23 +3206,16 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
3367 * allocate the consecutive block of IRTE's 3206 * allocate the consecutive block of IRTE's
3368 * for 'nvec' 3207 * for 'nvec'
3369 */ 3208 */
3370 index = msi_alloc_irte(dev, irq, nvec); 3209 index = msi_alloc_remapped_irq(dev, irq, nvec);
3371 if (index < 0) { 3210 if (index < 0) {
3372 ret = index; 3211 ret = index;
3373 goto error; 3212 goto error;
3374 } 3213 }
3375 } else { 3214 } else {
3376 iommu = map_dev_to_ir(dev); 3215 ret = msi_setup_remapped_irq(dev, irq, index,
3377 if (!iommu) { 3216 sub_handle);
3378 ret = -ENOENT; 3217 if (ret < 0)
3379 goto error; 3218 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 } 3219 }
3388no_ir: 3220no_ir:
3389 ret = setup_msi_irq(dev, msidesc, irq); 3221 ret = setup_msi_irq(dev, msidesc, irq);
@@ -3501,15 +3333,8 @@ int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
3501 struct msi_msg msg; 3333 struct msi_msg msg;
3502 int ret; 3334 int ret;
3503 3335
3504 if (intr_remapping_enabled) { 3336 if (irq_remapping_enabled) {
3505 struct intel_iommu *iommu = map_hpet_to_ir(id); 3337 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; 3338 return -1;
3514 } 3339 }
3515 3340
@@ -3888,8 +3713,8 @@ void __init setup_ioapic_dest(void)
3888 else 3713 else
3889 mask = apic->target_cpus(); 3714 mask = apic->target_cpus();
3890 3715
3891 if (intr_remapping_enabled) 3716 if (irq_remapping_enabled)
3892 ir_ioapic_set_affinity(idata, mask, false); 3717 set_remapped_irq_affinity(idata, mask, false);
3893 else 3718 else
3894 ioapic_set_affinity(idata, mask, false); 3719 ioapic_set_affinity(idata, mask, false);
3895 } 3720 }