aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ia64/include/asm/intr_remapping.h4
-rw-r--r--arch/x86/include/asm/intr_remapping.h45
-rw-r--r--arch/x86/kernel/apic/apic.c14
-rw-r--r--arch/x86/kernel/apic/io_apic.c1
-rw-r--r--drivers/iommu/Makefile2
-rw-r--r--drivers/iommu/dmar.c1
-rw-r--r--drivers/iommu/intel-iommu.c1
-rw-r--r--drivers/iommu/intel_intr_remapping.c52
-rw-r--r--drivers/iommu/intr_remapping.c76
-rw-r--r--drivers/iommu/intr_remapping.h46
-rw-r--r--include/linux/dmar.h3
11 files changed, 196 insertions, 49 deletions
diff --git a/arch/ia64/include/asm/intr_remapping.h b/arch/ia64/include/asm/intr_remapping.h
new file mode 100644
index 000000000000..095aa0d46c58
--- /dev/null
+++ b/arch/ia64/include/asm/intr_remapping.h
@@ -0,0 +1,4 @@
1#ifndef __IA64_INTR_REMAPPING_H
2#define __IA64_INTR_REMAPPING_H
3#define intr_remapping_enabled 0
4#endif
diff --git a/arch/x86/include/asm/intr_remapping.h b/arch/x86/include/asm/intr_remapping.h
new file mode 100644
index 000000000000..207c605dbdf5
--- /dev/null
+++ b/arch/x86/include/asm/intr_remapping.h
@@ -0,0 +1,45 @@
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 the interface of the interrupt remapping code to
19 * the x86 interrupt management code.
20 */
21
22#ifndef __X86_INTR_REMAPPING_H
23#define __X86_INTR_REMAPPING_H
24
25#ifdef CONFIG_IRQ_REMAP
26
27extern int intr_remapping_enabled;
28
29extern void setup_intr_remapping(void);
30extern int intr_remapping_supported(void);
31extern int intr_hardware_init(void);
32extern int intr_hardware_enable(void);
33
34#else /* CONFIG_IRQ_REMAP */
35
36#define intr_remapping_enabled 0
37
38static inline void setup_intr_remapping(void) { }
39static inline int intr_remapping_supported(void) { return 0; }
40static inline int intr_hardware_init(void) { return -ENODEV; }
41static inline int intr_hardware_enable(void) { return -ENODEV; }
42
43#endif /* CONFIG_IRQ_REMAP */
44
45#endif /* __X86_INTR_REMAPPING_H */
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index edc24480469f..1db6f63a22ff 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/intr_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>
@@ -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 intr_hardware_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_intr_remapping();
1545
1546 hardware_init_ret = intr_hardware_init();
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();
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index e88300d8e80a..1151fdccaad6 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -57,6 +57,7 @@
57#include <asm/msidef.h> 57#include <asm/msidef.h>
58#include <asm/hypertransport.h> 58#include <asm/hypertransport.h>
59#include <asm/setup.h> 59#include <asm/setup.h>
60#include <asm/intr_remapping.h>
60#include <asm/irq_remapping.h> 61#include <asm/irq_remapping.h>
61#include <asm/hpet.h> 62#include <asm/hpet.h>
62#include <asm/hw_irq.h> 63#include <asm/hw_irq.h>
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 1533ebf1d68e..823e1cf8708f 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) += intel_intr_remapping.o 7obj-$(CONFIG_IRQ_REMAP) += intel_intr_remapping.o intr_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..647e366403dc 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/intr_remapping.h>
39#include <asm/iommu_table.h> 40#include <asm/iommu_table.h>
40 41
41#define PREFIX "DMAR: " 42#define PREFIX "DMAR: "
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index f93d5ac8f81c..e1439808192c 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/intr_remapping.h>
45#include <asm/cacheflush.h> 46#include <asm/cacheflush.h>
46#include <asm/iommu.h> 47#include <asm/iommu.h>
47 48
diff --git a/drivers/iommu/intel_intr_remapping.c b/drivers/iommu/intel_intr_remapping.c
index 212fff0c24b5..9c742fb111b6 100644
--- a/drivers/iommu/intel_intr_remapping.c
+++ b/drivers/iommu/intel_intr_remapping.c
@@ -11,8 +11,11 @@
11#include <asm/cpu.h> 11#include <asm/cpu.h>
12#include <linux/intel-iommu.h> 12#include <linux/intel-iommu.h>
13#include <acpi/acpi.h> 13#include <acpi/acpi.h>
14#include <asm/intr_remapping.h>
14#include <asm/pci-direct.h> 15#include <asm/pci-direct.h>
15 16
17#include "intr_remapping.h"
18
16struct ioapic_scope { 19struct ioapic_scope {
17 struct intel_iommu *iommu; 20 struct intel_iommu *iommu;
18 unsigned int id; 21 unsigned int id;
@@ -32,42 +35,6 @@ struct hpet_scope {
32static struct ioapic_scope ir_ioapic[MAX_IO_APICS]; 35static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
33static struct hpet_scope ir_hpet[MAX_HPET_TBS]; 36static struct hpet_scope ir_hpet[MAX_HPET_TBS];
34static int ir_ioapic_num, ir_hpet_num; 37static int ir_ioapic_num, ir_hpet_num;
35int intr_remapping_enabled;
36
37static int disable_intremap;
38static int disable_sourceid_checking;
39static int no_x2apic_optout;
40
41static __init int setup_nointremap(char *str)
42{
43 disable_intremap = 1;
44 return 0;
45}
46early_param("nointremap", setup_nointremap);
47
48static __init int setup_intremap(char *str)
49{
50 if (!str)
51 return -EINVAL;
52
53 while (*str) {
54 if (!strncmp(str, "on", 2))
55 disable_intremap = 0;
56 else if (!strncmp(str, "off", 3))
57 disable_intremap = 1;
58 else if (!strncmp(str, "nosid", 5))
59 disable_sourceid_checking = 1;
60 else if (!strncmp(str, "no_x2apic_optout", 16))
61 no_x2apic_optout = 1;
62
63 str += strcspn(str, ",");
64 while (*str == ',')
65 str++;
66 }
67
68 return 0;
69}
70early_param("intremap", setup_intremap);
71 38
72static DEFINE_RAW_SPINLOCK(irq_2_ir_lock); 39static DEFINE_RAW_SPINLOCK(irq_2_ir_lock);
73 40
@@ -465,7 +432,7 @@ static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode)
465} 432}
466 433
467 434
468static int setup_intr_remapping(struct intel_iommu *iommu, int mode) 435static int intel_setup_intr_remapping(struct intel_iommu *iommu, int mode)
469{ 436{
470 struct ir_table *ir_table; 437 struct ir_table *ir_table;
471 struct page *pages; 438 struct page *pages;
@@ -534,7 +501,7 @@ static int __init dmar_x2apic_optout(void)
534 return dmar->flags & DMAR_X2APIC_OPT_OUT; 501 return dmar->flags & DMAR_X2APIC_OPT_OUT;
535} 502}
536 503
537int __init intr_remapping_supported(void) 504static int __init intel_intr_remapping_supported(void)
538{ 505{
539 struct dmar_drhd_unit *drhd; 506 struct dmar_drhd_unit *drhd;
540 507
@@ -554,7 +521,7 @@ int __init intr_remapping_supported(void)
554 return 1; 521 return 1;
555} 522}
556 523
557int __init enable_intr_remapping(void) 524static int __init intel_enable_intr_remapping(void)
558{ 525{
559 struct dmar_drhd_unit *drhd; 526 struct dmar_drhd_unit *drhd;
560 int setup = 0; 527 int setup = 0;
@@ -638,7 +605,7 @@ int __init enable_intr_remapping(void)
638 if (!ecap_ir_support(iommu->ecap)) 605 if (!ecap_ir_support(iommu->ecap))
639 continue; 606 continue;
640 607
641 if (setup_intr_remapping(iommu, eim)) 608 if (intel_setup_intr_remapping(iommu, eim))
642 goto error; 609 goto error;
643 610
644 setup = 1; 611 setup = 1;
@@ -847,3 +814,8 @@ error:
847 return -1; 814 return -1;
848} 815}
849 816
817struct irq_remap_ops intel_irq_remap_ops = {
818 .supported = intel_intr_remapping_supported,
819 .hardware_init = dmar_table_init,
820 .hardware_enable = intel_enable_intr_remapping,
821};
diff --git a/drivers/iommu/intr_remapping.c b/drivers/iommu/intr_remapping.c
new file mode 100644
index 000000000000..670c69a80afd
--- /dev/null
+++ b/drivers/iommu/intr_remapping.c
@@ -0,0 +1,76 @@
1#include <linux/kernel.h>
2#include <linux/string.h>
3#include <linux/errno.h>
4
5#include "intr_remapping.h"
6
7int intr_remapping_enabled;
8
9int disable_intremap;
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_intremap = 1;
18 return 0;
19}
20early_param("nointremap", setup_nointremap);
21
22static __init int setup_intremap(char *str)
23{
24 if (!str)
25 return -EINVAL;
26
27 while (*str) {
28 if (!strncmp(str, "on", 2))
29 disable_intremap = 0;
30 else if (!strncmp(str, "off", 3))
31 disable_intremap = 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_intremap);
45
46void __init setup_intr_remapping(void)
47{
48 remap_ops = &intel_irq_remap_ops;
49}
50
51int intr_remapping_supported(void)
52{
53 if (disable_intremap)
54 return 0;
55
56 if (!remap_ops || !remap_ops->supported)
57 return 0;
58
59 return remap_ops->supported();
60}
61
62int __init intr_hardware_init(void)
63{
64 if (!remap_ops || !remap_ops->hardware_init)
65 return -ENODEV;
66
67 return remap_ops->hardware_init();
68}
69
70int __init intr_hardware_enable(void)
71{
72 if (!remap_ops || !remap_ops->hardware_enable)
73 return -ENODEV;
74
75 return remap_ops->hardware_enable();
76}
diff --git a/drivers/iommu/intr_remapping.h b/drivers/iommu/intr_remapping.h
new file mode 100644
index 000000000000..d6df732e001f
--- /dev/null
+++ b/drivers/iommu/intr_remapping.h
@@ -0,0 +1,46 @@
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 __INTR_REMAPPING_H
23#define __INTR_REMAPPING_H
24
25#ifdef CONFIG_IRQ_REMAP
26
27extern int disable_intremap;
28extern int disable_sourceid_checking;
29extern int no_x2apic_optout;
30
31struct irq_remap_ops {
32 /* Check whether Interrupt Remapping is supported */
33 int (*supported)(void);
34
35 /* Initializes hardware and makes it ready for remapping interrupts */
36 int (*hardware_init)(void);
37
38 /* Enables the remapping hardware */
39 int (*hardware_enable)(void);
40};
41
42extern struct irq_remap_ops intel_irq_remap_ops;
43
44#endif /* CONFIG_IRQ_REMAP */
45
46#endif /* __INTR_REMAPPING_H */
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index 731a60975101..6d66c9c76e0a 100644
--- a/include/linux/dmar.h
+++ b/include/linux/dmar.h
@@ -115,9 +115,6 @@ struct irte {
115}; 115};
116 116
117#ifdef CONFIG_IRQ_REMAP 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); 118extern void disable_intr_remapping(void);
122extern int reenable_intr_remapping(int); 119extern int reenable_intr_remapping(int);
123 120