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

Merge branch 'core-iommu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull iommu core changes from Ingo Molnar:
"The IOMMU changes in this cycle are mostly about factoring out
Intel-VT-d specific IRQ remapping details and introducing struct
irq_remap_ops, in preparation for AMD specific hardware."

* 'core-iommu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
iommu: Fix off by one in dmar_get_fault_reason()
irq_remap: Fix the 'sub_handle' uninitialized warning
irq_remap: Fix UP build failure
irq_remap: Fix compiler warning with CONFIG_IRQ_REMAP=y
iommu: rename intr_remapping.[ch] to irq_remapping.[ch]
iommu: rename intr_remapping references to irq_remapping
x86, iommu/vt-d: Clean up interfaces for interrupt remapping
iommu/vt-d: Convert MSI remapping setup to remap_ops
iommu/vt-d: Convert free_irte into a remap_ops callback
iommu/vt-d: Convert IR set_affinity function to remap_ops
iommu/vt-d: Convert IR ioapic-setup to use remap_ops
iommu/vt-d: Convert missing apic.c intr-remapping call to remap_ops
iommu/vt-d: Make intr-remapping initialization generic
iommu: Rename intr_remapping files to intel_intr_remapping

+744 -464
+4
arch/ia64/include/asm/irq_remapping.h
··· 1 + #ifndef __IA64_INTR_REMAPPING_H 2 + #define __IA64_INTR_REMAPPING_H 3 + #define irq_remapping_enabled 0 4 + #endif
+96 -40
arch/x86/include/asm/irq_remapping.h
··· 1 - #ifndef _ASM_X86_IRQ_REMAPPING_H 2 - #define _ASM_X86_IRQ_REMAPPING_H 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 + */ 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 27 #ifdef CONFIG_IRQ_REMAP 7 - static void irq_remap_modify_chip_defaults(struct irq_chip *chip); 8 - static inline void prepare_irte(struct irte *irte, int vector, 9 - unsigned int dest) 10 - { 11 - memset(irte, 0, sizeof(*irte)); 12 28 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 - } 28 - static inline bool irq_remapped(struct irq_cfg *cfg) 29 - { 30 - return cfg->irq_2_iommu.iommu != NULL; 31 - } 32 - #else 33 - static void prepare_irte(struct irte *irte, int vector, unsigned int dest) 34 - { 35 - } 36 - static inline bool irq_remapped(struct irq_cfg *cfg) 37 - { 38 - return false; 39 - } 40 - static inline void irq_remap_modify_chip_defaults(struct irq_chip *chip) 41 - { 42 - } 43 - #endif 29 + extern int irq_remapping_enabled; 44 30 45 - #endif /* _ASM_X86_IRQ_REMAPPING_H */ 31 + extern void setup_irq_remapping_ops(void); 32 + extern int irq_remapping_supported(void); 33 + extern int irq_remapping_prepare(void); 34 + extern int irq_remapping_enable(void); 35 + extern void irq_remapping_disable(void); 36 + extern int irq_remapping_reenable(int); 37 + extern int irq_remap_enable_fault_handling(void); 38 + extern 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); 43 + extern int set_remapped_irq_affinity(struct irq_data *data, 44 + const struct cpumask *mask, 45 + bool force); 46 + extern void free_remapped_irq(int irq); 47 + extern void compose_remapped_msi_msg(struct pci_dev *pdev, 48 + unsigned int irq, unsigned int dest, 49 + struct msi_msg *msg, u8 hpet_id); 50 + extern int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec); 51 + extern int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq, 52 + int index, int sub_handle); 53 + extern 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 + 59 + static inline void setup_irq_remapping_ops(void) { } 60 + static inline int irq_remapping_supported(void) { return 0; } 61 + static inline int irq_remapping_prepare(void) { return -ENODEV; } 62 + static inline int irq_remapping_enable(void) { return -ENODEV; } 63 + static inline void irq_remapping_disable(void) { } 64 + static inline int irq_remapping_reenable(int eim) { return -ENODEV; } 65 + static inline int irq_remap_enable_fault_handling(void) { return -ENODEV; } 66 + static 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 + } 74 + static inline int set_remapped_irq_affinity(struct irq_data *data, 75 + const struct cpumask *mask, 76 + bool force) 77 + { 78 + return 0; 79 + } 80 + static inline void free_remapped_irq(int irq) { } 81 + static 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) 84 + { 85 + } 86 + static inline int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec) 87 + { 88 + return -ENODEV; 89 + } 90 + static inline int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq, 91 + int index, int sub_handle) 92 + { 93 + return -ENODEV; 94 + } 95 + static inline int setup_hpet_msi_remapped(unsigned int irq, unsigned int id) 96 + { 97 + return -ENODEV; 98 + } 99 + #endif /* CONFIG_IRQ_REMAP */ 100 + 101 + #endif /* __X86_IRQ_REMAPPING_H */
+17 -13
arch/x86/kernel/apic/apic.c
··· 35 35 #include <linux/smp.h> 36 36 #include <linux/mm.h> 37 37 38 + #include <asm/irq_remapping.h> 38 39 #include <asm/perf_event.h> 39 40 #include <asm/x86_init.h> 40 41 #include <asm/pgalloc.h> ··· 1442 1441 * Now that local APIC setup is completed for BP, configure the fault 1443 1442 * handling for interrupt remapping. 1444 1443 */ 1445 - if (intr_remapping_enabled) 1446 - enable_drhd_fault_handling(); 1444 + if (irq_remapping_enabled) 1445 + irq_remap_enable_fault_handling(); 1447 1446 1448 1447 } 1449 1448 ··· 1518 1517 int __init enable_IR(void) 1519 1518 { 1520 1519 #ifdef CONFIG_IRQ_REMAP 1521 - if (!intr_remapping_supported()) { 1520 + if (!irq_remapping_supported()) { 1522 1521 pr_debug("intr-remapping not supported\n"); 1523 1522 return -1; 1524 1523 } ··· 1529 1528 return -1; 1530 1529 } 1531 1530 1532 - return enable_intr_remapping(); 1531 + return irq_remapping_enable(); 1533 1532 #endif 1534 1533 return -1; 1535 1534 } ··· 1538 1537 { 1539 1538 unsigned long flags; 1540 1539 int ret, x2apic_enabled = 0; 1541 - int dmar_table_init_ret; 1540 + int hardware_init_ret; 1542 1541 1543 - dmar_table_init_ret = dmar_table_init(); 1544 - if (dmar_table_init_ret && !x2apic_supported()) 1542 + /* Make sure irq_remap_ops are initialized */ 1543 + setup_irq_remapping_ops(); 1544 + 1545 + hardware_init_ret = irq_remapping_prepare(); 1546 + if (hardware_init_ret && !x2apic_supported()) 1545 1547 return; 1546 1548 1547 1549 ret = save_ioapic_entries(); ··· 1560 1556 if (x2apic_preenabled && nox2apic) 1561 1557 disable_x2apic(); 1562 1558 1563 - if (dmar_table_init_ret) 1559 + if (hardware_init_ret) 1564 1560 ret = -1; 1565 1561 else 1566 1562 ret = enable_IR(); ··· 2180 2176 local_irq_save(flags); 2181 2177 disable_local_APIC(); 2182 2178 2183 - if (intr_remapping_enabled) 2184 - disable_intr_remapping(); 2179 + if (irq_remapping_enabled) 2180 + irq_remapping_disable(); 2185 2181 2186 2182 local_irq_restore(flags); 2187 2183 return 0; ··· 2197 2193 return; 2198 2194 2199 2195 local_irq_save(flags); 2200 - if (intr_remapping_enabled) { 2196 + if (irq_remapping_enabled) { 2201 2197 /* 2202 2198 * IO-APIC and PIC have their own resume routines. 2203 2199 * We just mask them here to make sure the interrupt ··· 2249 2245 apic_write(APIC_ESR, 0); 2250 2246 apic_read(APIC_ESR); 2251 2247 2252 - if (intr_remapping_enabled) 2253 - reenable_intr_remapping(x2apic_mode); 2248 + if (irq_remapping_enabled) 2249 + irq_remapping_reenable(x2apic_mode); 2254 2250 2255 2251 local_irq_restore(flags); 2256 2252 }
+64 -239
arch/x86/kernel/apic/io_apic.c
··· 86 86 io_apic_ops = *ops; 87 87 } 88 88 89 + #ifdef CONFIG_IRQ_REMAP 90 + static void irq_remap_modify_chip_defaults(struct irq_chip *chip); 91 + static inline bool irq_remapped(struct irq_cfg *cfg) 92 + { 93 + return cfg->irq_2_iommu.iommu != NULL; 94 + } 95 + #else 96 + static inline bool irq_remapped(struct irq_cfg *cfg) 97 + { 98 + return false; 99 + } 100 + static inline void irq_remap_modify_chip_defaults(struct irq_chip *chip) 101 + { 102 + } 103 + #endif 104 + 89 105 /* 90 106 * Is the SiS APIC rmw bug present ? 91 107 * -1 = don't know, 0 = no, 1 = yes ··· 1377 1361 fasteoi ? "fasteoi" : "edge"); 1378 1362 } 1379 1363 1380 - 1381 - static int setup_ir_ioapic_entry(int irq, 1382 - struct IR_IO_APIC_route_entry *entry, 1383 - unsigned int destination, int vector, 1384 - struct io_apic_irq_attr *attr) 1385 - { 1386 - int index; 1387 - struct irte irte; 1388 - int ioapic_id = mpc_ioapic_id(attr->ioapic); 1389 - struct intel_iommu *iommu = map_ioapic_to_ir(ioapic_id); 1390 - 1391 - if (!iommu) { 1392 - pr_warn("No mapping iommu for ioapic %d\n", ioapic_id); 1393 - return -ENODEV; 1394 - } 1395 - 1396 - index = alloc_irte(iommu, irq, 1); 1397 - if (index < 0) { 1398 - pr_warn("Failed to allocate IRTE for ioapic %d\n", ioapic_id); 1399 - return -ENOMEM; 1400 - } 1401 - 1402 - prepare_irte(&irte, vector, destination); 1403 - 1404 - /* Set source-id of interrupt request */ 1405 - set_ioapic_sid(&irte, ioapic_id); 1406 - 1407 - modify_irte(irq, &irte); 1408 - 1409 - apic_printk(APIC_VERBOSE, KERN_DEBUG "IOAPIC[%d]: " 1410 - "Set IRTE entry (P:%d FPD:%d Dst_Mode:%d " 1411 - "Redir_hint:%d Trig_Mode:%d Dlvry_Mode:%X " 1412 - "Avail:%X Vector:%02X Dest:%08X " 1413 - "SID:%04X SQ:%X SVT:%X)\n", 1414 - attr->ioapic, irte.present, irte.fpd, irte.dst_mode, 1415 - irte.redir_hint, irte.trigger_mode, irte.dlvry_mode, 1416 - irte.avail, irte.vector, irte.dest_id, 1417 - irte.sid, irte.sq, irte.svt); 1418 - 1419 - memset(entry, 0, sizeof(*entry)); 1420 - 1421 - entry->index2 = (index >> 15) & 0x1; 1422 - entry->zero = 0; 1423 - entry->format = 1; 1424 - entry->index = (index & 0x7fff); 1425 - /* 1426 - * IO-APIC RTE will be configured with virtual vector. 1427 - * irq handler will do the explicit EOI to the io-apic. 1428 - */ 1429 - entry->vector = attr->ioapic_pin; 1430 - entry->mask = 0; /* enable IRQ */ 1431 - entry->trigger = attr->trigger; 1432 - entry->polarity = attr->polarity; 1433 - 1434 - /* Mask level triggered irqs. 1435 - * Use IRQ_DELAYED_DISABLE for edge triggered irqs. 1436 - */ 1437 - if (attr->trigger) 1438 - entry->mask = 1; 1439 - 1440 - return 0; 1441 - } 1442 - 1443 1364 static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry, 1444 1365 unsigned int destination, int vector, 1445 1366 struct io_apic_irq_attr *attr) 1446 1367 { 1447 - if (intr_remapping_enabled) 1448 - return setup_ir_ioapic_entry(irq, 1449 - (struct IR_IO_APIC_route_entry *)entry, 1450 - destination, vector, attr); 1368 + if (irq_remapping_enabled) 1369 + return setup_ioapic_remapped_entry(irq, entry, destination, 1370 + vector, attr); 1451 1371 1452 1372 memset(entry, 0, sizeof(*entry)); 1453 1373 ··· 1540 1588 { 1541 1589 struct IO_APIC_route_entry entry; 1542 1590 1543 - if (intr_remapping_enabled) 1591 + if (irq_remapping_enabled) 1544 1592 return; 1545 1593 1546 1594 memset(&entry, 0, sizeof(entry)); ··· 1626 1674 1627 1675 printk(KERN_DEBUG ".... IRQ redirection table:\n"); 1628 1676 1629 - if (intr_remapping_enabled) { 1677 + if (irq_remapping_enabled) { 1630 1678 printk(KERN_DEBUG " NR Indx Fmt Mask Trig IRR" 1631 1679 " Pol Stat Indx2 Zero Vect:\n"); 1632 1680 } else { ··· 1635 1683 } 1636 1684 1637 1685 for (i = 0; i <= reg_01.bits.entries; i++) { 1638 - if (intr_remapping_enabled) { 1686 + if (irq_remapping_enabled) { 1639 1687 struct IO_APIC_route_entry entry; 1640 1688 struct IR_IO_APIC_route_entry *ir_entry; 1641 1689 ··· 2002 2050 * IOAPIC RTE as well as interrupt-remapping table entry). 2003 2051 * As this gets called during crash dump, keep this simple for now. 2004 2052 */ 2005 - if (ioapic_i8259.pin != -1 && !intr_remapping_enabled) { 2053 + if (ioapic_i8259.pin != -1 && !irq_remapping_enabled) { 2006 2054 struct IO_APIC_route_entry entry; 2007 2055 2008 2056 memset(&entry, 0, sizeof(entry)); ··· 2026 2074 * Use virtual wire A mode when interrupt remapping is enabled. 2027 2075 */ 2028 2076 if (cpu_has_apic || apic_from_smp_config()) 2029 - disconnect_bsp_APIC(!intr_remapping_enabled && 2077 + disconnect_bsp_APIC(!irq_remapping_enabled && 2030 2078 ioapic_i8259.pin != -1); 2031 2079 } 2032 2080 ··· 2342 2390 return ret; 2343 2391 } 2344 2392 2345 - #ifdef CONFIG_IRQ_REMAP 2346 - 2347 - /* 2348 - * Migrate the IO-APIC irq in the presence of intr-remapping. 2349 - * 2350 - * For both level and edge triggered, irq migration is a simple atomic 2351 - * update(of vector and cpu destination) of IRTE and flush the hardware cache. 2352 - * 2353 - * For level triggered, we eliminate the io-apic RTE modification (with the 2354 - * updated vector information), by using a virtual vector (io-apic pin number). 2355 - * Real vector that is used for interrupting cpu will be coming from 2356 - * the interrupt-remapping table entry. 2357 - * 2358 - * As the migration is a simple atomic update of IRTE, the same mechanism 2359 - * is used to migrate MSI irq's in the presence of interrupt-remapping. 2360 - */ 2361 - static int 2362 - ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, 2363 - bool force) 2364 - { 2365 - struct irq_cfg *cfg = data->chip_data; 2366 - unsigned int dest, irq = data->irq; 2367 - struct irte irte; 2368 - 2369 - if (!cpumask_intersects(mask, cpu_online_mask)) 2370 - return -EINVAL; 2371 - 2372 - if (get_irte(irq, &irte)) 2373 - return -EBUSY; 2374 - 2375 - if (assign_irq_vector(irq, cfg, mask)) 2376 - return -EBUSY; 2377 - 2378 - dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask); 2379 - 2380 - irte.vector = cfg->vector; 2381 - irte.dest_id = IRTE_DEST(dest); 2382 - 2383 - /* 2384 - * Atomically updates the IRTE with the new destination, vector 2385 - * and flushes the interrupt entry cache. 2386 - */ 2387 - modify_irte(irq, &irte); 2388 - 2389 - /* 2390 - * After this point, all the interrupts will start arriving 2391 - * at the new destination. So, time to cleanup the previous 2392 - * vector allocation. 2393 - */ 2394 - if (cfg->move_in_progress) 2395 - send_cleanup_vector(cfg); 2396 - 2397 - cpumask_copy(data->affinity, mask); 2398 - return 0; 2399 - } 2400 - 2401 - #else 2402 - static inline int 2403 - ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, 2404 - bool force) 2405 - { 2406 - return 0; 2407 - } 2408 - #endif 2409 - 2410 2393 asmlinkage void smp_irq_move_cleanup_interrupt(void) 2411 2394 { 2412 2395 unsigned vector, me; ··· 2586 2699 chip->irq_eoi = ir_ack_apic_level; 2587 2700 2588 2701 #ifdef CONFIG_SMP 2589 - chip->irq_set_affinity = ir_ioapic_set_affinity; 2702 + chip->irq_set_affinity = set_remapped_irq_affinity; 2590 2703 #endif 2591 2704 } 2592 2705 #endif /* CONFIG_IRQ_REMAP */ ··· 2799 2912 * 8259A. 2800 2913 */ 2801 2914 if (pin1 == -1) { 2802 - if (intr_remapping_enabled) 2915 + if (irq_remapping_enabled) 2803 2916 panic("BIOS bug: timer not connected to IO-APIC"); 2804 2917 pin1 = pin2; 2805 2918 apic1 = apic2; ··· 2832 2945 clear_IO_APIC_pin(0, pin1); 2833 2946 goto out; 2834 2947 } 2835 - if (intr_remapping_enabled) 2948 + if (irq_remapping_enabled) 2836 2949 panic("timer doesn't work through Interrupt-remapped IO-APIC"); 2837 2950 local_irq_disable(); 2838 2951 clear_IO_APIC_pin(apic1, pin1); ··· 3056 3169 irq_set_status_flags(irq, IRQ_NOREQUEST|IRQ_NOPROBE); 3057 3170 3058 3171 if (irq_remapped(cfg)) 3059 - free_irte(irq); 3172 + free_remapped_irq(irq); 3060 3173 raw_spin_lock_irqsave(&vector_lock, flags); 3061 3174 __clear_irq_vector(irq, cfg); 3062 3175 raw_spin_unlock_irqrestore(&vector_lock, flags); ··· 3085 3198 dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); 3086 3199 3087 3200 if (irq_remapped(cfg)) { 3088 - struct irte irte; 3089 - int ir_index; 3090 - u16 sub_handle; 3091 - 3092 - ir_index = map_irq_to_irte_handle(irq, &sub_handle); 3093 - BUG_ON(ir_index == -1); 3094 - 3095 - prepare_irte(&irte, cfg->vector, dest); 3096 - 3097 - /* Set source-id of interrupt request */ 3098 - if (pdev) 3099 - set_msi_sid(&irte, pdev); 3100 - else 3101 - set_hpet_sid(&irte, hpet_id); 3102 - 3103 - modify_irte(irq, &irte); 3104 - 3105 - msg->address_hi = MSI_ADDR_BASE_HI; 3106 - msg->data = sub_handle; 3107 - msg->address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_IR_EXT_INT | 3108 - MSI_ADDR_IR_SHV | 3109 - MSI_ADDR_IR_INDEX1(ir_index) | 3110 - MSI_ADDR_IR_INDEX2(ir_index); 3111 - } else { 3112 - if (x2apic_enabled()) 3113 - msg->address_hi = MSI_ADDR_BASE_HI | 3114 - MSI_ADDR_EXT_DEST_ID(dest); 3115 - else 3116 - msg->address_hi = MSI_ADDR_BASE_HI; 3117 - 3118 - msg->address_lo = 3119 - MSI_ADDR_BASE_LO | 3120 - ((apic->irq_dest_mode == 0) ? 3121 - MSI_ADDR_DEST_MODE_PHYSICAL: 3122 - MSI_ADDR_DEST_MODE_LOGICAL) | 3123 - ((apic->irq_delivery_mode != dest_LowestPrio) ? 3124 - MSI_ADDR_REDIRECTION_CPU: 3125 - MSI_ADDR_REDIRECTION_LOWPRI) | 3126 - MSI_ADDR_DEST_ID(dest); 3127 - 3128 - msg->data = 3129 - MSI_DATA_TRIGGER_EDGE | 3130 - MSI_DATA_LEVEL_ASSERT | 3131 - ((apic->irq_delivery_mode != dest_LowestPrio) ? 3132 - MSI_DATA_DELIVERY_FIXED: 3133 - MSI_DATA_DELIVERY_LOWPRI) | 3134 - MSI_DATA_VECTOR(cfg->vector); 3201 + compose_remapped_msi_msg(pdev, irq, dest, msg, hpet_id); 3202 + return err; 3135 3203 } 3204 + 3205 + if (x2apic_enabled()) 3206 + msg->address_hi = MSI_ADDR_BASE_HI | 3207 + MSI_ADDR_EXT_DEST_ID(dest); 3208 + else 3209 + msg->address_hi = MSI_ADDR_BASE_HI; 3210 + 3211 + msg->address_lo = 3212 + MSI_ADDR_BASE_LO | 3213 + ((apic->irq_dest_mode == 0) ? 3214 + MSI_ADDR_DEST_MODE_PHYSICAL: 3215 + MSI_ADDR_DEST_MODE_LOGICAL) | 3216 + ((apic->irq_delivery_mode != dest_LowestPrio) ? 3217 + MSI_ADDR_REDIRECTION_CPU: 3218 + MSI_ADDR_REDIRECTION_LOWPRI) | 3219 + MSI_ADDR_DEST_ID(dest); 3220 + 3221 + msg->data = 3222 + MSI_DATA_TRIGGER_EDGE | 3223 + MSI_DATA_LEVEL_ASSERT | 3224 + ((apic->irq_delivery_mode != dest_LowestPrio) ? 3225 + MSI_DATA_DELIVERY_FIXED: 3226 + MSI_DATA_DELIVERY_LOWPRI) | 3227 + MSI_DATA_VECTOR(cfg->vector); 3228 + 3136 3229 return err; 3137 3230 } 3138 3231 ··· 3155 3288 .irq_retrigger = ioapic_retrigger_irq, 3156 3289 }; 3157 3290 3158 - /* 3159 - * Map the PCI dev to the corresponding remapping hardware unit 3160 - * and allocate 'nvec' consecutive interrupt-remapping table entries 3161 - * in it. 3162 - */ 3163 - static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec) 3164 - { 3165 - struct intel_iommu *iommu; 3166 - int index; 3167 - 3168 - iommu = map_dev_to_ir(dev); 3169 - if (!iommu) { 3170 - printk(KERN_ERR 3171 - "Unable to map PCI %s to iommu\n", pci_name(dev)); 3172 - return -ENOENT; 3173 - } 3174 - 3175 - index = alloc_irte(iommu, irq, nvec); 3176 - if (index < 0) { 3177 - printk(KERN_ERR 3178 - "Unable to allocate %d IRTE for PCI %s\n", nvec, 3179 - pci_name(dev)); 3180 - return -ENOSPC; 3181 - } 3182 - return index; 3183 - } 3184 - 3185 3291 static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) 3186 3292 { 3187 3293 struct irq_chip *chip = &msi_chip; ··· 3185 3345 int node, ret, sub_handle, index = 0; 3186 3346 unsigned int irq, irq_want; 3187 3347 struct msi_desc *msidesc; 3188 - struct intel_iommu *iommu = NULL; 3189 3348 3190 3349 /* x86 doesn't support multiple MSI yet */ 3191 3350 if (type == PCI_CAP_ID_MSI && nvec > 1) ··· 3198 3359 if (irq == 0) 3199 3360 return -1; 3200 3361 irq_want = irq + 1; 3201 - if (!intr_remapping_enabled) 3362 + if (!irq_remapping_enabled) 3202 3363 goto no_ir; 3203 3364 3204 3365 if (!sub_handle) { ··· 3206 3367 * allocate the consecutive block of IRTE's 3207 3368 * for 'nvec' 3208 3369 */ 3209 - index = msi_alloc_irte(dev, irq, nvec); 3370 + index = msi_alloc_remapped_irq(dev, irq, nvec); 3210 3371 if (index < 0) { 3211 3372 ret = index; 3212 3373 goto error; 3213 3374 } 3214 3375 } else { 3215 - iommu = map_dev_to_ir(dev); 3216 - if (!iommu) { 3217 - ret = -ENOENT; 3376 + ret = msi_setup_remapped_irq(dev, irq, index, 3377 + sub_handle); 3378 + if (ret < 0) 3218 3379 goto error; 3219 - } 3220 - /* 3221 - * setup the mapping between the irq and the IRTE 3222 - * base index, the sub_handle pointing to the 3223 - * appropriate interrupt remap table entry. 3224 - */ 3225 - set_irte_irq(irq, iommu, index, sub_handle); 3226 3380 } 3227 3381 no_ir: 3228 3382 ret = setup_msi_irq(dev, msidesc, irq); ··· 3333 3501 struct msi_msg msg; 3334 3502 int ret; 3335 3503 3336 - if (intr_remapping_enabled) { 3337 - struct intel_iommu *iommu = map_hpet_to_ir(id); 3338 - int index; 3339 - 3340 - if (!iommu) 3341 - return -1; 3342 - 3343 - index = alloc_irte(iommu, irq, 1); 3344 - if (index < 0) 3504 + if (irq_remapping_enabled) { 3505 + if (!setup_hpet_msi_remapped(irq, id)) 3345 3506 return -1; 3346 3507 } 3347 3508 ··· 3713 3888 else 3714 3889 mask = apic->target_cpus(); 3715 3890 3716 - if (intr_remapping_enabled) 3717 - ir_ioapic_set_affinity(idata, mask, false); 3891 + if (irq_remapping_enabled) 3892 + set_remapped_irq_affinity(idata, mask, false); 3718 3893 else 3719 3894 ioapic_set_affinity(idata, mask, false); 3720 3895 }
+1 -1
drivers/iommu/Makefile
··· 4 4 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o 5 5 obj-$(CONFIG_DMAR_TABLE) += dmar.o 6 6 obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o 7 - obj-$(CONFIG_IRQ_REMAP) += intr_remapping.o 7 + obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o 8 8 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o 9 9 obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o 10 10 obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
+6 -5
drivers/iommu/dmar.c
··· 36 36 #include <linux/tboot.h> 37 37 #include <linux/dmi.h> 38 38 #include <linux/slab.h> 39 + #include <asm/irq_remapping.h> 39 40 #include <asm/iommu_table.h> 40 41 41 42 #define PREFIX "DMAR: " ··· 556 555 557 556 dmar = (struct acpi_table_dmar *) dmar_tbl; 558 557 559 - if (ret && intr_remapping_enabled && cpu_has_x2apic && 558 + if (ret && irq_remapping_enabled && cpu_has_x2apic && 560 559 dmar->flags & 0x1) 561 560 printk(KERN_INFO 562 561 "Queued invalidation will be enabled to support x2apic and Intr-remapping.\n"); ··· 1042 1041 "non-zero reserved fields in PTE", 1043 1042 }; 1044 1043 1045 - static const char *intr_remap_fault_reasons[] = 1044 + static const char *irq_remap_fault_reasons[] = 1046 1045 { 1047 1046 "Detected reserved fields in the decoded interrupt-remapped request", 1048 1047 "Interrupt index exceeded the interrupt-remapping table size", ··· 1057 1056 1058 1057 const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type) 1059 1058 { 1060 - if (fault_reason >= 0x20 && (fault_reason <= 0x20 + 1061 - ARRAY_SIZE(intr_remap_fault_reasons))) { 1059 + if (fault_reason >= 0x20 && (fault_reason - 0x20 < 1060 + ARRAY_SIZE(irq_remap_fault_reasons))) { 1062 1061 *fault_type = INTR_REMAP; 1063 - return intr_remap_fault_reasons[fault_reason - 0x20]; 1062 + return irq_remap_fault_reasons[fault_reason - 0x20]; 1064 1063 } else if (fault_reason < ARRAY_SIZE(dma_remap_fault_reasons)) { 1065 1064 *fault_type = DMA_REMAP; 1066 1065 return dma_remap_fault_reasons[fault_reason];
+2 -1
drivers/iommu/intel-iommu.c
··· 42 42 #include <linux/dmi.h> 43 43 #include <linux/pci-ats.h> 44 44 #include <linux/memblock.h> 45 + #include <asm/irq_remapping.h> 45 46 #include <asm/cacheflush.h> 46 47 #include <asm/iommu.h> 47 48 ··· 4083 4082 if (cap == IOMMU_CAP_CACHE_COHERENCY) 4084 4083 return dmar_domain->iommu_snooping; 4085 4084 if (cap == IOMMU_CAP_INTR_REMAP) 4086 - return intr_remapping_enabled; 4085 + return irq_remapping_enabled; 4087 4086 4088 4087 return 0; 4089 4088 }
+298 -63
drivers/iommu/intr_remapping.c drivers/iommu/intel_irq_remapping.c
··· 10 10 #include <asm/smp.h> 11 11 #include <asm/cpu.h> 12 12 #include <linux/intel-iommu.h> 13 - #include "intr_remapping.h" 14 13 #include <acpi/acpi.h> 14 + #include <asm/irq_remapping.h> 15 15 #include <asm/pci-direct.h> 16 + #include <asm/msidef.h> 17 + 18 + #include "irq_remapping.h" 19 + 20 + struct ioapic_scope { 21 + struct intel_iommu *iommu; 22 + unsigned int id; 23 + unsigned int bus; /* PCI bus number */ 24 + unsigned int devfn; /* PCI devfn number */ 25 + }; 26 + 27 + struct hpet_scope { 28 + struct intel_iommu *iommu; 29 + u8 id; 30 + unsigned int bus; 31 + unsigned int devfn; 32 + }; 33 + 34 + #define IR_X2APIC_MODE(mode) (mode ? (1 << 11) : 0) 35 + #define IRTE_DEST(dest) ((x2apic_mode) ? dest : dest << 8) 16 36 17 37 static struct ioapic_scope ir_ioapic[MAX_IO_APICS]; 18 38 static struct hpet_scope ir_hpet[MAX_HPET_TBS]; 19 39 static int ir_ioapic_num, ir_hpet_num; 20 - int intr_remapping_enabled; 21 - 22 - static int disable_intremap; 23 - static int disable_sourceid_checking; 24 - static int no_x2apic_optout; 25 - 26 - static __init int setup_nointremap(char *str) 27 - { 28 - disable_intremap = 1; 29 - return 0; 30 - } 31 - early_param("nointremap", setup_nointremap); 32 - 33 - static __init int setup_intremap(char *str) 34 - { 35 - if (!str) 36 - return -EINVAL; 37 - 38 - while (*str) { 39 - if (!strncmp(str, "on", 2)) 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 - 53 - return 0; 54 - } 55 - early_param("intremap", setup_intremap); 56 40 57 41 static DEFINE_RAW_SPINLOCK(irq_2_ir_lock); 58 42 ··· 64 80 return 0; 65 81 } 66 82 67 - int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) 83 + static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) 68 84 { 69 85 struct ir_table *table = iommu->ir_table; 70 86 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); ··· 136 152 return qi_submit_sync(&desc, iommu); 137 153 } 138 154 139 - int map_irq_to_irte_handle(int irq, u16 *sub_handle) 155 + static int map_irq_to_irte_handle(int irq, u16 *sub_handle) 140 156 { 141 157 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); 142 158 unsigned long flags; ··· 152 168 return index; 153 169 } 154 170 155 - int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) 171 + static int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) 156 172 { 157 173 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); 158 174 unsigned long flags; ··· 172 188 return 0; 173 189 } 174 190 175 - int modify_irte(int irq, struct irte *irte_modified) 191 + static int modify_irte(int irq, struct irte *irte_modified) 176 192 { 177 193 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); 178 194 struct intel_iommu *iommu; ··· 200 216 return rc; 201 217 } 202 218 203 - struct intel_iommu *map_hpet_to_ir(u8 hpet_id) 219 + static struct intel_iommu *map_hpet_to_ir(u8 hpet_id) 204 220 { 205 221 int i; 206 222 ··· 210 226 return NULL; 211 227 } 212 228 213 - struct intel_iommu *map_ioapic_to_ir(int apic) 229 + static struct intel_iommu *map_ioapic_to_ir(int apic) 214 230 { 215 231 int i; 216 232 ··· 220 236 return NULL; 221 237 } 222 238 223 - struct intel_iommu *map_dev_to_ir(struct pci_dev *dev) 239 + static struct intel_iommu *map_dev_to_ir(struct pci_dev *dev) 224 240 { 225 241 struct dmar_drhd_unit *drhd; 226 242 ··· 254 270 return qi_flush_iec(iommu, index, irq_iommu->irte_mask); 255 271 } 256 272 257 - int free_irte(int irq) 273 + static int free_irte(int irq) 258 274 { 259 275 struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); 260 276 unsigned long flags; ··· 312 328 irte->sid = sid; 313 329 } 314 330 315 - int set_ioapic_sid(struct irte *irte, int apic) 331 + static int set_ioapic_sid(struct irte *irte, int apic) 316 332 { 317 333 int i; 318 334 u16 sid = 0; ··· 337 353 return 0; 338 354 } 339 355 340 - int set_hpet_sid(struct irte *irte, u8 id) 356 + static int set_hpet_sid(struct irte *irte, u8 id) 341 357 { 342 358 int i; 343 359 u16 sid = 0; ··· 367 383 return 0; 368 384 } 369 385 370 - int set_msi_sid(struct irte *irte, struct pci_dev *dev) 386 + static int set_msi_sid(struct irte *irte, struct pci_dev *dev) 371 387 { 372 388 struct pci_dev *bridge; 373 389 ··· 394 410 return 0; 395 411 } 396 412 397 - static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode) 413 + static void iommu_set_irq_remapping(struct intel_iommu *iommu, int mode) 398 414 { 399 415 u64 addr; 400 416 u32 sts; ··· 434 450 } 435 451 436 452 437 - static int setup_intr_remapping(struct intel_iommu *iommu, int mode) 453 + static int intel_setup_irq_remapping(struct intel_iommu *iommu, int mode) 438 454 { 439 455 struct ir_table *ir_table; 440 456 struct page *pages; ··· 457 473 458 474 ir_table->base = page_address(pages); 459 475 460 - iommu_set_intr_remapping(iommu, mode); 476 + iommu_set_irq_remapping(iommu, mode); 461 477 return 0; 462 478 } 463 479 464 480 /* 465 481 * Disable Interrupt Remapping. 466 482 */ 467 - static void iommu_disable_intr_remapping(struct intel_iommu *iommu) 483 + static void iommu_disable_irq_remapping(struct intel_iommu *iommu) 468 484 { 469 485 unsigned long flags; 470 486 u32 sts; ··· 503 519 return dmar->flags & DMAR_X2APIC_OPT_OUT; 504 520 } 505 521 506 - int __init intr_remapping_supported(void) 522 + static int __init intel_irq_remapping_supported(void) 507 523 { 508 524 struct dmar_drhd_unit *drhd; 509 525 510 - if (disable_intremap) 526 + if (disable_irq_remap) 511 527 return 0; 512 528 513 529 if (!dmar_ir_support()) ··· 523 539 return 1; 524 540 } 525 541 526 - int __init enable_intr_remapping(void) 542 + static int __init intel_enable_irq_remapping(void) 527 543 { 528 544 struct dmar_drhd_unit *drhd; 529 545 int setup = 0; ··· 561 577 * Disable intr remapping and queued invalidation, if already 562 578 * enabled prior to OS handover. 563 579 */ 564 - iommu_disable_intr_remapping(iommu); 580 + iommu_disable_irq_remapping(iommu); 565 581 566 582 dmar_disable_qi(iommu); 567 583 } ··· 607 623 if (!ecap_ir_support(iommu->ecap)) 608 624 continue; 609 625 610 - if (setup_intr_remapping(iommu, eim)) 626 + if (intel_setup_irq_remapping(iommu, eim)) 611 627 goto error; 612 628 613 629 setup = 1; ··· 616 632 if (!setup) 617 633 goto error; 618 634 619 - intr_remapping_enabled = 1; 635 + irq_remapping_enabled = 1; 620 636 pr_info("Enabled IRQ remapping in %s mode\n", eim ? "x2apic" : "xapic"); 621 637 622 638 return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE; ··· 759 775 760 776 int __init ir_dev_scope_init(void) 761 777 { 762 - if (!intr_remapping_enabled) 778 + if (!irq_remapping_enabled) 763 779 return 0; 764 780 765 781 return dmar_dev_scope_init(); 766 782 } 767 783 rootfs_initcall(ir_dev_scope_init); 768 784 769 - void disable_intr_remapping(void) 785 + static void disable_irq_remapping(void) 770 786 { 771 787 struct dmar_drhd_unit *drhd; 772 788 struct intel_iommu *iommu = NULL; ··· 778 794 if (!ecap_ir_support(iommu->ecap)) 779 795 continue; 780 796 781 - iommu_disable_intr_remapping(iommu); 797 + iommu_disable_irq_remapping(iommu); 782 798 } 783 799 } 784 800 785 - int reenable_intr_remapping(int eim) 801 + static int reenable_irq_remapping(int eim) 786 802 { 787 803 struct dmar_drhd_unit *drhd; 788 804 int setup = 0; ··· 800 816 continue; 801 817 802 818 /* Set up interrupt remapping for iommu.*/ 803 - iommu_set_intr_remapping(iommu, eim); 819 + iommu_set_irq_remapping(iommu, eim); 804 820 setup = 1; 805 821 } 806 822 ··· 816 832 return -1; 817 833 } 818 834 835 + static void prepare_irte(struct irte *irte, int vector, 836 + unsigned int dest) 837 + { 838 + memset(irte, 0, sizeof(*irte)); 839 + 840 + irte->present = 1; 841 + irte->dst_mode = apic->irq_dest_mode; 842 + /* 843 + * Trigger mode in the IRTE will always be edge, and for IO-APIC, the 844 + * actual level or edge trigger will be setup in the IO-APIC 845 + * RTE. This will help simplify level triggered irq migration. 846 + * For more details, see the comments (in io_apic.c) explainig IO-APIC 847 + * irq migration in the presence of interrupt-remapping. 848 + */ 849 + irte->trigger_mode = 0; 850 + irte->dlvry_mode = apic->irq_delivery_mode; 851 + irte->vector = vector; 852 + irte->dest_id = IRTE_DEST(dest); 853 + irte->redir_hint = 1; 854 + } 855 + 856 + static int intel_setup_ioapic_entry(int irq, 857 + struct IO_APIC_route_entry *route_entry, 858 + unsigned int destination, int vector, 859 + struct io_apic_irq_attr *attr) 860 + { 861 + int ioapic_id = mpc_ioapic_id(attr->ioapic); 862 + struct intel_iommu *iommu = map_ioapic_to_ir(ioapic_id); 863 + struct IR_IO_APIC_route_entry *entry; 864 + struct irte irte; 865 + int index; 866 + 867 + if (!iommu) { 868 + pr_warn("No mapping iommu for ioapic %d\n", ioapic_id); 869 + return -ENODEV; 870 + } 871 + 872 + entry = (struct IR_IO_APIC_route_entry *)route_entry; 873 + 874 + index = alloc_irte(iommu, irq, 1); 875 + if (index < 0) { 876 + pr_warn("Failed to allocate IRTE for ioapic %d\n", ioapic_id); 877 + return -ENOMEM; 878 + } 879 + 880 + prepare_irte(&irte, vector, destination); 881 + 882 + /* Set source-id of interrupt request */ 883 + set_ioapic_sid(&irte, ioapic_id); 884 + 885 + modify_irte(irq, &irte); 886 + 887 + apic_printk(APIC_VERBOSE, KERN_DEBUG "IOAPIC[%d]: " 888 + "Set IRTE entry (P:%d FPD:%d Dst_Mode:%d " 889 + "Redir_hint:%d Trig_Mode:%d Dlvry_Mode:%X " 890 + "Avail:%X Vector:%02X Dest:%08X " 891 + "SID:%04X SQ:%X SVT:%X)\n", 892 + attr->ioapic, irte.present, irte.fpd, irte.dst_mode, 893 + irte.redir_hint, irte.trigger_mode, irte.dlvry_mode, 894 + irte.avail, irte.vector, irte.dest_id, 895 + irte.sid, irte.sq, irte.svt); 896 + 897 + memset(entry, 0, sizeof(*entry)); 898 + 899 + entry->index2 = (index >> 15) & 0x1; 900 + entry->zero = 0; 901 + entry->format = 1; 902 + entry->index = (index & 0x7fff); 903 + /* 904 + * IO-APIC RTE will be configured with virtual vector. 905 + * irq handler will do the explicit EOI to the io-apic. 906 + */ 907 + entry->vector = attr->ioapic_pin; 908 + entry->mask = 0; /* enable IRQ */ 909 + entry->trigger = attr->trigger; 910 + entry->polarity = attr->polarity; 911 + 912 + /* Mask level triggered irqs. 913 + * Use IRQ_DELAYED_DISABLE for edge triggered irqs. 914 + */ 915 + if (attr->trigger) 916 + entry->mask = 1; 917 + 918 + return 0; 919 + } 920 + 921 + #ifdef CONFIG_SMP 922 + /* 923 + * Migrate the IO-APIC irq in the presence of intr-remapping. 924 + * 925 + * For both level and edge triggered, irq migration is a simple atomic 926 + * update(of vector and cpu destination) of IRTE and flush the hardware cache. 927 + * 928 + * For level triggered, we eliminate the io-apic RTE modification (with the 929 + * updated vector information), by using a virtual vector (io-apic pin number). 930 + * Real vector that is used for interrupting cpu will be coming from 931 + * the interrupt-remapping table entry. 932 + * 933 + * As the migration is a simple atomic update of IRTE, the same mechanism 934 + * is used to migrate MSI irq's in the presence of interrupt-remapping. 935 + */ 936 + static int 937 + intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, 938 + bool force) 939 + { 940 + struct irq_cfg *cfg = data->chip_data; 941 + unsigned int dest, irq = data->irq; 942 + struct irte irte; 943 + 944 + if (!cpumask_intersects(mask, cpu_online_mask)) 945 + return -EINVAL; 946 + 947 + if (get_irte(irq, &irte)) 948 + return -EBUSY; 949 + 950 + if (assign_irq_vector(irq, cfg, mask)) 951 + return -EBUSY; 952 + 953 + dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask); 954 + 955 + irte.vector = cfg->vector; 956 + irte.dest_id = IRTE_DEST(dest); 957 + 958 + /* 959 + * Atomically updates the IRTE with the new destination, vector 960 + * and flushes the interrupt entry cache. 961 + */ 962 + modify_irte(irq, &irte); 963 + 964 + /* 965 + * After this point, all the interrupts will start arriving 966 + * at the new destination. So, time to cleanup the previous 967 + * vector allocation. 968 + */ 969 + if (cfg->move_in_progress) 970 + send_cleanup_vector(cfg); 971 + 972 + cpumask_copy(data->affinity, mask); 973 + return 0; 974 + } 975 + #endif 976 + 977 + static void intel_compose_msi_msg(struct pci_dev *pdev, 978 + unsigned int irq, unsigned int dest, 979 + struct msi_msg *msg, u8 hpet_id) 980 + { 981 + struct irq_cfg *cfg; 982 + struct irte irte; 983 + u16 sub_handle = 0; 984 + int ir_index; 985 + 986 + cfg = irq_get_chip_data(irq); 987 + 988 + ir_index = map_irq_to_irte_handle(irq, &sub_handle); 989 + BUG_ON(ir_index == -1); 990 + 991 + prepare_irte(&irte, cfg->vector, dest); 992 + 993 + /* Set source-id of interrupt request */ 994 + if (pdev) 995 + set_msi_sid(&irte, pdev); 996 + else 997 + set_hpet_sid(&irte, hpet_id); 998 + 999 + modify_irte(irq, &irte); 1000 + 1001 + msg->address_hi = MSI_ADDR_BASE_HI; 1002 + msg->data = sub_handle; 1003 + msg->address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_IR_EXT_INT | 1004 + MSI_ADDR_IR_SHV | 1005 + MSI_ADDR_IR_INDEX1(ir_index) | 1006 + MSI_ADDR_IR_INDEX2(ir_index); 1007 + } 1008 + 1009 + /* 1010 + * Map the PCI dev to the corresponding remapping hardware unit 1011 + * and allocate 'nvec' consecutive interrupt-remapping table entries 1012 + * in it. 1013 + */ 1014 + static int intel_msi_alloc_irq(struct pci_dev *dev, int irq, int nvec) 1015 + { 1016 + struct intel_iommu *iommu; 1017 + int index; 1018 + 1019 + iommu = map_dev_to_ir(dev); 1020 + if (!iommu) { 1021 + printk(KERN_ERR 1022 + "Unable to map PCI %s to iommu\n", pci_name(dev)); 1023 + return -ENOENT; 1024 + } 1025 + 1026 + index = alloc_irte(iommu, irq, nvec); 1027 + if (index < 0) { 1028 + printk(KERN_ERR 1029 + "Unable to allocate %d IRTE for PCI %s\n", nvec, 1030 + pci_name(dev)); 1031 + return -ENOSPC; 1032 + } 1033 + return index; 1034 + } 1035 + 1036 + static int intel_msi_setup_irq(struct pci_dev *pdev, unsigned int irq, 1037 + int index, int sub_handle) 1038 + { 1039 + struct intel_iommu *iommu; 1040 + 1041 + iommu = map_dev_to_ir(pdev); 1042 + if (!iommu) 1043 + return -ENOENT; 1044 + /* 1045 + * setup the mapping between the irq and the IRTE 1046 + * base index, the sub_handle pointing to the 1047 + * appropriate interrupt remap table entry. 1048 + */ 1049 + set_irte_irq(irq, iommu, index, sub_handle); 1050 + 1051 + return 0; 1052 + } 1053 + 1054 + static int intel_setup_hpet_msi(unsigned int irq, unsigned int id) 1055 + { 1056 + struct intel_iommu *iommu = map_hpet_to_ir(id); 1057 + int index; 1058 + 1059 + if (!iommu) 1060 + return -1; 1061 + 1062 + index = alloc_irte(iommu, irq, 1); 1063 + if (index < 0) 1064 + return -1; 1065 + 1066 + return 0; 1067 + } 1068 + 1069 + struct irq_remap_ops intel_irq_remap_ops = { 1070 + .supported = intel_irq_remapping_supported, 1071 + .prepare = dmar_table_init, 1072 + .enable = intel_enable_irq_remapping, 1073 + .disable = disable_irq_remapping, 1074 + .reenable = reenable_irq_remapping, 1075 + .enable_faulting = enable_drhd_fault_handling, 1076 + .setup_ioapic_entry = intel_setup_ioapic_entry, 1077 + #ifdef CONFIG_SMP 1078 + .set_affinity = intel_ioapic_set_affinity, 1079 + #endif 1080 + .free_irq = free_irte, 1081 + .compose_msi_msg = intel_compose_msi_msg, 1082 + .msi_alloc_irq = intel_msi_alloc_irq, 1083 + .msi_setup_irq = intel_msi_setup_irq, 1084 + .setup_hpet_msi = intel_setup_hpet_msi, 1085 + };
-17
drivers/iommu/intr_remapping.h
··· 1 - #include <linux/intel-iommu.h> 2 - 3 - struct 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 - 10 - struct 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)
+166
drivers/iommu/irq_remapping.c
··· 1 + #include <linux/kernel.h> 2 + #include <linux/string.h> 3 + #include <linux/errno.h> 4 + 5 + #include "irq_remapping.h" 6 + 7 + int irq_remapping_enabled; 8 + 9 + int disable_irq_remap; 10 + int disable_sourceid_checking; 11 + int no_x2apic_optout; 12 + 13 + static struct irq_remap_ops *remap_ops; 14 + 15 + static __init int setup_nointremap(char *str) 16 + { 17 + disable_irq_remap = 1; 18 + return 0; 19 + } 20 + early_param("nointremap", setup_nointremap); 21 + 22 + static __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 + } 44 + early_param("intremap", setup_irqremap); 45 + 46 + void __init setup_irq_remapping_ops(void) 47 + { 48 + remap_ops = &intel_irq_remap_ops; 49 + } 50 + 51 + int 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 + 62 + int __init irq_remapping_prepare(void) 63 + { 64 + if (!remap_ops || !remap_ops->prepare) 65 + return -ENODEV; 66 + 67 + return remap_ops->prepare(); 68 + } 69 + 70 + int __init irq_remapping_enable(void) 71 + { 72 + if (!remap_ops || !remap_ops->enable) 73 + return -ENODEV; 74 + 75 + return remap_ops->enable(); 76 + } 77 + 78 + void irq_remapping_disable(void) 79 + { 80 + if (!remap_ops || !remap_ops->disable) 81 + return; 82 + 83 + remap_ops->disable(); 84 + } 85 + 86 + int 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 + 94 + int __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 + 102 + int 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 115 + int 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 + 125 + void 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 + 133 + void 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 + 143 + int 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 + 151 + int 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 + 160 + int 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 + }
+90
drivers/iommu/irq_remapping.h
··· 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 + 27 + struct IO_APIC_route_entry; 28 + struct io_apic_irq_attr; 29 + struct irq_data; 30 + struct cpumask; 31 + struct pci_dev; 32 + struct msi_msg; 33 + 34 + extern int disable_irq_remap; 35 + extern int disable_sourceid_checking; 36 + extern int no_x2apic_optout; 37 + 38 + struct 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 + 86 + extern struct irq_remap_ops intel_irq_remap_ops; 87 + 88 + #endif /* CONFIG_IRQ_REMAP */ 89 + 90 + #endif /* __IRQ_REMAPPING_H */
-85
include/linux/dmar.h
··· 114 114 }; 115 115 }; 116 116 117 - #ifdef CONFIG_IRQ_REMAP 118 - extern int intr_remapping_enabled; 119 - extern int intr_remapping_supported(void); 120 - extern int enable_intr_remapping(void); 121 - extern void disable_intr_remapping(void); 122 - extern int reenable_intr_remapping(int); 123 - 124 - extern int get_irte(int irq, struct irte *entry); 125 - extern int modify_irte(int irq, struct irte *irte_modified); 126 - extern int alloc_irte(struct intel_iommu *iommu, int irq, u16 count); 127 - extern int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, 128 - u16 sub_handle); 129 - extern int map_irq_to_irte_handle(int irq, u16 *sub_handle); 130 - extern int free_irte(int irq); 131 - 132 - extern struct intel_iommu *map_dev_to_ir(struct pci_dev *dev); 133 - extern struct intel_iommu *map_ioapic_to_ir(int apic); 134 - extern struct intel_iommu *map_hpet_to_ir(u8 id); 135 - extern int set_ioapic_sid(struct irte *irte, int apic); 136 - extern int set_hpet_sid(struct irte *irte, u8 id); 137 - extern int set_msi_sid(struct irte *irte, struct pci_dev *dev); 138 - #else 139 - static inline int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) 140 - { 141 - return -1; 142 - } 143 - static inline int modify_irte(int irq, struct irte *irte_modified) 144 - { 145 - return -1; 146 - } 147 - static inline int free_irte(int irq) 148 - { 149 - return -1; 150 - } 151 - static inline int map_irq_to_irte_handle(int irq, u16 *sub_handle) 152 - { 153 - return -1; 154 - } 155 - static inline int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, 156 - u16 sub_handle) 157 - { 158 - return -1; 159 - } 160 - static inline struct intel_iommu *map_dev_to_ir(struct pci_dev *dev) 161 - { 162 - return NULL; 163 - } 164 - static inline struct intel_iommu *map_ioapic_to_ir(int apic) 165 - { 166 - return NULL; 167 - } 168 - static inline struct intel_iommu *map_hpet_to_ir(unsigned int hpet_id) 169 - { 170 - return NULL; 171 - } 172 - static inline int set_ioapic_sid(struct irte *irte, int apic) 173 - { 174 - return 0; 175 - } 176 - static inline int set_hpet_sid(struct irte *irte, u8 id) 177 - { 178 - return -1; 179 - } 180 - static 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 - 187 - static inline int enable_intr_remapping(void) 188 - { 189 - return -1; 190 - } 191 - 192 - static inline void disable_intr_remapping(void) 193 - { 194 - } 195 - 196 - static inline int reenable_intr_remapping(int eim) 197 - { 198 - return 0; 199 - } 200 - #endif 201 - 202 117 enum { 203 118 IRQ_REMAP_XAPIC_MODE, 204 119 IRQ_REMAP_X2APIC_MODE,