aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/hw_irq.h1
-rw-r--r--arch/x86/include/asm/io_apic.h5
-rw-r--r--arch/x86/include/asm/irq_remapping.h17
-rw-r--r--arch/x86/kernel/apic/io_apic.c44
-rw-r--r--drivers/iommu/amd_iommu.c8
-rw-r--r--drivers/iommu/intel_irq_remapping.c4
-rw-r--r--drivers/iommu/irq_remapping.c25
7 files changed, 57 insertions, 47 deletions
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index fc89a2a9b04a..10a78c3d3d5a 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -127,6 +127,7 @@ struct irq_cfg {
127 u8 vector; 127 u8 vector;
128 u8 move_in_progress : 1; 128 u8 move_in_progress : 1;
129#ifdef CONFIG_IRQ_REMAP 129#ifdef CONFIG_IRQ_REMAP
130 u8 remapped : 1;
130 union { 131 union {
131 struct irq_2_iommu irq_2_iommu; 132 struct irq_2_iommu irq_2_iommu;
132 struct irq_2_irte irq_2_irte; 133 struct irq_2_irte irq_2_irte;
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 71f5f0865e7c..36fb5abd3725 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -144,6 +144,7 @@ extern int timer_through_8259;
144 (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs) 144 (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs)
145 145
146struct io_apic_irq_attr; 146struct io_apic_irq_attr;
147struct irq_cfg;
147extern int io_apic_set_pci_routing(struct device *dev, int irq, 148extern int io_apic_set_pci_routing(struct device *dev, int irq,
148 struct io_apic_irq_attr *irq_attr); 149 struct io_apic_irq_attr *irq_attr);
149void setup_IO_APIC_irq_extra(u32 gsi); 150void setup_IO_APIC_irq_extra(u32 gsi);
@@ -152,6 +153,10 @@ extern void ioapic_insert_resources(void);
152extern int native_setup_ioapic_entry(int, struct IO_APIC_route_entry *, 153extern int native_setup_ioapic_entry(int, struct IO_APIC_route_entry *,
153 unsigned int, int, 154 unsigned int, int,
154 struct io_apic_irq_attr *); 155 struct io_apic_irq_attr *);
156extern int native_setup_ioapic_entry(int, struct IO_APIC_route_entry *,
157 unsigned int, int,
158 struct io_apic_irq_attr *);
159extern void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg);
155 160
156int io_apic_setup_irq_pin_once(unsigned int irq, int node, struct io_apic_irq_attr *attr); 161int io_apic_setup_irq_pin_once(unsigned int irq, int node, struct io_apic_irq_attr *attr);
157 162
diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h
index 6f4b48ba7a5c..562db68906f8 100644
--- a/arch/x86/include/asm/irq_remapping.h
+++ b/arch/x86/include/asm/irq_remapping.h
@@ -45,6 +45,13 @@ extern void compose_remapped_msi_msg(struct pci_dev *pdev,
45extern int setup_hpet_msi_remapped(unsigned int irq, unsigned int id); 45extern int setup_hpet_msi_remapped(unsigned int irq, unsigned int id);
46extern void panic_if_irq_remap(const char *msg); 46extern void panic_if_irq_remap(const char *msg);
47 47
48static inline bool irq_remapped(struct irq_cfg *cfg)
49{
50 return (cfg->remapped == 1);
51}
52
53void irq_remap_modify_chip_defaults(struct irq_chip *chip);
54
48#else /* CONFIG_IRQ_REMAP */ 55#else /* CONFIG_IRQ_REMAP */
49 56
50static inline void setup_irq_remapping_ops(void) { } 57static inline void setup_irq_remapping_ops(void) { }
@@ -76,6 +83,16 @@ static inline int setup_hpet_msi_remapped(unsigned int irq, unsigned int id)
76static inline void panic_if_irq_remap(const char *msg) 83static inline void panic_if_irq_remap(const char *msg)
77{ 84{
78} 85}
86
87static inline bool irq_remapped(struct irq_cfg *cfg)
88{
89 return false;
90}
91
92static inline void irq_remap_modify_chip_defaults(struct irq_chip *chip)
93{
94}
95
79#endif /* CONFIG_IRQ_REMAP */ 96#endif /* CONFIG_IRQ_REMAP */
80 97
81#endif /* __X86_IRQ_REMAPPING_H */ 98#endif /* __X86_IRQ_REMAPPING_H */
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index ee0757db34ec..0fd5f30bac7f 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -68,22 +68,6 @@
68#define for_each_irq_pin(entry, head) \ 68#define for_each_irq_pin(entry, head) \
69 for (entry = head; entry; entry = entry->next) 69 for (entry = head; entry; entry = entry->next)
70 70
71#ifdef CONFIG_IRQ_REMAP
72static void irq_remap_modify_chip_defaults(struct irq_chip *chip);
73static inline bool irq_remapped(struct irq_cfg *cfg)
74{
75 return cfg->irq_2_iommu.iommu != NULL;
76}
77#else
78static inline bool irq_remapped(struct irq_cfg *cfg)
79{
80 return false;
81}
82static inline void irq_remap_modify_chip_defaults(struct irq_chip *chip)
83{
84}
85#endif
86
87/* 71/*
88 * Is the SiS APIC rmw bug present ? 72 * Is the SiS APIC rmw bug present ?
89 * -1 = don't know, 0 = no, 1 = yes 73 * -1 = don't know, 0 = no, 1 = yes
@@ -606,7 +590,7 @@ static void __eoi_ioapic_pin(int apic, int pin, int vector, struct irq_cfg *cfg)
606 } 590 }
607} 591}
608 592
609static void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) 593void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
610{ 594{
611 struct irq_pin_list *entry; 595 struct irq_pin_list *entry;
612 unsigned long flags; 596 unsigned long flags;
@@ -2542,32 +2526,6 @@ static void ack_apic_level(struct irq_data *data)
2542 ioapic_irqd_unmask(data, cfg, masked); 2526 ioapic_irqd_unmask(data, cfg, masked);
2543} 2527}
2544 2528
2545#ifdef CONFIG_IRQ_REMAP
2546static void ir_ack_apic_edge(struct irq_data *data)
2547{
2548 ack_APIC_irq();
2549}
2550
2551static void ir_ack_apic_level(struct irq_data *data)
2552{
2553 ack_APIC_irq();
2554 eoi_ioapic_irq(data->irq, data->chip_data);
2555}
2556
2557static void ir_print_prefix(struct irq_data *data, struct seq_file *p)
2558{
2559 seq_printf(p, " IR-%s", data->chip->name);
2560}
2561
2562static void irq_remap_modify_chip_defaults(struct irq_chip *chip)
2563{
2564 chip->irq_print_chip = ir_print_prefix;
2565 chip->irq_ack = ir_ack_apic_edge;
2566 chip->irq_eoi = ir_ack_apic_level;
2567 chip->irq_set_affinity = x86_io_apic_ops.set_affinity;
2568}
2569#endif /* CONFIG_IRQ_REMAP */
2570
2571static struct irq_chip ioapic_chip __read_mostly = { 2529static struct irq_chip ioapic_chip __read_mostly = {
2572 .name = "IO-APIC", 2530 .name = "IO-APIC",
2573 .irq_startup = startup_ioapic_irq, 2531 .irq_startup = startup_ioapic_irq,
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index c1c74e030a58..d33eaaf783ad 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -4017,10 +4017,10 @@ static int alloc_irq_index(struct irq_cfg *cfg, u16 devid, int count)
4017 4017
4018 index -= count - 1; 4018 index -= count - 1;
4019 4019
4020 cfg->remapped = 1;
4020 irte_info = &cfg->irq_2_iommu; 4021 irte_info = &cfg->irq_2_iommu;
4021 irte_info->sub_handle = devid; 4022 irte_info->sub_handle = devid;
4022 irte_info->irte_index = index; 4023 irte_info->irte_index = index;
4023 irte_info->iommu = (void *)cfg;
4024 4024
4025 goto out; 4025 goto out;
4026 } 4026 }
@@ -4127,9 +4127,9 @@ static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry,
4127 index = attr->ioapic_pin; 4127 index = attr->ioapic_pin;
4128 4128
4129 /* Setup IRQ remapping info */ 4129 /* Setup IRQ remapping info */
4130 cfg->remapped = 1;
4130 irte_info->sub_handle = devid; 4131 irte_info->sub_handle = devid;
4131 irte_info->irte_index = index; 4132 irte_info->irte_index = index;
4132 irte_info->iommu = (void *)cfg;
4133 4133
4134 /* Setup IRTE for IOMMU */ 4134 /* Setup IRTE for IOMMU */
4135 irte.val = 0; 4135 irte.val = 0;
@@ -4288,9 +4288,9 @@ static int msi_setup_irq(struct pci_dev *pdev, unsigned int irq,
4288 devid = get_device_id(&pdev->dev); 4288 devid = get_device_id(&pdev->dev);
4289 irte_info = &cfg->irq_2_iommu; 4289 irte_info = &cfg->irq_2_iommu;
4290 4290
4291 cfg->remapped = 1;
4291 irte_info->sub_handle = devid; 4292 irte_info->sub_handle = devid;
4292 irte_info->irte_index = index + offset; 4293 irte_info->irte_index = index + offset;
4293 irte_info->iommu = (void *)cfg;
4294 4294
4295 return 0; 4295 return 0;
4296} 4296}
@@ -4314,9 +4314,9 @@ static int setup_hpet_msi(unsigned int irq, unsigned int id)
4314 if (index < 0) 4314 if (index < 0)
4315 return index; 4315 return index;
4316 4316
4317 cfg->remapped = 1;
4317 irte_info->sub_handle = devid; 4318 irte_info->sub_handle = devid;
4318 irte_info->irte_index = index; 4319 irte_info->irte_index = index;
4319 irte_info->iommu = (void *)cfg;
4320 4320
4321 return 0; 4321 return 0;
4322} 4322}
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c
index cb9a72d4cc09..7ca4947c3c10 100644
--- a/drivers/iommu/intel_irq_remapping.c
+++ b/drivers/iommu/intel_irq_remapping.c
@@ -68,6 +68,7 @@ static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
68{ 68{
69 struct ir_table *table = iommu->ir_table; 69 struct ir_table *table = iommu->ir_table;
70 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); 70 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq);
71 struct irq_cfg *cfg = irq_get_chip_data(irq);
71 u16 index, start_index; 72 u16 index, start_index;
72 unsigned int mask = 0; 73 unsigned int mask = 0;
73 unsigned long flags; 74 unsigned long flags;
@@ -115,6 +116,7 @@ static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
115 for (i = index; i < index + count; i++) 116 for (i = index; i < index + count; i++)
116 table->base[i].present = 1; 117 table->base[i].present = 1;
117 118
119 cfg->remapped = 1;
118 irq_iommu->iommu = iommu; 120 irq_iommu->iommu = iommu;
119 irq_iommu->irte_index = index; 121 irq_iommu->irte_index = index;
120 irq_iommu->sub_handle = 0; 122 irq_iommu->sub_handle = 0;
@@ -155,6 +157,7 @@ static int map_irq_to_irte_handle(int irq, u16 *sub_handle)
155static int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) 157static int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
156{ 158{
157 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); 159 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq);
160 struct irq_cfg *cfg = irq_get_chip_data(irq);
158 unsigned long flags; 161 unsigned long flags;
159 162
160 if (!irq_iommu) 163 if (!irq_iommu)
@@ -162,6 +165,7 @@ static int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subha
162 165
163 raw_spin_lock_irqsave(&irq_2_ir_lock, flags); 166 raw_spin_lock_irqsave(&irq_2_ir_lock, flags);
164 167
168 cfg->remapped = 1;
165 irq_iommu->iommu = iommu; 169 irq_iommu->iommu = iommu;
166 irq_iommu->irte_index = index; 170 irq_iommu->irte_index = index;
167 irq_iommu->sub_handle = subhandle; 171 irq_iommu->sub_handle = subhandle;
diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index ebd02bf98062..75afdf43317c 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -1,3 +1,4 @@
1#include <linux/seq_file.h>
1#include <linux/cpumask.h> 2#include <linux/cpumask.h>
2#include <linux/kernel.h> 3#include <linux/kernel.h>
3#include <linux/string.h> 4#include <linux/string.h>
@@ -327,3 +328,27 @@ void panic_if_irq_remap(const char *msg)
327 if (irq_remapping_enabled) 328 if (irq_remapping_enabled)
328 panic(msg); 329 panic(msg);
329} 330}
331
332static void ir_ack_apic_edge(struct irq_data *data)
333{
334 ack_APIC_irq();
335}
336
337static void ir_ack_apic_level(struct irq_data *data)
338{
339 ack_APIC_irq();
340 eoi_ioapic_irq(data->irq, data->chip_data);
341}
342
343static void ir_print_prefix(struct irq_data *data, struct seq_file *p)
344{
345 seq_printf(p, " IR-%s", data->chip->name);
346}
347
348void irq_remap_modify_chip_defaults(struct irq_chip *chip)
349{
350 chip->irq_print_chip = ir_print_prefix;
351 chip->irq_ack = ir_ack_apic_edge;
352 chip->irq_eoi = ir_ack_apic_level;
353 chip->irq_set_affinity = x86_io_apic_ops.set_affinity;
354}