diff options
-rw-r--r-- | arch/x86/include/asm/hw_irq.h | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/io_apic.h | 5 | ||||
-rw-r--r-- | arch/x86/include/asm/irq_remapping.h | 17 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 44 | ||||
-rw-r--r-- | drivers/iommu/amd_iommu.c | 8 | ||||
-rw-r--r-- | drivers/iommu/intel_irq_remapping.c | 4 | ||||
-rw-r--r-- | drivers/iommu/irq_remapping.c | 25 |
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 | ||
146 | struct io_apic_irq_attr; | 146 | struct io_apic_irq_attr; |
147 | struct irq_cfg; | ||
147 | extern int io_apic_set_pci_routing(struct device *dev, int irq, | 148 | extern 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); |
149 | void setup_IO_APIC_irq_extra(u32 gsi); | 150 | void setup_IO_APIC_irq_extra(u32 gsi); |
@@ -152,6 +153,10 @@ extern void ioapic_insert_resources(void); | |||
152 | extern int native_setup_ioapic_entry(int, struct IO_APIC_route_entry *, | 153 | extern 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 *); |
156 | extern int native_setup_ioapic_entry(int, struct IO_APIC_route_entry *, | ||
157 | unsigned int, int, | ||
158 | struct io_apic_irq_attr *); | ||
159 | extern void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg); | ||
155 | 160 | ||
156 | int io_apic_setup_irq_pin_once(unsigned int irq, int node, struct io_apic_irq_attr *attr); | 161 | int 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, | |||
45 | extern int setup_hpet_msi_remapped(unsigned int irq, unsigned int id); | 45 | extern int setup_hpet_msi_remapped(unsigned int irq, unsigned int id); |
46 | extern void panic_if_irq_remap(const char *msg); | 46 | extern void panic_if_irq_remap(const char *msg); |
47 | 47 | ||
48 | static inline bool irq_remapped(struct irq_cfg *cfg) | ||
49 | { | ||
50 | return (cfg->remapped == 1); | ||
51 | } | ||
52 | |||
53 | void irq_remap_modify_chip_defaults(struct irq_chip *chip); | ||
54 | |||
48 | #else /* CONFIG_IRQ_REMAP */ | 55 | #else /* CONFIG_IRQ_REMAP */ |
49 | 56 | ||
50 | static inline void setup_irq_remapping_ops(void) { } | 57 | static inline void setup_irq_remapping_ops(void) { } |
@@ -76,6 +83,16 @@ static inline int setup_hpet_msi_remapped(unsigned int irq, unsigned int id) | |||
76 | static inline void panic_if_irq_remap(const char *msg) | 83 | static inline void panic_if_irq_remap(const char *msg) |
77 | { | 84 | { |
78 | } | 85 | } |
86 | |||
87 | static inline bool irq_remapped(struct irq_cfg *cfg) | ||
88 | { | ||
89 | return false; | ||
90 | } | ||
91 | |||
92 | static 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 | ||
72 | static void irq_remap_modify_chip_defaults(struct irq_chip *chip); | ||
73 | static inline bool irq_remapped(struct irq_cfg *cfg) | ||
74 | { | ||
75 | return cfg->irq_2_iommu.iommu != NULL; | ||
76 | } | ||
77 | #else | ||
78 | static inline bool irq_remapped(struct irq_cfg *cfg) | ||
79 | { | ||
80 | return false; | ||
81 | } | ||
82 | static 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 | ||
609 | static void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) | 593 | void 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 | ||
2546 | static void ir_ack_apic_edge(struct irq_data *data) | ||
2547 | { | ||
2548 | ack_APIC_irq(); | ||
2549 | } | ||
2550 | |||
2551 | static 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 | |||
2557 | static void ir_print_prefix(struct irq_data *data, struct seq_file *p) | ||
2558 | { | ||
2559 | seq_printf(p, " IR-%s", data->chip->name); | ||
2560 | } | ||
2561 | |||
2562 | static 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 | |||
2571 | static struct irq_chip ioapic_chip __read_mostly = { | 2529 | static 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) | |||
155 | static int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) | 157 | static 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 | |||
332 | static void ir_ack_apic_edge(struct irq_data *data) | ||
333 | { | ||
334 | ack_APIC_irq(); | ||
335 | } | ||
336 | |||
337 | static 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 | |||
343 | static void ir_print_prefix(struct irq_data *data, struct seq_file *p) | ||
344 | { | ||
345 | seq_printf(p, " IR-%s", data->chip->name); | ||
346 | } | ||
347 | |||
348 | void 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 | } | ||