Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'ioapic-cleanups-for-tip' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu into x86/apic

Pull "x86 IOAPIC code from interrupt remapping details cleanups" from
Joerg Roedel:

"These patches move all interrupt remapping specific checks out of the
x86 core code and replaces the respective call-sites with function
pointers. As a result the interrupt remapping code is better abstraced
from x86 core interrupt handling code.

The code was rebased to v3.8-rc4 and tested on systems with AMD-Vi and
Intel VT-d (both capable of interrupt remapping). The systems were
tested with IOMMU enabled and with IOMMU disabled. No issues were found."

Signed-off-by: Ingo Molnar <mingo@kernel.org>

+510 -377
+3 -2
arch/x86/include/asm/hpet.h
··· 80 80 extern void hpet_msi_read(struct hpet_dev *hdev, struct msi_msg *msg); 81 81 82 82 #ifdef CONFIG_PCI_MSI 83 - extern int arch_setup_hpet_msi(unsigned int irq, unsigned int id); 83 + extern int default_setup_hpet_msi(unsigned int irq, unsigned int id); 84 84 #else 85 - static inline int arch_setup_hpet_msi(unsigned int irq, unsigned int id) 85 + static inline int default_setup_hpet_msi(unsigned int irq, unsigned int id) 86 86 { 87 87 return -EINVAL; 88 88 } ··· 111 111 static inline int hpet_enable(void) { return 0; } 112 112 static inline int is_hpet_enabled(void) { return 0; } 113 113 #define hpet_readl(a) 0 114 + #define default_setup_hpet_msi NULL 114 115 115 116 #endif 116 117 #endif /* _ASM_X86_HPET_H */
+12 -1
arch/x86/include/asm/hw_irq.h
··· 101 101 irq_attr->polarity = polarity; 102 102 } 103 103 104 + /* Intel specific interrupt remapping information */ 104 105 struct irq_2_iommu { 105 106 struct intel_iommu *iommu; 106 107 u16 irte_index; 107 108 u16 sub_handle; 108 109 u8 irte_mask; 110 + }; 111 + 112 + /* AMD specific interrupt remapping information */ 113 + struct irq_2_irte { 114 + u16 devid; /* Device ID for IRTE table */ 115 + u16 index; /* Index into IRTE table*/ 109 116 }; 110 117 111 118 /* ··· 127 120 u8 vector; 128 121 u8 move_in_progress : 1; 129 122 #ifdef CONFIG_IRQ_REMAP 130 - struct irq_2_iommu irq_2_iommu; 123 + u8 remapped : 1; 124 + union { 125 + struct irq_2_iommu irq_2_iommu; 126 + struct irq_2_irte irq_2_irte; 127 + }; 131 128 #endif 132 129 }; 133 130
+28
arch/x86/include/asm/io_apic.h
··· 144 144 (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs) 145 145 146 146 struct io_apic_irq_attr; 147 + struct irq_cfg; 147 148 extern int io_apic_set_pci_routing(struct device *dev, int irq, 148 149 struct io_apic_irq_attr *irq_attr); 149 150 void setup_IO_APIC_irq_extra(u32 gsi); 150 151 extern void ioapic_insert_resources(void); 151 152 153 + extern int native_setup_ioapic_entry(int, struct IO_APIC_route_entry *, 154 + unsigned int, int, 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); 160 + 161 + extern void native_compose_msi_msg(struct pci_dev *pdev, 162 + unsigned int irq, unsigned int dest, 163 + struct msi_msg *msg, u8 hpet_id); 164 + extern void native_eoi_ioapic_pin(int apic, int pin, int vector); 152 165 int io_apic_setup_irq_pin_once(unsigned int irq, int node, struct io_apic_irq_attr *attr); 153 166 154 167 extern int save_ioapic_entries(void); ··· 192 179 extern unsigned int native_io_apic_read(unsigned int apic, unsigned int reg); 193 180 extern void native_io_apic_write(unsigned int apic, unsigned int reg, unsigned int val); 194 181 extern void native_io_apic_modify(unsigned int apic, unsigned int reg, unsigned int val); 182 + extern void native_disable_io_apic(void); 183 + extern void native_io_apic_print_entries(unsigned int apic, unsigned int nr_entries); 184 + extern void intel_ir_io_apic_print_entries(unsigned int apic, unsigned int nr_entries); 185 + extern int native_ioapic_set_affinity(struct irq_data *, 186 + const struct cpumask *, 187 + bool); 195 188 196 189 static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) 197 190 { ··· 212 193 { 213 194 x86_io_apic_ops.modify(apic, reg, value); 214 195 } 196 + 197 + extern void io_apic_eoi(unsigned int apic, unsigned int vector); 198 + 215 199 #else /* !CONFIG_X86_IO_APIC */ 216 200 217 201 #define io_apic_assign_pci_irqs 0 ··· 245 223 #define native_io_apic_read NULL 246 224 #define native_io_apic_write NULL 247 225 #define native_io_apic_modify NULL 226 + #define native_disable_io_apic NULL 227 + #define native_io_apic_print_entries NULL 228 + #define native_ioapic_set_affinity NULL 229 + #define native_setup_ioapic_entry NULL 230 + #define native_compose_msi_msg NULL 231 + #define native_eoi_ioapic_pin NULL 248 232 #endif 249 233 250 234 #endif /* _ASM_X86_IO_APIC_H */
+21 -25
arch/x86/include/asm/irq_remapping.h
··· 26 26 27 27 #ifdef CONFIG_IRQ_REMAP 28 28 29 - extern int irq_remapping_enabled; 30 - 31 29 extern void setup_irq_remapping_ops(void); 32 30 extern int irq_remapping_supported(void); 33 31 extern int irq_remapping_prepare(void); ··· 38 40 unsigned int destination, 39 41 int vector, 40 42 struct io_apic_irq_attr *attr); 41 - extern int set_remapped_irq_affinity(struct irq_data *data, 42 - const struct cpumask *mask, 43 - bool force); 44 43 extern void free_remapped_irq(int irq); 45 44 extern void compose_remapped_msi_msg(struct pci_dev *pdev, 46 45 unsigned int irq, unsigned int dest, 47 46 struct msi_msg *msg, u8 hpet_id); 48 - extern int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec); 49 - extern int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq, 50 - int index, int sub_handle); 51 47 extern int setup_hpet_msi_remapped(unsigned int irq, unsigned int id); 48 + extern void panic_if_irq_remap(const char *msg); 49 + extern bool setup_remapped_irq(int irq, 50 + struct irq_cfg *cfg, 51 + struct irq_chip *chip); 52 + 53 + void irq_remap_modify_chip_defaults(struct irq_chip *chip); 52 54 53 55 #else /* CONFIG_IRQ_REMAP */ 54 - 55 - #define irq_remapping_enabled 0 56 56 57 57 static inline void setup_irq_remapping_ops(void) { } 58 58 static inline int irq_remapping_supported(void) { return 0; } ··· 67 71 { 68 72 return -ENODEV; 69 73 } 70 - static inline int set_remapped_irq_affinity(struct irq_data *data, 71 - const struct cpumask *mask, 72 - bool force) 73 - { 74 - return 0; 75 - } 76 74 static inline void free_remapped_irq(int irq) { } 77 75 static inline void compose_remapped_msi_msg(struct pci_dev *pdev, 78 76 unsigned int irq, unsigned int dest, 79 77 struct msi_msg *msg, u8 hpet_id) 80 78 { 81 79 } 82 - static inline int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec) 83 - { 84 - return -ENODEV; 85 - } 86 - static inline int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq, 87 - int index, int sub_handle) 88 - { 89 - return -ENODEV; 90 - } 91 80 static inline int setup_hpet_msi_remapped(unsigned int irq, unsigned int id) 92 81 { 93 82 return -ENODEV; 83 + } 84 + 85 + static inline void panic_if_irq_remap(const char *msg) 86 + { 87 + } 88 + 89 + static inline void irq_remap_modify_chip_defaults(struct irq_chip *chip) 90 + { 91 + } 92 + 93 + static inline bool setup_remapped_irq(int irq, 94 + struct irq_cfg *cfg, 95 + struct irq_chip *chip) 96 + { 97 + return false; 94 98 } 95 99 #endif /* CONFIG_IRQ_REMAP */ 96 100
+3
arch/x86/include/asm/pci.h
··· 121 121 #define arch_teardown_msi_irq x86_teardown_msi_irq 122 122 #define arch_restore_msi_irqs x86_restore_msi_irqs 123 123 /* implemented in arch/x86/kernel/apic/io_apic. */ 124 + struct msi_desc; 124 125 int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); 125 126 void native_teardown_msi_irq(unsigned int irq); 126 127 void native_restore_msi_irqs(struct pci_dev *dev, int irq); 128 + int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, 129 + unsigned int irq_base, unsigned int irq_offset); 127 130 /* default to the implementation in drivers/lib/msi.c */ 128 131 #define HAVE_DEFAULT_MSI_TEARDOWN_IRQS 129 132 #define HAVE_DEFAULT_MSI_RESTORE_IRQS
+23 -4
arch/x86/include/asm/x86_init.h
··· 181 181 }; 182 182 183 183 struct pci_dev; 184 + struct msi_msg; 184 185 185 186 struct x86_msi_ops { 186 187 int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type); 188 + void (*compose_msi_msg)(struct pci_dev *dev, unsigned int irq, 189 + unsigned int dest, struct msi_msg *msg, 190 + u8 hpet_id); 187 191 void (*teardown_msi_irq)(unsigned int irq); 188 192 void (*teardown_msi_irqs)(struct pci_dev *dev); 189 193 void (*restore_msi_irqs)(struct pci_dev *dev, int irq); 194 + int (*setup_hpet_msi)(unsigned int irq, unsigned int id); 190 195 }; 191 196 197 + struct IO_APIC_route_entry; 198 + struct io_apic_irq_attr; 199 + struct irq_data; 200 + struct cpumask; 201 + 192 202 struct x86_io_apic_ops { 193 - void (*init) (void); 194 - unsigned int (*read) (unsigned int apic, unsigned int reg); 195 - void (*write) (unsigned int apic, unsigned int reg, unsigned int value); 196 - void (*modify)(unsigned int apic, unsigned int reg, unsigned int value); 203 + void (*init) (void); 204 + unsigned int (*read) (unsigned int apic, unsigned int reg); 205 + void (*write) (unsigned int apic, unsigned int reg, unsigned int value); 206 + void (*modify) (unsigned int apic, unsigned int reg, unsigned int value); 207 + void (*disable)(void); 208 + void (*print_entries)(unsigned int apic, unsigned int nr_entries); 209 + int (*set_affinity)(struct irq_data *data, 210 + const struct cpumask *mask, 211 + bool force); 212 + int (*setup_entry)(int irq, struct IO_APIC_route_entry *entry, 213 + unsigned int destination, int vector, 214 + struct io_apic_irq_attr *attr); 215 + void (*eoi_ioapic_pin)(int apic, int pin, int vector); 197 216 }; 198 217 199 218 extern struct x86_init_ops x86_init;
+12 -16
arch/x86/kernel/apic/apic.c
··· 1477 1477 * Now that local APIC setup is completed for BP, configure the fault 1478 1478 * handling for interrupt remapping. 1479 1479 */ 1480 - if (irq_remapping_enabled) 1481 - irq_remap_enable_fault_handling(); 1480 + irq_remap_enable_fault_handling(); 1482 1481 1483 1482 } 1484 1483 ··· 2250 2251 local_irq_save(flags); 2251 2252 disable_local_APIC(); 2252 2253 2253 - if (irq_remapping_enabled) 2254 - irq_remapping_disable(); 2254 + irq_remapping_disable(); 2255 2255 2256 2256 local_irq_restore(flags); 2257 2257 return 0; ··· 2266 2268 return; 2267 2269 2268 2270 local_irq_save(flags); 2269 - if (irq_remapping_enabled) { 2270 - /* 2271 - * IO-APIC and PIC have their own resume routines. 2272 - * We just mask them here to make sure the interrupt 2273 - * subsystem is completely quiet while we enable x2apic 2274 - * and interrupt-remapping. 2275 - */ 2276 - mask_ioapic_entries(); 2277 - legacy_pic->mask_all(); 2278 - } 2271 + 2272 + /* 2273 + * IO-APIC and PIC have their own resume routines. 2274 + * We just mask them here to make sure the interrupt 2275 + * subsystem is completely quiet while we enable x2apic 2276 + * and interrupt-remapping. 2277 + */ 2278 + mask_ioapic_entries(); 2279 + legacy_pic->mask_all(); 2279 2280 2280 2281 if (x2apic_mode) 2281 2282 enable_x2apic(); ··· 2317 2320 apic_write(APIC_ESR, 0); 2318 2321 apic_read(APIC_ESR); 2319 2322 2320 - if (irq_remapping_enabled) 2321 - irq_remapping_reenable(x2apic_mode); 2323 + irq_remapping_reenable(x2apic_mode); 2322 2324 2323 2325 local_irq_restore(flags); 2324 2326 }
+146 -306
arch/x86/kernel/apic/io_apic.c
··· 68 68 #define for_each_irq_pin(entry, head) \ 69 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 72 * Is the SiS APIC rmw bug present ? 89 73 * -1 = don't know, 0 = no, 1 = yes ··· 310 326 + (mpc_ioapic_addr(idx) & ~PAGE_MASK); 311 327 } 312 328 313 - static inline void io_apic_eoi(unsigned int apic, unsigned int vector) 329 + void io_apic_eoi(unsigned int apic, unsigned int vector) 314 330 { 315 331 struct io_apic __iomem *io_apic = io_apic_base(apic); 316 332 writel(vector, &io_apic->eoi); ··· 557 573 * Otherwise, we simulate the EOI message manually by changing the trigger 558 574 * mode to edge and then back to level, with RTE being masked during this. 559 575 */ 560 - static void __eoi_ioapic_pin(int apic, int pin, int vector, struct irq_cfg *cfg) 576 + void native_eoi_ioapic_pin(int apic, int pin, int vector) 561 577 { 562 578 if (mpc_ioapic_ver(apic) >= 0x20) { 563 - /* 564 - * Intr-remapping uses pin number as the virtual vector 565 - * in the RTE. Actual vector is programmed in 566 - * intr-remapping table entry. Hence for the io-apic 567 - * EOI we use the pin number. 568 - */ 569 - if (cfg && irq_remapped(cfg)) 570 - io_apic_eoi(apic, pin); 571 - else 572 - io_apic_eoi(apic, vector); 579 + io_apic_eoi(apic, vector); 573 580 } else { 574 581 struct IO_APIC_route_entry entry, entry1; 575 582 ··· 581 606 } 582 607 } 583 608 584 - static void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) 609 + void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) 585 610 { 586 611 struct irq_pin_list *entry; 587 612 unsigned long flags; 588 613 589 614 raw_spin_lock_irqsave(&ioapic_lock, flags); 590 615 for_each_irq_pin(entry, cfg->irq_2_pin) 591 - __eoi_ioapic_pin(entry->apic, entry->pin, cfg->vector, cfg); 616 + x86_io_apic_ops.eoi_ioapic_pin(entry->apic, entry->pin, 617 + cfg->vector); 592 618 raw_spin_unlock_irqrestore(&ioapic_lock, flags); 593 619 } 594 620 ··· 626 650 } 627 651 628 652 raw_spin_lock_irqsave(&ioapic_lock, flags); 629 - __eoi_ioapic_pin(apic, pin, entry.vector, NULL); 653 + x86_io_apic_ops.eoi_ioapic_pin(apic, pin, entry.vector); 630 654 raw_spin_unlock_irqrestore(&ioapic_lock, flags); 631 655 } 632 656 ··· 1280 1304 fasteoi = false; 1281 1305 } 1282 1306 1283 - if (irq_remapped(cfg)) { 1284 - irq_set_status_flags(irq, IRQ_MOVE_PCNTXT); 1285 - irq_remap_modify_chip_defaults(chip); 1307 + if (setup_remapped_irq(irq, cfg, chip)) 1286 1308 fasteoi = trigger != 0; 1287 - } 1288 1309 1289 1310 hdl = fasteoi ? handle_fasteoi_irq : handle_edge_irq; 1290 1311 irq_set_chip_and_handler_name(irq, chip, hdl, 1291 1312 fasteoi ? "fasteoi" : "edge"); 1292 1313 } 1293 1314 1294 - static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry, 1295 - unsigned int destination, int vector, 1296 - struct io_apic_irq_attr *attr) 1315 + int native_setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry, 1316 + unsigned int destination, int vector, 1317 + struct io_apic_irq_attr *attr) 1297 1318 { 1298 - if (irq_remapping_enabled) 1299 - return setup_ioapic_remapped_entry(irq, entry, destination, 1300 - vector, attr); 1301 - 1302 1319 memset(entry, 0, sizeof(*entry)); 1303 1320 1304 1321 entry->delivery_mode = apic->irq_delivery_mode; ··· 1339 1370 attr->ioapic, mpc_ioapic_id(attr->ioapic), attr->ioapic_pin, 1340 1371 cfg->vector, irq, attr->trigger, attr->polarity, dest); 1341 1372 1342 - if (setup_ioapic_entry(irq, &entry, dest, cfg->vector, attr)) { 1343 - pr_warn("Failed to setup ioapic entry for ioapic %d, pin %d\n", 1373 + if (x86_io_apic_ops.setup_entry(irq, &entry, dest, cfg->vector, attr)) { 1374 + pr_warn("Failed to setup ioapic entry for ioapic %d, pin %d\n", 1344 1375 mpc_ioapic_id(attr->ioapic), attr->ioapic_pin); 1345 1376 __clear_irq_vector(irq, cfg); 1346 1377 ··· 1448 1479 struct IO_APIC_route_entry entry; 1449 1480 unsigned int dest; 1450 1481 1451 - if (irq_remapping_enabled) 1452 - return; 1453 - 1454 1482 memset(&entry, 0, sizeof(entry)); 1455 1483 1456 1484 /* ··· 1479 1513 ioapic_write_entry(ioapic_idx, pin, entry); 1480 1514 } 1481 1515 1482 - __apicdebuginit(void) print_IO_APIC(int ioapic_idx) 1516 + void native_io_apic_print_entries(unsigned int apic, unsigned int nr_entries) 1483 1517 { 1484 1518 int i; 1519 + 1520 + pr_debug(" NR Dst Mask Trig IRR Pol Stat Dmod Deli Vect:\n"); 1521 + 1522 + for (i = 0; i <= nr_entries; i++) { 1523 + struct IO_APIC_route_entry entry; 1524 + 1525 + entry = ioapic_read_entry(apic, i); 1526 + 1527 + pr_debug(" %02x %02X ", i, entry.dest); 1528 + pr_cont("%1d %1d %1d %1d %1d " 1529 + "%1d %1d %02X\n", 1530 + entry.mask, 1531 + entry.trigger, 1532 + entry.irr, 1533 + entry.polarity, 1534 + entry.delivery_status, 1535 + entry.dest_mode, 1536 + entry.delivery_mode, 1537 + entry.vector); 1538 + } 1539 + } 1540 + 1541 + void intel_ir_io_apic_print_entries(unsigned int apic, 1542 + unsigned int nr_entries) 1543 + { 1544 + int i; 1545 + 1546 + pr_debug(" NR Indx Fmt Mask Trig IRR Pol Stat Indx2 Zero Vect:\n"); 1547 + 1548 + for (i = 0; i <= nr_entries; i++) { 1549 + struct IR_IO_APIC_route_entry *ir_entry; 1550 + struct IO_APIC_route_entry entry; 1551 + 1552 + entry = ioapic_read_entry(apic, i); 1553 + 1554 + ir_entry = (struct IR_IO_APIC_route_entry *)&entry; 1555 + 1556 + pr_debug(" %02x %04X ", i, ir_entry->index); 1557 + pr_cont("%1d %1d %1d %1d %1d " 1558 + "%1d %1d %X %02X\n", 1559 + ir_entry->format, 1560 + ir_entry->mask, 1561 + ir_entry->trigger, 1562 + ir_entry->irr, 1563 + ir_entry->polarity, 1564 + ir_entry->delivery_status, 1565 + ir_entry->index2, 1566 + ir_entry->zero, 1567 + ir_entry->vector); 1568 + } 1569 + } 1570 + 1571 + __apicdebuginit(void) print_IO_APIC(int ioapic_idx) 1572 + { 1485 1573 union IO_APIC_reg_00 reg_00; 1486 1574 union IO_APIC_reg_01 reg_01; 1487 1575 union IO_APIC_reg_02 reg_02; ··· 1588 1568 1589 1569 printk(KERN_DEBUG ".... IRQ redirection table:\n"); 1590 1570 1591 - if (irq_remapping_enabled) { 1592 - printk(KERN_DEBUG " NR Indx Fmt Mask Trig IRR" 1593 - " Pol Stat Indx2 Zero Vect:\n"); 1594 - } else { 1595 - printk(KERN_DEBUG " NR Dst Mask Trig IRR Pol" 1596 - " Stat Dmod Deli Vect:\n"); 1597 - } 1598 - 1599 - for (i = 0; i <= reg_01.bits.entries; i++) { 1600 - if (irq_remapping_enabled) { 1601 - struct IO_APIC_route_entry entry; 1602 - struct IR_IO_APIC_route_entry *ir_entry; 1603 - 1604 - entry = ioapic_read_entry(ioapic_idx, i); 1605 - ir_entry = (struct IR_IO_APIC_route_entry *) &entry; 1606 - printk(KERN_DEBUG " %02x %04X ", 1607 - i, 1608 - ir_entry->index 1609 - ); 1610 - pr_cont("%1d %1d %1d %1d %1d " 1611 - "%1d %1d %X %02X\n", 1612 - ir_entry->format, 1613 - ir_entry->mask, 1614 - ir_entry->trigger, 1615 - ir_entry->irr, 1616 - ir_entry->polarity, 1617 - ir_entry->delivery_status, 1618 - ir_entry->index2, 1619 - ir_entry->zero, 1620 - ir_entry->vector 1621 - ); 1622 - } else { 1623 - struct IO_APIC_route_entry entry; 1624 - 1625 - entry = ioapic_read_entry(ioapic_idx, i); 1626 - printk(KERN_DEBUG " %02x %02X ", 1627 - i, 1628 - entry.dest 1629 - ); 1630 - pr_cont("%1d %1d %1d %1d %1d " 1631 - "%1d %1d %02X\n", 1632 - entry.mask, 1633 - entry.trigger, 1634 - entry.irr, 1635 - entry.polarity, 1636 - entry.delivery_status, 1637 - entry.dest_mode, 1638 - entry.delivery_mode, 1639 - entry.vector 1640 - ); 1641 - } 1642 - } 1571 + x86_io_apic_ops.print_entries(ioapic_idx, reg_01.bits.entries); 1643 1572 } 1644 1573 1645 1574 __apicdebuginit(void) print_IO_APICs(void) ··· 1890 1921 clear_IO_APIC(); 1891 1922 } 1892 1923 1893 - /* 1894 - * Not an __init, needed by the reboot code 1895 - */ 1896 - void disable_IO_APIC(void) 1924 + void native_disable_io_apic(void) 1897 1925 { 1898 - /* 1899 - * Clear the IO-APIC before rebooting: 1900 - */ 1901 - clear_IO_APIC(); 1902 - 1903 - if (!legacy_pic->nr_legacy_irqs) 1904 - return; 1905 - 1906 1926 /* 1907 1927 * If the i8259 is routed through an IOAPIC 1908 1928 * Put that IOAPIC in virtual wire mode 1909 1929 * so legacy interrupts can be delivered. 1910 - * 1911 - * With interrupt-remapping, for now we will use virtual wire A mode, 1912 - * as virtual wire B is little complex (need to configure both 1913 - * IOAPIC RTE as well as interrupt-remapping table entry). 1914 - * As this gets called during crash dump, keep this simple for now. 1915 1930 */ 1916 - if (ioapic_i8259.pin != -1 && !irq_remapping_enabled) { 1931 + if (ioapic_i8259.pin != -1) { 1917 1932 struct IO_APIC_route_entry entry; 1918 1933 1919 1934 memset(&entry, 0, sizeof(entry)); ··· 1917 1964 ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry); 1918 1965 } 1919 1966 1920 - /* 1921 - * Use virtual wire A mode when interrupt remapping is enabled. 1922 - */ 1923 1967 if (cpu_has_apic || apic_from_smp_config()) 1924 - disconnect_bsp_APIC(!irq_remapping_enabled && 1925 - ioapic_i8259.pin != -1); 1968 + disconnect_bsp_APIC(ioapic_i8259.pin != -1); 1969 + 1970 + } 1971 + 1972 + /* 1973 + * Not an __init, needed by the reboot code 1974 + */ 1975 + void disable_IO_APIC(void) 1976 + { 1977 + /* 1978 + * Clear the IO-APIC before rebooting: 1979 + */ 1980 + clear_IO_APIC(); 1981 + 1982 + if (!legacy_pic->nr_legacy_irqs) 1983 + return; 1984 + 1985 + x86_io_apic_ops.disable(); 1926 1986 } 1927 1987 1928 1988 #ifdef CONFIG_X86_32 ··· 2288 2322 2289 2323 apic = entry->apic; 2290 2324 pin = entry->pin; 2291 - /* 2292 - * With interrupt-remapping, destination information comes 2293 - * from interrupt-remapping table entry. 2294 - */ 2295 - if (!irq_remapped(cfg)) 2296 - io_apic_write(apic, 0x11 + pin*2, dest); 2325 + 2326 + io_apic_write(apic, 0x11 + pin*2, dest); 2297 2327 reg = io_apic_read(apic, 0x10 + pin*2); 2298 2328 reg &= ~IO_APIC_REDIR_VECTOR_MASK; 2299 2329 reg |= vector; ··· 2331 2369 return 0; 2332 2370 } 2333 2371 2334 - static int 2335 - ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, 2336 - bool force) 2372 + 2373 + int native_ioapic_set_affinity(struct irq_data *data, 2374 + const struct cpumask *mask, 2375 + bool force) 2337 2376 { 2338 2377 unsigned int dest, irq = data->irq; 2339 2378 unsigned long flags; ··· 2511 2548 ioapic_irqd_unmask(data, cfg, masked); 2512 2549 } 2513 2550 2514 - #ifdef CONFIG_IRQ_REMAP 2515 - static void ir_ack_apic_edge(struct irq_data *data) 2516 - { 2517 - ack_APIC_irq(); 2518 - } 2519 - 2520 - static void ir_ack_apic_level(struct irq_data *data) 2521 - { 2522 - ack_APIC_irq(); 2523 - eoi_ioapic_irq(data->irq, data->chip_data); 2524 - } 2525 - 2526 - static void ir_print_prefix(struct irq_data *data, struct seq_file *p) 2527 - { 2528 - seq_printf(p, " IR-%s", data->chip->name); 2529 - } 2530 - 2531 - static void irq_remap_modify_chip_defaults(struct irq_chip *chip) 2532 - { 2533 - chip->irq_print_chip = ir_print_prefix; 2534 - chip->irq_ack = ir_ack_apic_edge; 2535 - chip->irq_eoi = ir_ack_apic_level; 2536 - 2537 - chip->irq_set_affinity = set_remapped_irq_affinity; 2538 - } 2539 - #endif /* CONFIG_IRQ_REMAP */ 2540 - 2541 2551 static struct irq_chip ioapic_chip __read_mostly = { 2542 2552 .name = "IO-APIC", 2543 2553 .irq_startup = startup_ioapic_irq, ··· 2518 2582 .irq_unmask = unmask_ioapic_irq, 2519 2583 .irq_ack = ack_apic_edge, 2520 2584 .irq_eoi = ack_apic_level, 2521 - .irq_set_affinity = ioapic_set_affinity, 2585 + .irq_set_affinity = native_ioapic_set_affinity, 2522 2586 .irq_retrigger = ioapic_retrigger_irq, 2523 2587 }; 2524 2588 ··· 2717 2781 * 8259A. 2718 2782 */ 2719 2783 if (pin1 == -1) { 2720 - if (irq_remapping_enabled) 2721 - panic("BIOS bug: timer not connected to IO-APIC"); 2784 + panic_if_irq_remap("BIOS bug: timer not connected to IO-APIC"); 2722 2785 pin1 = pin2; 2723 2786 apic1 = apic2; 2724 2787 no_pin1 = 1; ··· 2749 2814 clear_IO_APIC_pin(0, pin1); 2750 2815 goto out; 2751 2816 } 2752 - if (irq_remapping_enabled) 2753 - panic("timer doesn't work through Interrupt-remapped IO-APIC"); 2817 + panic_if_irq_remap("timer doesn't work through Interrupt-remapped IO-APIC"); 2754 2818 local_irq_disable(); 2755 2819 clear_IO_APIC_pin(apic1, pin1); 2756 2820 if (!no_pin1) ··· 2992 3058 2993 3059 irq_set_status_flags(irq, IRQ_NOREQUEST|IRQ_NOPROBE); 2994 3060 2995 - if (irq_remapped(cfg)) 2996 - free_remapped_irq(irq); 3061 + free_remapped_irq(irq); 3062 + 2997 3063 raw_spin_lock_irqsave(&vector_lock, flags); 2998 3064 __clear_irq_vector(irq, cfg); 2999 3065 raw_spin_unlock_irqrestore(&vector_lock, flags); 3000 3066 free_irq_at(irq, cfg); 3001 3067 } 3002 3068 3003 - static inline void destroy_irqs(unsigned int irq, unsigned int count) 3069 + void destroy_irqs(unsigned int irq, unsigned int count) 3004 3070 { 3005 3071 unsigned int i; 3006 3072 ··· 3011 3077 /* 3012 3078 * MSI message composition 3013 3079 */ 3080 + void native_compose_msi_msg(struct pci_dev *pdev, 3081 + unsigned int irq, unsigned int dest, 3082 + struct msi_msg *msg, u8 hpet_id) 3083 + { 3084 + struct irq_cfg *cfg = irq_cfg(irq); 3085 + 3086 + msg->address_hi = MSI_ADDR_BASE_HI; 3087 + 3088 + if (x2apic_enabled()) 3089 + msg->address_hi |= MSI_ADDR_EXT_DEST_ID(dest); 3090 + 3091 + msg->address_lo = 3092 + MSI_ADDR_BASE_LO | 3093 + ((apic->irq_dest_mode == 0) ? 3094 + MSI_ADDR_DEST_MODE_PHYSICAL: 3095 + MSI_ADDR_DEST_MODE_LOGICAL) | 3096 + ((apic->irq_delivery_mode != dest_LowestPrio) ? 3097 + MSI_ADDR_REDIRECTION_CPU: 3098 + MSI_ADDR_REDIRECTION_LOWPRI) | 3099 + MSI_ADDR_DEST_ID(dest); 3100 + 3101 + msg->data = 3102 + MSI_DATA_TRIGGER_EDGE | 3103 + MSI_DATA_LEVEL_ASSERT | 3104 + ((apic->irq_delivery_mode != dest_LowestPrio) ? 3105 + MSI_DATA_DELIVERY_FIXED: 3106 + MSI_DATA_DELIVERY_LOWPRI) | 3107 + MSI_DATA_VECTOR(cfg->vector); 3108 + } 3109 + 3014 3110 #ifdef CONFIG_PCI_MSI 3015 3111 static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, 3016 3112 struct msi_msg *msg, u8 hpet_id) ··· 3062 3098 if (err) 3063 3099 return err; 3064 3100 3065 - if (irq_remapped(cfg)) { 3066 - compose_remapped_msi_msg(pdev, irq, dest, msg, hpet_id); 3067 - return 0; 3068 - } 3069 - 3070 - if (x2apic_enabled()) 3071 - msg->address_hi = MSI_ADDR_BASE_HI | 3072 - MSI_ADDR_EXT_DEST_ID(dest); 3073 - else 3074 - msg->address_hi = MSI_ADDR_BASE_HI; 3075 - 3076 - msg->address_lo = 3077 - MSI_ADDR_BASE_LO | 3078 - ((apic->irq_dest_mode == 0) ? 3079 - MSI_ADDR_DEST_MODE_PHYSICAL: 3080 - MSI_ADDR_DEST_MODE_LOGICAL) | 3081 - ((apic->irq_delivery_mode != dest_LowestPrio) ? 3082 - MSI_ADDR_REDIRECTION_CPU: 3083 - MSI_ADDR_REDIRECTION_LOWPRI) | 3084 - MSI_ADDR_DEST_ID(dest); 3085 - 3086 - msg->data = 3087 - MSI_DATA_TRIGGER_EDGE | 3088 - MSI_DATA_LEVEL_ASSERT | 3089 - ((apic->irq_delivery_mode != dest_LowestPrio) ? 3090 - MSI_DATA_DELIVERY_FIXED: 3091 - MSI_DATA_DELIVERY_LOWPRI) | 3092 - MSI_DATA_VECTOR(cfg->vector); 3101 + x86_msi.compose_msi_msg(pdev, irq, dest, msg, hpet_id); 3093 3102 3094 3103 return 0; 3095 3104 } ··· 3102 3165 .irq_retrigger = ioapic_retrigger_irq, 3103 3166 }; 3104 3167 3105 - static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, 3106 - unsigned int irq_base, unsigned int irq_offset) 3168 + int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, 3169 + unsigned int irq_base, unsigned int irq_offset) 3107 3170 { 3108 3171 struct irq_chip *chip = &msi_chip; 3109 3172 struct msi_msg msg; ··· 3123 3186 if (!irq_offset) 3124 3187 write_msi_msg(irq, &msg); 3125 3188 3126 - if (irq_remapped(irq_get_chip_data(irq))) { 3127 - irq_set_status_flags(irq, IRQ_MOVE_PCNTXT); 3128 - irq_remap_modify_chip_defaults(chip); 3129 - } 3189 + setup_remapped_irq(irq, irq_get_chip_data(irq), chip); 3130 3190 3131 3191 irq_set_chip_and_handler_name(irq, chip, handle_edge_irq, "edge"); 3132 3192 ··· 3132 3198 return 0; 3133 3199 } 3134 3200 3135 - int setup_msix_irqs(struct pci_dev *dev, int nvec) 3201 + int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 3136 3202 { 3137 - int node, ret, sub_handle, index = 0; 3138 3203 unsigned int irq, irq_want; 3139 3204 struct msi_desc *msidesc; 3205 + int node, ret; 3206 + 3207 + /* Multiple MSI vectors only supported with interrupt remapping */ 3208 + if (type == PCI_CAP_ID_MSI && nvec > 1) 3209 + return 1; 3140 3210 3141 3211 node = dev_to_node(&dev->dev); 3142 3212 irq_want = nr_irqs_gsi; 3143 - sub_handle = 0; 3144 3213 list_for_each_entry(msidesc, &dev->msi_list, list) { 3145 3214 irq = create_irq_nr(irq_want, node); 3146 3215 if (irq == 0) 3147 3216 return -ENOSPC; 3148 - irq_want = irq + 1; 3149 - if (!irq_remapping_enabled) 3150 - goto no_ir; 3151 3217 3152 - if (!sub_handle) { 3153 - /* 3154 - * allocate the consecutive block of IRTE's 3155 - * for 'nvec' 3156 - */ 3157 - index = msi_alloc_remapped_irq(dev, irq, nvec); 3158 - if (index < 0) { 3159 - ret = index; 3160 - goto error; 3161 - } 3162 - } else { 3163 - ret = msi_setup_remapped_irq(dev, irq, index, 3164 - sub_handle); 3165 - if (ret < 0) 3166 - goto error; 3167 - } 3168 - no_ir: 3218 + irq_want = irq + 1; 3219 + 3169 3220 ret = setup_msi_irq(dev, msidesc, irq, 0); 3170 3221 if (ret < 0) 3171 3222 goto error; 3172 - sub_handle++; 3173 3223 } 3174 3224 return 0; 3175 3225 3176 3226 error: 3177 3227 destroy_irq(irq); 3178 3228 return ret; 3179 - } 3180 - 3181 - int setup_msi_irqs(struct pci_dev *dev, int nvec) 3182 - { 3183 - int node, ret, sub_handle, index = 0; 3184 - unsigned int irq; 3185 - struct msi_desc *msidesc; 3186 - 3187 - if (nvec > 1 && !irq_remapping_enabled) 3188 - return 1; 3189 - 3190 - nvec = __roundup_pow_of_two(nvec); 3191 - 3192 - WARN_ON(!list_is_singular(&dev->msi_list)); 3193 - msidesc = list_entry(dev->msi_list.next, struct msi_desc, list); 3194 - WARN_ON(msidesc->irq); 3195 - WARN_ON(msidesc->msi_attrib.multiple); 3196 - 3197 - node = dev_to_node(&dev->dev); 3198 - irq = __create_irqs(nr_irqs_gsi, nvec, node); 3199 - if (irq == 0) 3200 - return -ENOSPC; 3201 - 3202 - if (!irq_remapping_enabled) { 3203 - ret = setup_msi_irq(dev, msidesc, irq, 0); 3204 - if (ret < 0) 3205 - goto error; 3206 - return 0; 3207 - } 3208 - 3209 - msidesc->msi_attrib.multiple = ilog2(nvec); 3210 - for (sub_handle = 0; sub_handle < nvec; sub_handle++) { 3211 - if (!sub_handle) { 3212 - index = msi_alloc_remapped_irq(dev, irq, nvec); 3213 - if (index < 0) { 3214 - ret = index; 3215 - goto error; 3216 - } 3217 - } else { 3218 - ret = msi_setup_remapped_irq(dev, irq + sub_handle, 3219 - index, sub_handle); 3220 - if (ret < 0) 3221 - goto error; 3222 - } 3223 - ret = setup_msi_irq(dev, msidesc, irq, sub_handle); 3224 - if (ret < 0) 3225 - goto error; 3226 - } 3227 - return 0; 3228 - 3229 - error: 3230 - destroy_irqs(irq, nvec); 3231 - 3232 - /* 3233 - * Restore altered MSI descriptor fields and prevent just destroyed 3234 - * IRQs from tearing down again in default_teardown_msi_irqs() 3235 - */ 3236 - msidesc->irq = 0; 3237 - msidesc->msi_attrib.multiple = 0; 3238 - 3239 - return ret; 3240 - } 3241 - 3242 - int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 3243 - { 3244 - if (type == PCI_CAP_ID_MSI) 3245 - return setup_msi_irqs(dev, nvec); 3246 - return setup_msix_irqs(dev, nvec); 3247 3229 } 3248 3230 3249 3231 void native_teardown_msi_irq(unsigned int irq) ··· 3249 3399 .irq_retrigger = ioapic_retrigger_irq, 3250 3400 }; 3251 3401 3252 - int arch_setup_hpet_msi(unsigned int irq, unsigned int id) 3402 + int default_setup_hpet_msi(unsigned int irq, unsigned int id) 3253 3403 { 3254 3404 struct irq_chip *chip = &hpet_msi_type; 3255 3405 struct msi_msg msg; 3256 3406 int ret; 3257 - 3258 - if (irq_remapping_enabled) { 3259 - ret = setup_hpet_msi_remapped(irq, id); 3260 - if (ret) 3261 - return ret; 3262 - } 3263 3407 3264 3408 ret = msi_compose_msg(NULL, irq, &msg, id); 3265 3409 if (ret < 0) ··· 3261 3417 3262 3418 hpet_msi_write(irq_get_handler_data(irq), &msg); 3263 3419 irq_set_status_flags(irq, IRQ_MOVE_PCNTXT); 3264 - if (irq_remapped(irq_get_chip_data(irq))) 3265 - irq_remap_modify_chip_defaults(chip); 3420 + setup_remapped_irq(irq, irq_get_chip_data(irq), chip); 3266 3421 3267 3422 irq_set_chip_and_handler_name(irq, chip, handle_edge_irq, "edge"); 3268 3423 return 0; ··· 3627 3784 else 3628 3785 mask = apic->target_cpus(); 3629 3786 3630 - if (irq_remapping_enabled) 3631 - set_remapped_irq_affinity(idata, mask, false); 3632 - else 3633 - ioapic_set_affinity(idata, mask, false); 3787 + x86_io_apic_ops.set_affinity(idata, mask, false); 3634 3788 } 3635 3789 3636 3790 }
+1 -1
arch/x86/kernel/hpet.c
··· 478 478 479 479 static int hpet_setup_msi_irq(unsigned int irq) 480 480 { 481 - if (arch_setup_hpet_msi(irq, hpet_blockid)) { 481 + if (x86_msi.setup_hpet_msi(irq, hpet_blockid)) { 482 482 destroy_irq(irq); 483 483 return -EINVAL; 484 484 }
+16 -8
arch/x86/kernel/x86_init.c
··· 19 19 #include <asm/time.h> 20 20 #include <asm/irq.h> 21 21 #include <asm/io_apic.h> 22 + #include <asm/hpet.h> 22 23 #include <asm/pat.h> 23 24 #include <asm/tsc.h> 24 25 #include <asm/iommu.h> ··· 112 111 113 112 EXPORT_SYMBOL_GPL(x86_platform); 114 113 struct x86_msi_ops x86_msi = { 115 - .setup_msi_irqs = native_setup_msi_irqs, 116 - .teardown_msi_irq = native_teardown_msi_irq, 117 - .teardown_msi_irqs = default_teardown_msi_irqs, 118 - .restore_msi_irqs = default_restore_msi_irqs, 114 + .setup_msi_irqs = native_setup_msi_irqs, 115 + .compose_msi_msg = native_compose_msi_msg, 116 + .teardown_msi_irq = native_teardown_msi_irq, 117 + .teardown_msi_irqs = default_teardown_msi_irqs, 118 + .restore_msi_irqs = default_restore_msi_irqs, 119 + .setup_hpet_msi = default_setup_hpet_msi, 119 120 }; 120 121 121 122 struct x86_io_apic_ops x86_io_apic_ops = { 122 - .init = native_io_apic_init_mappings, 123 - .read = native_io_apic_read, 124 - .write = native_io_apic_write, 125 - .modify = native_io_apic_modify, 123 + .init = native_io_apic_init_mappings, 124 + .read = native_io_apic_read, 125 + .write = native_io_apic_write, 126 + .modify = native_io_apic_modify, 127 + .disable = native_disable_io_apic, 128 + .print_entries = native_io_apic_print_entries, 129 + .set_affinity = native_ioapic_set_affinity, 130 + .setup_entry = native_setup_ioapic_entry, 131 + .eoi_ioapic_pin = native_eoi_ioapic_pin, 126 132 };
+4 -4
drivers/iommu/amd_iommu.c
··· 4017 4017 4018 4018 index -= count - 1; 4019 4019 4020 + cfg->remapped = 1; 4020 4021 irte_info = &cfg->irq_2_iommu; 4021 4022 irte_info->sub_handle = devid; 4022 4023 irte_info->irte_index = index; 4023 - irte_info->iommu = (void *)cfg; 4024 4024 4025 4025 goto out; 4026 4026 } ··· 4127 4127 index = attr->ioapic_pin; 4128 4128 4129 4129 /* Setup IRQ remapping info */ 4130 + cfg->remapped = 1; 4130 4131 irte_info->sub_handle = devid; 4131 4132 irte_info->irte_index = index; 4132 - irte_info->iommu = (void *)cfg; 4133 4133 4134 4134 /* Setup IRTE for IOMMU */ 4135 4135 irte.val = 0; ··· 4288 4288 devid = get_device_id(&pdev->dev); 4289 4289 irte_info = &cfg->irq_2_iommu; 4290 4290 4291 + cfg->remapped = 1; 4291 4292 irte_info->sub_handle = devid; 4292 4293 irte_info->irte_index = index + offset; 4293 - irte_info->iommu = (void *)cfg; 4294 4294 4295 4295 return 0; 4296 4296 } ··· 4314 4314 if (index < 0) 4315 4315 return index; 4316 4316 4317 + cfg->remapped = 1; 4317 4318 irte_info->sub_handle = devid; 4318 4319 irte_info->irte_index = index; 4319 - irte_info->iommu = (void *)cfg; 4320 4320 4321 4321 return 0; 4322 4322 }
+2
drivers/iommu/dmar.c
··· 41 41 #include <asm/irq_remapping.h> 42 42 #include <asm/iommu_table.h> 43 43 44 + #include "irq_remapping.h" 45 + 44 46 /* No locks are needed as DMA remapping hardware unit 45 47 * list is constructed at boot time and hotplug of 46 48 * these units are not supported by the architecture.
+2
drivers/iommu/intel-iommu.c
··· 46 46 #include <asm/cacheflush.h> 47 47 #include <asm/iommu.h> 48 48 49 + #include "irq_remapping.h" 50 + 49 51 #define ROOT_SIZE VTD_PAGE_SIZE 50 52 #define CONTEXT_SIZE VTD_PAGE_SIZE 51 53
+12
drivers/iommu/intel_irq_remapping.c
··· 68 68 { 69 69 struct ir_table *table = iommu->ir_table; 70 70 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); 71 + struct irq_cfg *cfg = irq_get_chip_data(irq); 71 72 u16 index, start_index; 72 73 unsigned int mask = 0; 73 74 unsigned long flags; ··· 116 115 for (i = index; i < index + count; i++) 117 116 table->base[i].present = 1; 118 117 118 + cfg->remapped = 1; 119 119 irq_iommu->iommu = iommu; 120 120 irq_iommu->irte_index = index; 121 121 irq_iommu->sub_handle = 0; ··· 157 155 static int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) 158 156 { 159 157 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); 158 + struct irq_cfg *cfg = irq_get_chip_data(irq); 160 159 unsigned long flags; 161 160 162 161 if (!irq_iommu) ··· 165 162 166 163 raw_spin_lock_irqsave(&irq_2_ir_lock, flags); 167 164 165 + cfg->remapped = 1; 168 166 irq_iommu->iommu = iommu; 169 167 irq_iommu->irte_index = index; 170 168 irq_iommu->sub_handle = subhandle; ··· 621 617 goto error; 622 618 623 619 irq_remapping_enabled = 1; 620 + 621 + /* 622 + * VT-d has a different layout for IO-APIC entries when 623 + * interrupt remapping is enabled. So it needs a special routine 624 + * to print IO-APIC entries for debugging purposes too. 625 + */ 626 + x86_io_apic_ops.print_entries = intel_ir_io_apic_print_entries; 627 + 624 628 pr_info("Enabled IRQ remapping in %s mode\n", eim ? "x2apic" : "xapic"); 625 629 626 630 return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE;
+221 -10
drivers/iommu/irq_remapping.c
··· 1 + #include <linux/seq_file.h> 2 + #include <linux/cpumask.h> 1 3 #include <linux/kernel.h> 2 4 #include <linux/string.h> 3 5 #include <linux/cpumask.h> 4 6 #include <linux/errno.h> 5 7 #include <linux/msi.h> 8 + #include <linux/irq.h> 9 + #include <linux/pci.h> 6 10 7 11 #include <asm/hw_irq.h> 8 12 #include <asm/irq_remapping.h> 13 + #include <asm/processor.h> 14 + #include <asm/x86_init.h> 15 + #include <asm/apic.h> 9 16 10 17 #include "irq_remapping.h" 11 18 ··· 23 16 int no_x2apic_optout; 24 17 25 18 static struct irq_remap_ops *remap_ops; 19 + 20 + static int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec); 21 + static int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq, 22 + int index, int sub_handle); 23 + static int set_remapped_irq_affinity(struct irq_data *data, 24 + const struct cpumask *mask, 25 + bool force); 26 + 27 + static bool irq_remapped(struct irq_cfg *cfg) 28 + { 29 + return (cfg->remapped == 1); 30 + } 31 + 32 + static void irq_remapping_disable_io_apic(void) 33 + { 34 + /* 35 + * With interrupt-remapping, for now we will use virtual wire A 36 + * mode, as virtual wire B is little complex (need to configure 37 + * both IOAPIC RTE as well as interrupt-remapping table entry). 38 + * As this gets called during crash dump, keep this simple for 39 + * now. 40 + */ 41 + if (cpu_has_apic || apic_from_smp_config()) 42 + disconnect_bsp_APIC(0); 43 + } 44 + 45 + static int do_setup_msi_irqs(struct pci_dev *dev, int nvec) 46 + { 47 + int node, ret, sub_handle, index = 0; 48 + unsigned int irq; 49 + struct msi_desc *msidesc; 50 + 51 + nvec = __roundup_pow_of_two(nvec); 52 + 53 + WARN_ON(!list_is_singular(&dev->msi_list)); 54 + msidesc = list_entry(dev->msi_list.next, struct msi_desc, list); 55 + WARN_ON(msidesc->irq); 56 + WARN_ON(msidesc->msi_attrib.multiple); 57 + 58 + node = dev_to_node(&dev->dev); 59 + irq = __create_irqs(get_nr_irqs_gsi(), nvec, node); 60 + if (irq == 0) 61 + return -ENOSPC; 62 + 63 + msidesc->msi_attrib.multiple = ilog2(nvec); 64 + for (sub_handle = 0; sub_handle < nvec; sub_handle++) { 65 + if (!sub_handle) { 66 + index = msi_alloc_remapped_irq(dev, irq, nvec); 67 + if (index < 0) { 68 + ret = index; 69 + goto error; 70 + } 71 + } else { 72 + ret = msi_setup_remapped_irq(dev, irq + sub_handle, 73 + index, sub_handle); 74 + if (ret < 0) 75 + goto error; 76 + } 77 + ret = setup_msi_irq(dev, msidesc, irq, sub_handle); 78 + if (ret < 0) 79 + goto error; 80 + } 81 + return 0; 82 + 83 + error: 84 + destroy_irqs(irq, nvec); 85 + 86 + /* 87 + * Restore altered MSI descriptor fields and prevent just destroyed 88 + * IRQs from tearing down again in default_teardown_msi_irqs() 89 + */ 90 + msidesc->irq = 0; 91 + msidesc->msi_attrib.multiple = 0; 92 + 93 + return ret; 94 + } 95 + 96 + static int do_setup_msix_irqs(struct pci_dev *dev, int nvec) 97 + { 98 + int node, ret, sub_handle, index = 0; 99 + struct msi_desc *msidesc; 100 + unsigned int irq; 101 + 102 + node = dev_to_node(&dev->dev); 103 + irq = get_nr_irqs_gsi(); 104 + sub_handle = 0; 105 + 106 + list_for_each_entry(msidesc, &dev->msi_list, list) { 107 + 108 + irq = create_irq_nr(irq, node); 109 + if (irq == 0) 110 + return -1; 111 + 112 + if (sub_handle == 0) 113 + ret = index = msi_alloc_remapped_irq(dev, irq, nvec); 114 + else 115 + ret = msi_setup_remapped_irq(dev, irq, index, sub_handle); 116 + 117 + if (ret < 0) 118 + goto error; 119 + 120 + ret = setup_msi_irq(dev, msidesc, irq, 0); 121 + if (ret < 0) 122 + goto error; 123 + 124 + sub_handle += 1; 125 + irq += 1; 126 + } 127 + 128 + return 0; 129 + 130 + error: 131 + destroy_irq(irq); 132 + return ret; 133 + } 134 + 135 + static int irq_remapping_setup_msi_irqs(struct pci_dev *dev, 136 + int nvec, int type) 137 + { 138 + if (type == PCI_CAP_ID_MSI) 139 + return do_setup_msi_irqs(dev, nvec); 140 + else 141 + return do_setup_msix_irqs(dev, nvec); 142 + } 143 + 144 + void eoi_ioapic_pin_remapped(int apic, int pin, int vector) 145 + { 146 + /* 147 + * Intr-remapping uses pin number as the virtual vector 148 + * in the RTE. Actual vector is programmed in 149 + * intr-remapping table entry. Hence for the io-apic 150 + * EOI we use the pin number. 151 + */ 152 + io_apic_eoi(apic, pin); 153 + } 154 + 155 + static void __init irq_remapping_modify_x86_ops(void) 156 + { 157 + x86_io_apic_ops.disable = irq_remapping_disable_io_apic; 158 + x86_io_apic_ops.set_affinity = set_remapped_irq_affinity; 159 + x86_io_apic_ops.setup_entry = setup_ioapic_remapped_entry; 160 + x86_io_apic_ops.eoi_ioapic_pin = eoi_ioapic_pin_remapped; 161 + x86_msi.setup_msi_irqs = irq_remapping_setup_msi_irqs; 162 + x86_msi.setup_hpet_msi = setup_hpet_msi_remapped; 163 + x86_msi.compose_msi_msg = compose_remapped_msi_msg; 164 + } 26 165 27 166 static __init int setup_nointremap(char *str) 28 167 { ··· 232 79 233 80 int __init irq_remapping_enable(void) 234 81 { 82 + int ret; 83 + 235 84 if (!remap_ops || !remap_ops->enable) 236 85 return -ENODEV; 237 86 238 - return remap_ops->enable(); 87 + ret = remap_ops->enable(); 88 + 89 + if (irq_remapping_enabled) 90 + irq_remapping_modify_x86_ops(); 91 + 92 + return ret; 239 93 } 240 94 241 95 void irq_remapping_disable(void) 242 96 { 243 - if (!remap_ops || !remap_ops->disable) 97 + if (!irq_remapping_enabled || 98 + !remap_ops || 99 + !remap_ops->disable) 244 100 return; 245 101 246 102 remap_ops->disable(); ··· 257 95 258 96 int irq_remapping_reenable(int mode) 259 97 { 260 - if (!remap_ops || !remap_ops->reenable) 98 + if (!irq_remapping_enabled || 99 + !remap_ops || 100 + !remap_ops->reenable) 261 101 return 0; 262 102 263 103 return remap_ops->reenable(mode); ··· 267 103 268 104 int __init irq_remap_enable_fault_handling(void) 269 105 { 106 + if (!irq_remapping_enabled) 107 + return 0; 108 + 270 109 if (!remap_ops || !remap_ops->enable_faulting) 271 110 return -ENODEV; 272 111 ··· 300 133 301 134 void free_remapped_irq(int irq) 302 135 { 136 + struct irq_cfg *cfg = irq_get_chip_data(irq); 137 + 303 138 if (!remap_ops || !remap_ops->free_irq) 304 139 return; 305 140 306 - remap_ops->free_irq(irq); 141 + if (irq_remapped(cfg)) 142 + remap_ops->free_irq(irq); 307 143 } 308 144 309 145 void compose_remapped_msi_msg(struct pci_dev *pdev, 310 146 unsigned int irq, unsigned int dest, 311 147 struct msi_msg *msg, u8 hpet_id) 312 148 { 313 - if (!remap_ops || !remap_ops->compose_msi_msg) 314 - return; 149 + struct irq_cfg *cfg = irq_get_chip_data(irq); 315 150 316 - remap_ops->compose_msi_msg(pdev, irq, dest, msg, hpet_id); 151 + if (!irq_remapped(cfg)) 152 + native_compose_msi_msg(pdev, irq, dest, msg, hpet_id); 153 + else if (remap_ops && remap_ops->compose_msi_msg) 154 + remap_ops->compose_msi_msg(pdev, irq, dest, msg, hpet_id); 317 155 } 318 156 319 - int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec) 157 + static int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec) 320 158 { 321 159 if (!remap_ops || !remap_ops->msi_alloc_irq) 322 160 return -ENODEV; ··· 329 157 return remap_ops->msi_alloc_irq(pdev, irq, nvec); 330 158 } 331 159 332 - int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq, 333 - int index, int sub_handle) 160 + static int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq, 161 + int index, int sub_handle) 334 162 { 335 163 if (!remap_ops || !remap_ops->msi_setup_irq) 336 164 return -ENODEV; ··· 344 172 return -ENODEV; 345 173 346 174 return remap_ops->setup_hpet_msi(irq, id); 175 + } 176 + 177 + void panic_if_irq_remap(const char *msg) 178 + { 179 + if (irq_remapping_enabled) 180 + panic(msg); 181 + } 182 + 183 + static void ir_ack_apic_edge(struct irq_data *data) 184 + { 185 + ack_APIC_irq(); 186 + } 187 + 188 + static void ir_ack_apic_level(struct irq_data *data) 189 + { 190 + ack_APIC_irq(); 191 + eoi_ioapic_irq(data->irq, data->chip_data); 192 + } 193 + 194 + static void ir_print_prefix(struct irq_data *data, struct seq_file *p) 195 + { 196 + seq_printf(p, " IR-%s", data->chip->name); 197 + } 198 + 199 + void irq_remap_modify_chip_defaults(struct irq_chip *chip) 200 + { 201 + chip->irq_print_chip = ir_print_prefix; 202 + chip->irq_ack = ir_ack_apic_edge; 203 + chip->irq_eoi = ir_ack_apic_level; 204 + chip->irq_set_affinity = x86_io_apic_ops.set_affinity; 205 + } 206 + 207 + bool setup_remapped_irq(int irq, struct irq_cfg *cfg, struct irq_chip *chip) 208 + { 209 + if (!irq_remapped(cfg)) 210 + return false; 211 + irq_set_status_flags(irq, IRQ_MOVE_PCNTXT); 212 + irq_remap_modify_chip_defaults(chip); 213 + return true; 347 214 }
+1
drivers/iommu/irq_remapping.h
··· 34 34 extern int disable_irq_remap; 35 35 extern int disable_sourceid_checking; 36 36 extern int no_x2apic_optout; 37 + extern int irq_remapping_enabled; 37 38 38 39 struct irq_remap_ops { 39 40 /* Check whether Interrupt Remapping is supported */
+3
include/linux/irq.h
··· 509 509 510 510 /* Handle dynamic irq creation and destruction */ 511 511 extern unsigned int create_irq_nr(unsigned int irq_want, int node); 512 + extern unsigned int __create_irqs(unsigned int from, unsigned int count, 513 + int node); 512 514 extern int create_irq(void); 513 515 extern void destroy_irq(unsigned int irq); 516 + extern void destroy_irqs(unsigned int irq, unsigned int count); 514 517 515 518 /* 516 519 * Dynamic irq helper functions. Obsolete. Use irq_alloc_desc* and