aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--drivers/iommu/Makefile2
-rw-r--r--drivers/iommu/dmar.c11
-rw-r--r--drivers/iommu/intel-iommu.c3
-rw-r--r--drivers/iommu/intel_irq_remapping.c (renamed from drivers/iommu/intr_remapping.c)359
-rw-r--r--drivers/iommu/intr_remapping.h17
-rw-r--r--drivers/iommu/irq_remapping.c166
-rw-r--r--drivers/iommu/irq_remapping.h90
-rw-r--r--include/linux/dmar.h85
12 files changed, 731 insertions, 451 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 }
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 7ad7a3bc1242..3e5e82ae9f0d 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -4,7 +4,7 @@ obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
4obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o 4obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
5obj-$(CONFIG_DMAR_TABLE) += dmar.o 5obj-$(CONFIG_DMAR_TABLE) += dmar.o
6obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o 6obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o
7obj-$(CONFIG_IRQ_REMAP) += intr_remapping.o 7obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o
8obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o 8obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
9obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o 9obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o
10obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o 10obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 35c1e17fce1d..3a74e4410fc0 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -36,6 +36,7 @@
36#include <linux/tboot.h> 36#include <linux/tboot.h>
37#include <linux/dmi.h> 37#include <linux/dmi.h>
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <asm/irq_remapping.h>
39#include <asm/iommu_table.h> 40#include <asm/iommu_table.h>
40 41
41#define PREFIX "DMAR: " 42#define PREFIX "DMAR: "
@@ -555,7 +556,7 @@ int __init detect_intel_iommu(void)
555 556
556 dmar = (struct acpi_table_dmar *) dmar_tbl; 557 dmar = (struct acpi_table_dmar *) dmar_tbl;
557 558
558 if (ret && intr_remapping_enabled && cpu_has_x2apic && 559 if (ret && irq_remapping_enabled && cpu_has_x2apic &&
559 dmar->flags & 0x1) 560 dmar->flags & 0x1)
560 printk(KERN_INFO 561 printk(KERN_INFO
561 "Queued invalidation will be enabled to support x2apic and Intr-remapping.\n"); 562 "Queued invalidation will be enabled to support x2apic and Intr-remapping.\n");
@@ -1041,7 +1042,7 @@ static const char *dma_remap_fault_reasons[] =
1041 "non-zero reserved fields in PTE", 1042 "non-zero reserved fields in PTE",
1042}; 1043};
1043 1044
1044static const char *intr_remap_fault_reasons[] = 1045static const char *irq_remap_fault_reasons[] =
1045{ 1046{
1046 "Detected reserved fields in the decoded interrupt-remapped request", 1047 "Detected reserved fields in the decoded interrupt-remapped request",
1047 "Interrupt index exceeded the interrupt-remapping table size", 1048 "Interrupt index exceeded the interrupt-remapping table size",
@@ -1056,10 +1057,10 @@ static const char *intr_remap_fault_reasons[] =
1056 1057
1057const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type) 1058const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type)
1058{ 1059{
1059 if (fault_reason >= 0x20 && (fault_reason <= 0x20 + 1060 if (fault_reason >= 0x20 && (fault_reason - 0x20 <
1060 ARRAY_SIZE(intr_remap_fault_reasons))) { 1061 ARRAY_SIZE(irq_remap_fault_reasons))) {
1061 *fault_type = INTR_REMAP; 1062 *fault_type = INTR_REMAP;
1062 return intr_remap_fault_reasons[fault_reason - 0x20]; 1063 return irq_remap_fault_reasons[fault_reason - 0x20];
1063 } else if (fault_reason < ARRAY_SIZE(dma_remap_fault_reasons)) { 1064 } else if (fault_reason < ARRAY_SIZE(dma_remap_fault_reasons)) {
1064 *fault_type = DMA_REMAP; 1065 *fault_type = DMA_REMAP;
1065 return dma_remap_fault_reasons[fault_reason]; 1066 return dma_remap_fault_reasons[fault_reason];
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index f93d5ac8f81c..bf2fbaad5e22 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -42,6 +42,7 @@
42#include <linux/dmi.h> 42#include <linux/dmi.h>
43#include <linux/pci-ats.h> 43#include <linux/pci-ats.h>
44#include <linux/memblock.h> 44#include <linux/memblock.h>
45#include <asm/irq_remapping.h>
45#include <asm/cacheflush.h> 46#include <asm/cacheflush.h>
46#include <asm/iommu.h> 47#include <asm/iommu.h>
47 48
@@ -4082,7 +4083,7 @@ static int intel_iommu_domain_has_cap(struct iommu_domain *domain,
4082 if (cap == IOMMU_CAP_CACHE_COHERENCY) 4083 if (cap == IOMMU_CAP_CACHE_COHERENCY)
4083 return dmar_domain->iommu_snooping; 4084 return dmar_domain->iommu_snooping;
4084 if (cap == IOMMU_CAP_INTR_REMAP) 4085 if (cap == IOMMU_CAP_INTR_REMAP)
4085 return intr_remapping_enabled; 4086 return irq_remapping_enabled;
4086 4087
4087 return 0; 4088 return 0;
4088} 4089}
diff --git a/drivers/iommu/intr_remapping.c b/drivers/iommu/intel_irq_remapping.c
index 6777ca049471..6d347064b8b0 100644
--- a/drivers/iommu/intr_remapping.c
+++ b/drivers/iommu/intel_irq_remapping.c
@@ -10,49 +10,33 @@
10#include <asm/smp.h> 10#include <asm/smp.h>
11#include <asm/cpu.h> 11#include <asm/cpu.h>
12#include <linux/intel-iommu.h> 12#include <linux/intel-iommu.h>
13#include "intr_remapping.h"
14#include <acpi/acpi.h> 13#include <acpi/acpi.h>
14#include <asm/irq_remapping.h>
15#include <asm/pci-direct.h> 15#include <asm/pci-direct.h>
16#include <asm/msidef.h>
16 17
17static struct ioapic_scope ir_ioapic[MAX_IO_APICS]; 18#include "irq_remapping.h"
18static struct hpet_scope ir_hpet[MAX_HPET_TBS];
19static int ir_ioapic_num, ir_hpet_num;
20int intr_remapping_enabled;
21
22static int disable_intremap;
23static int disable_sourceid_checking;
24static int no_x2apic_optout;
25 19
26static __init int setup_nointremap(char *str) 20struct ioapic_scope {
27{ 21 struct intel_iommu *iommu;
28 disable_intremap = 1; 22 unsigned int id;
29 return 0; 23 unsigned int bus; /* PCI bus number */
30} 24 unsigned int devfn; /* PCI devfn number */
31early_param("nointremap", setup_nointremap); 25};
32 26
33static __init int setup_intremap(char *str) 27struct hpet_scope {
34{ 28 struct intel_iommu *iommu;
35 if (!str) 29 u8 id;
36 return -EINVAL; 30 unsigned int bus;
31 unsigned int devfn;
32};
37 33
38 while (*str) { 34#define IR_X2APIC_MODE(mode) (mode ? (1 << 11) : 0)
39 if (!strncmp(str, "on", 2)) 35#define IRTE_DEST(dest) ((x2apic_mode) ? dest : dest << 8)
40 disable_intremap = 0;
41 else if (!strncmp(str, "off", 3))
42 disable_intremap = 1;
43 else if (!strncmp(str, "nosid", 5))
44 disable_sourceid_checking = 1;
45 else if (!strncmp(str, "no_x2apic_optout", 16))
46 no_x2apic_optout = 1;
47
48 str += strcspn(str, ",");
49 while (*str == ',')
50 str++;
51 }
52 36
53 return 0; 37static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
54} 38static struct hpet_scope ir_hpet[MAX_HPET_TBS];
55early_param("intremap", setup_intremap); 39static int ir_ioapic_num, ir_hpet_num;
56 40
57static DEFINE_RAW_SPINLOCK(irq_2_ir_lock); 41static DEFINE_RAW_SPINLOCK(irq_2_ir_lock);
58 42
@@ -80,7 +64,7 @@ int get_irte(int irq, struct irte *entry)
80 return 0; 64 return 0;
81} 65}
82 66
83int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) 67static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
84{ 68{
85 struct ir_table *table = iommu->ir_table; 69 struct ir_table *table = iommu->ir_table;
86 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); 70 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq);
@@ -152,7 +136,7 @@ static int qi_flush_iec(struct intel_iommu *iommu, int index, int mask)
152 return qi_submit_sync(&desc, iommu); 136 return qi_submit_sync(&desc, iommu);
153} 137}
154 138
155int map_irq_to_irte_handle(int irq, u16 *sub_handle) 139static int map_irq_to_irte_handle(int irq, u16 *sub_handle)
156{ 140{
157 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); 141 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq);
158 unsigned long flags; 142 unsigned long flags;
@@ -168,7 +152,7 @@ int map_irq_to_irte_handle(int irq, u16 *sub_handle)
168 return index; 152 return index;
169} 153}
170 154
171int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) 155static int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
172{ 156{
173 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); 157 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq);
174 unsigned long flags; 158 unsigned long flags;
@@ -188,7 +172,7 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
188 return 0; 172 return 0;
189} 173}
190 174
191int modify_irte(int irq, struct irte *irte_modified) 175static int modify_irte(int irq, struct irte *irte_modified)
192{ 176{
193 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); 177 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq);
194 struct intel_iommu *iommu; 178 struct intel_iommu *iommu;
@@ -216,7 +200,7 @@ int modify_irte(int irq, struct irte *irte_modified)
216 return rc; 200 return rc;
217} 201}
218 202
219struct intel_iommu *map_hpet_to_ir(u8 hpet_id) 203static struct intel_iommu *map_hpet_to_ir(u8 hpet_id)
220{ 204{
221 int i; 205 int i;
222 206
@@ -226,7 +210,7 @@ struct intel_iommu *map_hpet_to_ir(u8 hpet_id)
226 return NULL; 210 return NULL;
227} 211}
228 212
229struct intel_iommu *map_ioapic_to_ir(int apic) 213static struct intel_iommu *map_ioapic_to_ir(int apic)
230{ 214{
231 int i; 215 int i;
232 216
@@ -236,7 +220,7 @@ struct intel_iommu *map_ioapic_to_ir(int apic)
236 return NULL; 220 return NULL;
237} 221}
238 222
239struct intel_iommu *map_dev_to_ir(struct pci_dev *dev) 223static struct intel_iommu *map_dev_to_ir(struct pci_dev *dev)
240{ 224{
241 struct dmar_drhd_unit *drhd; 225 struct dmar_drhd_unit *drhd;
242 226
@@ -270,7 +254,7 @@ static int clear_entries(struct irq_2_iommu *irq_iommu)
270 return qi_flush_iec(iommu, index, irq_iommu->irte_mask); 254 return qi_flush_iec(iommu, index, irq_iommu->irte_mask);
271} 255}
272 256
273int free_irte(int irq) 257static int free_irte(int irq)
274{ 258{
275 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); 259 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq);
276 unsigned long flags; 260 unsigned long flags;
@@ -328,7 +312,7 @@ static void set_irte_sid(struct irte *irte, unsigned int svt,
328 irte->sid = sid; 312 irte->sid = sid;
329} 313}
330 314
331int set_ioapic_sid(struct irte *irte, int apic) 315static int set_ioapic_sid(struct irte *irte, int apic)
332{ 316{
333 int i; 317 int i;
334 u16 sid = 0; 318 u16 sid = 0;
@@ -353,7 +337,7 @@ int set_ioapic_sid(struct irte *irte, int apic)
353 return 0; 337 return 0;
354} 338}
355 339
356int set_hpet_sid(struct irte *irte, u8 id) 340static int set_hpet_sid(struct irte *irte, u8 id)
357{ 341{
358 int i; 342 int i;
359 u16 sid = 0; 343 u16 sid = 0;
@@ -383,7 +367,7 @@ int set_hpet_sid(struct irte *irte, u8 id)
383 return 0; 367 return 0;
384} 368}
385 369
386int set_msi_sid(struct irte *irte, struct pci_dev *dev) 370static int set_msi_sid(struct irte *irte, struct pci_dev *dev)
387{ 371{
388 struct pci_dev *bridge; 372 struct pci_dev *bridge;
389 373
@@ -410,7 +394,7 @@ int set_msi_sid(struct irte *irte, struct pci_dev *dev)
410 return 0; 394 return 0;
411} 395}
412 396
413static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode) 397static void iommu_set_irq_remapping(struct intel_iommu *iommu, int mode)
414{ 398{
415 u64 addr; 399 u64 addr;
416 u32 sts; 400 u32 sts;
@@ -450,7 +434,7 @@ static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode)
450} 434}
451 435
452 436
453static int setup_intr_remapping(struct intel_iommu *iommu, int mode) 437static int intel_setup_irq_remapping(struct intel_iommu *iommu, int mode)
454{ 438{
455 struct ir_table *ir_table; 439 struct ir_table *ir_table;
456 struct page *pages; 440 struct page *pages;
@@ -473,14 +457,14 @@ static int setup_intr_remapping(struct intel_iommu *iommu, int mode)
473 457
474 ir_table->base = page_address(pages); 458 ir_table->base = page_address(pages);
475 459
476 iommu_set_intr_remapping(iommu, mode); 460 iommu_set_irq_remapping(iommu, mode);
477 return 0; 461 return 0;
478} 462}
479 463
480/* 464/*
481 * Disable Interrupt Remapping. 465 * Disable Interrupt Remapping.
482 */ 466 */
483static void iommu_disable_intr_remapping(struct intel_iommu *iommu) 467static void iommu_disable_irq_remapping(struct intel_iommu *iommu)
484{ 468{
485 unsigned long flags; 469 unsigned long flags;
486 u32 sts; 470 u32 sts;
@@ -519,11 +503,11 @@ static int __init dmar_x2apic_optout(void)
519 return dmar->flags & DMAR_X2APIC_OPT_OUT; 503 return dmar->flags & DMAR_X2APIC_OPT_OUT;
520} 504}
521 505
522int __init intr_remapping_supported(void) 506static int __init intel_irq_remapping_supported(void)
523{ 507{
524 struct dmar_drhd_unit *drhd; 508 struct dmar_drhd_unit *drhd;
525 509
526 if (disable_intremap) 510 if (disable_irq_remap)
527 return 0; 511 return 0;
528 512
529 if (!dmar_ir_support()) 513 if (!dmar_ir_support())
@@ -539,7 +523,7 @@ int __init intr_remapping_supported(void)
539 return 1; 523 return 1;
540} 524}
541 525
542int __init enable_intr_remapping(void) 526static int __init intel_enable_irq_remapping(void)
543{ 527{
544 struct dmar_drhd_unit *drhd; 528 struct dmar_drhd_unit *drhd;
545 int setup = 0; 529 int setup = 0;
@@ -577,7 +561,7 @@ int __init enable_intr_remapping(void)
577 * Disable intr remapping and queued invalidation, if already 561 * Disable intr remapping and queued invalidation, if already
578 * enabled prior to OS handover. 562 * enabled prior to OS handover.
579 */ 563 */
580 iommu_disable_intr_remapping(iommu); 564 iommu_disable_irq_remapping(iommu);
581 565
582 dmar_disable_qi(iommu); 566 dmar_disable_qi(iommu);
583 } 567 }
@@ -623,7 +607,7 @@ int __init enable_intr_remapping(void)
623 if (!ecap_ir_support(iommu->ecap)) 607 if (!ecap_ir_support(iommu->ecap))
624 continue; 608 continue;
625 609
626 if (setup_intr_remapping(iommu, eim)) 610 if (intel_setup_irq_remapping(iommu, eim))
627 goto error; 611 goto error;
628 612
629 setup = 1; 613 setup = 1;
@@ -632,7 +616,7 @@ int __init enable_intr_remapping(void)
632 if (!setup) 616 if (!setup)
633 goto error; 617 goto error;
634 618
635 intr_remapping_enabled = 1; 619 irq_remapping_enabled = 1;
636 pr_info("Enabled IRQ remapping in %s mode\n", eim ? "x2apic" : "xapic"); 620 pr_info("Enabled IRQ remapping in %s mode\n", eim ? "x2apic" : "xapic");
637 621
638 return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE; 622 return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE;
@@ -775,14 +759,14 @@ int __init parse_ioapics_under_ir(void)
775 759
776int __init ir_dev_scope_init(void) 760int __init ir_dev_scope_init(void)
777{ 761{
778 if (!intr_remapping_enabled) 762 if (!irq_remapping_enabled)
779 return 0; 763 return 0;
780 764
781 return dmar_dev_scope_init(); 765 return dmar_dev_scope_init();
782} 766}
783rootfs_initcall(ir_dev_scope_init); 767rootfs_initcall(ir_dev_scope_init);
784 768
785void disable_intr_remapping(void) 769static void disable_irq_remapping(void)
786{ 770{
787 struct dmar_drhd_unit *drhd; 771 struct dmar_drhd_unit *drhd;
788 struct intel_iommu *iommu = NULL; 772 struct intel_iommu *iommu = NULL;
@@ -794,11 +778,11 @@ void disable_intr_remapping(void)
794 if (!ecap_ir_support(iommu->ecap)) 778 if (!ecap_ir_support(iommu->ecap))
795 continue; 779 continue;
796 780
797 iommu_disable_intr_remapping(iommu); 781 iommu_disable_irq_remapping(iommu);
798 } 782 }
799} 783}
800 784
801int reenable_intr_remapping(int eim) 785static int reenable_irq_remapping(int eim)
802{ 786{
803 struct dmar_drhd_unit *drhd; 787 struct dmar_drhd_unit *drhd;
804 int setup = 0; 788 int setup = 0;
@@ -816,7 +800,7 @@ int reenable_intr_remapping(int eim)
816 continue; 800 continue;
817 801
818 /* Set up interrupt remapping for iommu.*/ 802 /* Set up interrupt remapping for iommu.*/
819 iommu_set_intr_remapping(iommu, eim); 803 iommu_set_irq_remapping(iommu, eim);
820 setup = 1; 804 setup = 1;
821 } 805 }
822 806
@@ -832,3 +816,254 @@ error:
832 return -1; 816 return -1;
833} 817}
834 818
819static void prepare_irte(struct irte *irte, int vector,
820 unsigned int dest)
821{
822 memset(irte, 0, sizeof(*irte));
823
824 irte->present = 1;
825 irte->dst_mode = apic->irq_dest_mode;
826 /*
827 * Trigger mode in the IRTE will always be edge, and for IO-APIC, the
828 * actual level or edge trigger will be setup in the IO-APIC
829 * RTE. This will help simplify level triggered irq migration.
830 * For more details, see the comments (in io_apic.c) explainig IO-APIC
831 * irq migration in the presence of interrupt-remapping.
832 */
833 irte->trigger_mode = 0;
834 irte->dlvry_mode = apic->irq_delivery_mode;
835 irte->vector = vector;
836 irte->dest_id = IRTE_DEST(dest);
837 irte->redir_hint = 1;
838}
839
840static int intel_setup_ioapic_entry(int irq,
841 struct IO_APIC_route_entry *route_entry,
842 unsigned int destination, int vector,
843 struct io_apic_irq_attr *attr)
844{
845 int ioapic_id = mpc_ioapic_id(attr->ioapic);
846 struct intel_iommu *iommu = map_ioapic_to_ir(ioapic_id);
847 struct IR_IO_APIC_route_entry *entry;
848 struct irte irte;
849 int index;
850
851 if (!iommu) {
852 pr_warn("No mapping iommu for ioapic %d\n", ioapic_id);
853 return -ENODEV;
854 }
855
856 entry = (struct IR_IO_APIC_route_entry *)route_entry;
857
858 index = alloc_irte(iommu, irq, 1);
859 if (index < 0) {
860 pr_warn("Failed to allocate IRTE for ioapic %d\n", ioapic_id);
861 return -ENOMEM;
862 }
863
864 prepare_irte(&irte, vector, destination);
865
866 /* Set source-id of interrupt request */
867 set_ioapic_sid(&irte, ioapic_id);
868
869 modify_irte(irq, &irte);
870
871 apic_printk(APIC_VERBOSE, KERN_DEBUG "IOAPIC[%d]: "
872 "Set IRTE entry (P:%d FPD:%d Dst_Mode:%d "
873 "Redir_hint:%d Trig_Mode:%d Dlvry_Mode:%X "
874 "Avail:%X Vector:%02X Dest:%08X "
875 "SID:%04X SQ:%X SVT:%X)\n",
876 attr->ioapic, irte.present, irte.fpd, irte.dst_mode,
877 irte.redir_hint, irte.trigger_mode, irte.dlvry_mode,
878 irte.avail, irte.vector, irte.dest_id,
879 irte.sid, irte.sq, irte.svt);
880
881 memset(entry, 0, sizeof(*entry));
882
883 entry->index2 = (index >> 15) & 0x1;
884 entry->zero = 0;
885 entry->format = 1;
886 entry->index = (index & 0x7fff);
887 /*
888 * IO-APIC RTE will be configured with virtual vector.
889 * irq handler will do the explicit EOI to the io-apic.
890 */
891 entry->vector = attr->ioapic_pin;
892 entry->mask = 0; /* enable IRQ */
893 entry->trigger = attr->trigger;
894 entry->polarity = attr->polarity;
895
896 /* Mask level triggered irqs.
897 * Use IRQ_DELAYED_DISABLE for edge triggered irqs.
898 */
899 if (attr->trigger)
900 entry->mask = 1;
901
902 return 0;
903}
904
905#ifdef CONFIG_SMP
906/*
907 * Migrate the IO-APIC irq in the presence of intr-remapping.
908 *
909 * For both level and edge triggered, irq migration is a simple atomic
910 * update(of vector and cpu destination) of IRTE and flush the hardware cache.
911 *
912 * For level triggered, we eliminate the io-apic RTE modification (with the
913 * updated vector information), by using a virtual vector (io-apic pin number).
914 * Real vector that is used for interrupting cpu will be coming from
915 * the interrupt-remapping table entry.
916 *
917 * As the migration is a simple atomic update of IRTE, the same mechanism
918 * is used to migrate MSI irq's in the presence of interrupt-remapping.
919 */
920static int
921intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
922 bool force)
923{
924 struct irq_cfg *cfg = data->chip_data;
925 unsigned int dest, irq = data->irq;
926 struct irte irte;
927
928 if (!cpumask_intersects(mask, cpu_online_mask))
929 return -EINVAL;
930
931 if (get_irte(irq, &irte))
932 return -EBUSY;
933
934 if (assign_irq_vector(irq, cfg, mask))
935 return -EBUSY;
936
937 dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask);
938
939 irte.vector = cfg->vector;
940 irte.dest_id = IRTE_DEST(dest);
941
942 /*
943 * Atomically updates the IRTE with the new destination, vector
944 * and flushes the interrupt entry cache.
945 */
946 modify_irte(irq, &irte);
947
948 /*
949 * After this point, all the interrupts will start arriving
950 * at the new destination. So, time to cleanup the previous
951 * vector allocation.
952 */
953 if (cfg->move_in_progress)
954 send_cleanup_vector(cfg);
955
956 cpumask_copy(data->affinity, mask);
957 return 0;
958}
959#endif
960
961static void intel_compose_msi_msg(struct pci_dev *pdev,
962 unsigned int irq, unsigned int dest,
963 struct msi_msg *msg, u8 hpet_id)
964{
965 struct irq_cfg *cfg;
966 struct irte irte;
967 u16 sub_handle = 0;
968 int ir_index;
969
970 cfg = irq_get_chip_data(irq);
971
972 ir_index = map_irq_to_irte_handle(irq, &sub_handle);
973 BUG_ON(ir_index == -1);
974
975 prepare_irte(&irte, cfg->vector, dest);
976
977 /* Set source-id of interrupt request */
978 if (pdev)
979 set_msi_sid(&irte, pdev);
980 else
981 set_hpet_sid(&irte, hpet_id);
982
983 modify_irte(irq, &irte);
984
985 msg->address_hi = MSI_ADDR_BASE_HI;
986 msg->data = sub_handle;
987 msg->address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_IR_EXT_INT |
988 MSI_ADDR_IR_SHV |
989 MSI_ADDR_IR_INDEX1(ir_index) |
990 MSI_ADDR_IR_INDEX2(ir_index);
991}
992
993/*
994 * Map the PCI dev to the corresponding remapping hardware unit
995 * and allocate 'nvec' consecutive interrupt-remapping table entries
996 * in it.
997 */
998static int intel_msi_alloc_irq(struct pci_dev *dev, int irq, int nvec)
999{
1000 struct intel_iommu *iommu;
1001 int index;
1002
1003 iommu = map_dev_to_ir(dev);
1004 if (!iommu) {
1005 printk(KERN_ERR
1006 "Unable to map PCI %s to iommu\n", pci_name(dev));
1007 return -ENOENT;
1008 }
1009
1010 index = alloc_irte(iommu, irq, nvec);
1011 if (index < 0) {
1012 printk(KERN_ERR
1013 "Unable to allocate %d IRTE for PCI %s\n", nvec,
1014 pci_name(dev));
1015 return -ENOSPC;
1016 }
1017 return index;
1018}
1019
1020static int intel_msi_setup_irq(struct pci_dev *pdev, unsigned int irq,
1021 int index, int sub_handle)
1022{
1023 struct intel_iommu *iommu;
1024
1025 iommu = map_dev_to_ir(pdev);
1026 if (!iommu)
1027 return -ENOENT;
1028 /*
1029 * setup the mapping between the irq and the IRTE
1030 * base index, the sub_handle pointing to the
1031 * appropriate interrupt remap table entry.
1032 */
1033 set_irte_irq(irq, iommu, index, sub_handle);
1034
1035 return 0;
1036}
1037
1038static int intel_setup_hpet_msi(unsigned int irq, unsigned int id)
1039{
1040 struct intel_iommu *iommu = map_hpet_to_ir(id);
1041 int index;
1042
1043 if (!iommu)
1044 return -1;
1045
1046 index = alloc_irte(iommu, irq, 1);
1047 if (index < 0)
1048 return -1;
1049
1050 return 0;
1051}
1052
1053struct irq_remap_ops intel_irq_remap_ops = {
1054 .supported = intel_irq_remapping_supported,
1055 .prepare = dmar_table_init,
1056 .enable = intel_enable_irq_remapping,
1057 .disable = disable_irq_remapping,
1058 .reenable = reenable_irq_remapping,
1059 .enable_faulting = enable_drhd_fault_handling,
1060 .setup_ioapic_entry = intel_setup_ioapic_entry,
1061#ifdef CONFIG_SMP
1062 .set_affinity = intel_ioapic_set_affinity,
1063#endif
1064 .free_irq = free_irte,
1065 .compose_msi_msg = intel_compose_msi_msg,
1066 .msi_alloc_irq = intel_msi_alloc_irq,
1067 .msi_setup_irq = intel_msi_setup_irq,
1068 .setup_hpet_msi = intel_setup_hpet_msi,
1069};
diff --git a/drivers/iommu/intr_remapping.h b/drivers/iommu/intr_remapping.h
deleted file mode 100644
index 5662fecfee60..000000000000
--- a/drivers/iommu/intr_remapping.h
+++ /dev/null
@@ -1,17 +0,0 @@
1#include <linux/intel-iommu.h>
2
3struct ioapic_scope {
4 struct intel_iommu *iommu;
5 unsigned int id;
6 unsigned int bus; /* PCI bus number */
7 unsigned int devfn; /* PCI devfn number */
8};
9
10struct hpet_scope {
11 struct intel_iommu *iommu;
12 u8 id;
13 unsigned int bus;
14 unsigned int devfn;
15};
16
17#define IR_X2APIC_MODE(mode) (mode ? (1 << 11) : 0)
diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
new file mode 100644
index 000000000000..40cda8e98d87
--- /dev/null
+++ b/drivers/iommu/irq_remapping.c
@@ -0,0 +1,166 @@
1#include <linux/kernel.h>
2#include <linux/string.h>
3#include <linux/errno.h>
4
5#include "irq_remapping.h"
6
7int irq_remapping_enabled;
8
9int disable_irq_remap;
10int disable_sourceid_checking;
11int no_x2apic_optout;
12
13static struct irq_remap_ops *remap_ops;
14
15static __init int setup_nointremap(char *str)
16{
17 disable_irq_remap = 1;
18 return 0;
19}
20early_param("nointremap", setup_nointremap);
21
22static __init int setup_irqremap(char *str)
23{
24 if (!str)
25 return -EINVAL;
26
27 while (*str) {
28 if (!strncmp(str, "on", 2))
29 disable_irq_remap = 0;
30 else if (!strncmp(str, "off", 3))
31 disable_irq_remap = 1;
32 else if (!strncmp(str, "nosid", 5))
33 disable_sourceid_checking = 1;
34 else if (!strncmp(str, "no_x2apic_optout", 16))
35 no_x2apic_optout = 1;
36
37 str += strcspn(str, ",");
38 while (*str == ',')
39 str++;
40 }
41
42 return 0;
43}
44early_param("intremap", setup_irqremap);
45
46void __init setup_irq_remapping_ops(void)
47{
48 remap_ops = &intel_irq_remap_ops;
49}
50
51int irq_remapping_supported(void)
52{
53 if (disable_irq_remap)
54 return 0;
55
56 if (!remap_ops || !remap_ops->supported)
57 return 0;
58
59 return remap_ops->supported();
60}
61
62int __init irq_remapping_prepare(void)
63{
64 if (!remap_ops || !remap_ops->prepare)
65 return -ENODEV;
66
67 return remap_ops->prepare();
68}
69
70int __init irq_remapping_enable(void)
71{
72 if (!remap_ops || !remap_ops->enable)
73 return -ENODEV;
74
75 return remap_ops->enable();
76}
77
78void irq_remapping_disable(void)
79{
80 if (!remap_ops || !remap_ops->disable)
81 return;
82
83 remap_ops->disable();
84}
85
86int irq_remapping_reenable(int mode)
87{
88 if (!remap_ops || !remap_ops->reenable)
89 return 0;
90
91 return remap_ops->reenable(mode);
92}
93
94int __init irq_remap_enable_fault_handling(void)
95{
96 if (!remap_ops || !remap_ops->enable_faulting)
97 return -ENODEV;
98
99 return remap_ops->enable_faulting();
100}
101
102int setup_ioapic_remapped_entry(int irq,
103 struct IO_APIC_route_entry *entry,
104 unsigned int destination, int vector,
105 struct io_apic_irq_attr *attr)
106{
107 if (!remap_ops || !remap_ops->setup_ioapic_entry)
108 return -ENODEV;
109
110 return remap_ops->setup_ioapic_entry(irq, entry, destination,
111 vector, attr);
112}
113
114#ifdef CONFIG_SMP
115int set_remapped_irq_affinity(struct irq_data *data, const struct cpumask *mask,
116 bool force)
117{
118 if (!remap_ops || !remap_ops->set_affinity)
119 return 0;
120
121 return remap_ops->set_affinity(data, mask, force);
122}
123#endif
124
125void free_remapped_irq(int irq)
126{
127 if (!remap_ops || !remap_ops->free_irq)
128 return;
129
130 remap_ops->free_irq(irq);
131}
132
133void compose_remapped_msi_msg(struct pci_dev *pdev,
134 unsigned int irq, unsigned int dest,
135 struct msi_msg *msg, u8 hpet_id)
136{
137 if (!remap_ops || !remap_ops->compose_msi_msg)
138 return;
139
140 remap_ops->compose_msi_msg(pdev, irq, dest, msg, hpet_id);
141}
142
143int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec)
144{
145 if (!remap_ops || !remap_ops->msi_alloc_irq)
146 return -ENODEV;
147
148 return remap_ops->msi_alloc_irq(pdev, irq, nvec);
149}
150
151int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq,
152 int index, int sub_handle)
153{
154 if (!remap_ops || !remap_ops->msi_setup_irq)
155 return -ENODEV;
156
157 return remap_ops->msi_setup_irq(pdev, irq, index, sub_handle);
158}
159
160int setup_hpet_msi_remapped(unsigned int irq, unsigned int id)
161{
162 if (!remap_ops || !remap_ops->setup_hpet_msi)
163 return -ENODEV;
164
165 return remap_ops->setup_hpet_msi(irq, id);
166}
diff --git a/drivers/iommu/irq_remapping.h b/drivers/iommu/irq_remapping.h
new file mode 100644
index 000000000000..be9d72950c51
--- /dev/null
+++ b/drivers/iommu/irq_remapping.h
@@ -0,0 +1,90 @@
1/*
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 stuff that is shared between different interrupt
19 * remapping drivers but with no need to be visible outside of the IOMMU layer.
20 */
21
22#ifndef __IRQ_REMAPPING_H
23#define __IRQ_REMAPPING_H
24
25#ifdef CONFIG_IRQ_REMAP
26
27struct IO_APIC_route_entry;
28struct io_apic_irq_attr;
29struct irq_data;
30struct cpumask;
31struct pci_dev;
32struct msi_msg;
33
34extern int disable_irq_remap;
35extern int disable_sourceid_checking;
36extern int no_x2apic_optout;
37
38struct irq_remap_ops {
39 /* Check whether Interrupt Remapping is supported */
40 int (*supported)(void);
41
42 /* Initializes hardware and makes it ready for remapping interrupts */
43 int (*prepare)(void);
44
45 /* Enables the remapping hardware */
46 int (*enable)(void);
47
48 /* Disables the remapping hardware */
49 void (*disable)(void);
50
51 /* Reenables the remapping hardware */
52 int (*reenable)(int);
53
54 /* Enable fault handling */
55 int (*enable_faulting)(void);
56
57 /* IO-APIC setup routine */
58 int (*setup_ioapic_entry)(int irq, struct IO_APIC_route_entry *,
59 unsigned int, int,
60 struct io_apic_irq_attr *);
61
62#ifdef CONFIG_SMP
63 /* Set the CPU affinity of a remapped interrupt */
64 int (*set_affinity)(struct irq_data *data, const struct cpumask *mask,
65 bool force);
66#endif
67
68 /* Free an IRQ */
69 int (*free_irq)(int);
70
71 /* Create MSI msg to use for interrupt remapping */
72 void (*compose_msi_msg)(struct pci_dev *,
73 unsigned int, unsigned int,
74 struct msi_msg *, u8);
75
76 /* Allocate remapping resources for MSI */
77 int (*msi_alloc_irq)(struct pci_dev *, int, int);
78
79 /* Setup the remapped MSI irq */
80 int (*msi_setup_irq)(struct pci_dev *, unsigned int, int, int);
81
82 /* Setup interrupt remapping for an HPET MSI */
83 int (*setup_hpet_msi)(unsigned int, unsigned int);
84};
85
86extern struct irq_remap_ops intel_irq_remap_ops;
87
88#endif /* CONFIG_IRQ_REMAP */
89
90#endif /* __IRQ_REMAPPING_H */
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index 731a60975101..b029d1aa2d12 100644
--- a/include/linux/dmar.h
+++ b/include/linux/dmar.h
@@ -114,91 +114,6 @@ struct irte {
114 }; 114 };
115}; 115};
116 116
117#ifdef CONFIG_IRQ_REMAP
118extern int intr_remapping_enabled;
119extern int intr_remapping_supported(void);
120extern int enable_intr_remapping(void);
121extern void disable_intr_remapping(void);
122extern int reenable_intr_remapping(int);
123
124extern int get_irte(int irq, struct irte *entry);
125extern int modify_irte(int irq, struct irte *irte_modified);
126extern int alloc_irte(struct intel_iommu *iommu, int irq, u16 count);
127extern int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index,
128 u16 sub_handle);
129extern int map_irq_to_irte_handle(int irq, u16 *sub_handle);
130extern int free_irte(int irq);
131
132extern struct intel_iommu *map_dev_to_ir(struct pci_dev *dev);
133extern struct intel_iommu *map_ioapic_to_ir(int apic);
134extern struct intel_iommu *map_hpet_to_ir(u8 id);
135extern int set_ioapic_sid(struct irte *irte, int apic);
136extern int set_hpet_sid(struct irte *irte, u8 id);
137extern int set_msi_sid(struct irte *irte, struct pci_dev *dev);
138#else
139static inline int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
140{
141 return -1;
142}
143static inline int modify_irte(int irq, struct irte *irte_modified)
144{
145 return -1;
146}
147static inline int free_irte(int irq)
148{
149 return -1;
150}
151static inline int map_irq_to_irte_handle(int irq, u16 *sub_handle)
152{
153 return -1;
154}
155static inline int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index,
156 u16 sub_handle)
157{
158 return -1;
159}
160static inline struct intel_iommu *map_dev_to_ir(struct pci_dev *dev)
161{
162 return NULL;
163}
164static inline struct intel_iommu *map_ioapic_to_ir(int apic)
165{
166 return NULL;
167}
168static inline struct intel_iommu *map_hpet_to_ir(unsigned int hpet_id)
169{
170 return NULL;
171}
172static inline int set_ioapic_sid(struct irte *irte, int apic)
173{
174 return 0;
175}
176static inline int set_hpet_sid(struct irte *irte, u8 id)
177{
178 return -1;
179}
180static inline int set_msi_sid(struct irte *irte, struct pci_dev *dev)
181{
182 return 0;
183}
184
185#define intr_remapping_enabled (0)
186
187static inline int enable_intr_remapping(void)
188{
189 return -1;
190}
191
192static inline void disable_intr_remapping(void)
193{
194}
195
196static inline int reenable_intr_remapping(int eim)
197{
198 return 0;
199}
200#endif
201
202enum { 117enum {
203 IRQ_REMAP_XAPIC_MODE, 118 IRQ_REMAP_XAPIC_MODE,
204 IRQ_REMAP_X2APIC_MODE, 119 IRQ_REMAP_X2APIC_MODE,