diff options
-rw-r--r-- | arch/x86/kernel/apic_64.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/io_apic_64.c | 300 | ||||
-rw-r--r-- | drivers/pci/intr_remapping.c | 10 | ||||
-rw-r--r-- | include/asm-x86/apic.h | 9 | ||||
-rw-r--r-- | include/asm-x86/io_apic.h | 14 | ||||
-rw-r--r-- | include/asm-x86/irq_remapping.h | 8 | ||||
-rw-r--r-- | include/linux/dmar.h | 1 |
7 files changed, 321 insertions, 22 deletions
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c index a969ef78e12a..d5c06917b5b1 100644 --- a/arch/x86/kernel/apic_64.c +++ b/arch/x86/kernel/apic_64.c | |||
@@ -46,6 +46,7 @@ | |||
46 | static int disable_apic_timer __cpuinitdata; | 46 | static int disable_apic_timer __cpuinitdata; |
47 | static int apic_calibrate_pmtmr __initdata; | 47 | static int apic_calibrate_pmtmr __initdata; |
48 | int disable_apic; | 48 | int disable_apic; |
49 | int x2apic; | ||
49 | 50 | ||
50 | /* Local APIC timer works in C2 */ | 51 | /* Local APIC timer works in C2 */ |
51 | int local_apic_timer_c2_ok; | 52 | int local_apic_timer_c2_ok; |
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c index b62d42ef9283..9bd02ef049a0 100644 --- a/arch/x86/kernel/io_apic_64.c +++ b/arch/x86/kernel/io_apic_64.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <acpi/acpi_bus.h> | 37 | #include <acpi/acpi_bus.h> |
38 | #endif | 38 | #endif |
39 | #include <linux/bootmem.h> | 39 | #include <linux/bootmem.h> |
40 | #include <linux/dmar.h> | ||
40 | 41 | ||
41 | #include <asm/idle.h> | 42 | #include <asm/idle.h> |
42 | #include <asm/io.h> | 43 | #include <asm/io.h> |
@@ -48,6 +49,7 @@ | |||
48 | #include <asm/nmi.h> | 49 | #include <asm/nmi.h> |
49 | #include <asm/msidef.h> | 50 | #include <asm/msidef.h> |
50 | #include <asm/hypertransport.h> | 51 | #include <asm/hypertransport.h> |
52 | #include <asm/irq_remapping.h> | ||
51 | 53 | ||
52 | #include <mach_ipi.h> | 54 | #include <mach_ipi.h> |
53 | #include <mach_apic.h> | 55 | #include <mach_apic.h> |
@@ -312,7 +314,12 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, u8 vector) | |||
312 | pin = entry->pin; | 314 | pin = entry->pin; |
313 | if (pin == -1) | 315 | if (pin == -1) |
314 | break; | 316 | break; |
315 | io_apic_write(apic, 0x11 + pin*2, dest); | 317 | /* |
318 | * With interrupt-remapping, destination information comes | ||
319 | * from interrupt-remapping table entry. | ||
320 | */ | ||
321 | if (!irq_remapped(irq)) | ||
322 | io_apic_write(apic, 0x11 + pin*2, dest); | ||
316 | reg = io_apic_read(apic, 0x10 + pin*2); | 323 | reg = io_apic_read(apic, 0x10 + pin*2); |
317 | reg &= ~IO_APIC_REDIR_VECTOR_MASK; | 324 | reg &= ~IO_APIC_REDIR_VECTOR_MASK; |
318 | reg |= vector; | 325 | reg |= vector; |
@@ -906,18 +913,98 @@ void setup_vector_irq(int cpu) | |||
906 | 913 | ||
907 | 914 | ||
908 | static struct irq_chip ioapic_chip; | 915 | static struct irq_chip ioapic_chip; |
916 | #ifdef CONFIG_INTR_REMAP | ||
917 | static struct irq_chip ir_ioapic_chip; | ||
918 | #endif | ||
909 | 919 | ||
910 | static void ioapic_register_intr(int irq, unsigned long trigger) | 920 | static void ioapic_register_intr(int irq, unsigned long trigger) |
911 | { | 921 | { |
912 | if (trigger) { | 922 | if (trigger) |
913 | irq_desc[irq].status |= IRQ_LEVEL; | 923 | irq_desc[irq].status |= IRQ_LEVEL; |
914 | set_irq_chip_and_handler_name(irq, &ioapic_chip, | 924 | else |
915 | handle_fasteoi_irq, "fasteoi"); | ||
916 | } else { | ||
917 | irq_desc[irq].status &= ~IRQ_LEVEL; | 925 | irq_desc[irq].status &= ~IRQ_LEVEL; |
926 | |||
927 | #ifdef CONFIG_INTR_REMAP | ||
928 | if (irq_remapped(irq)) { | ||
929 | irq_desc[irq].status |= IRQ_MOVE_PCNTXT; | ||
930 | if (trigger) | ||
931 | set_irq_chip_and_handler_name(irq, &ir_ioapic_chip, | ||
932 | handle_fasteoi_irq, | ||
933 | "fasteoi"); | ||
934 | else | ||
935 | set_irq_chip_and_handler_name(irq, &ir_ioapic_chip, | ||
936 | handle_edge_irq, "edge"); | ||
937 | return; | ||
938 | } | ||
939 | #endif | ||
940 | if (trigger) | ||
941 | set_irq_chip_and_handler_name(irq, &ioapic_chip, | ||
942 | handle_fasteoi_irq, | ||
943 | "fasteoi"); | ||
944 | else | ||
918 | set_irq_chip_and_handler_name(irq, &ioapic_chip, | 945 | set_irq_chip_and_handler_name(irq, &ioapic_chip, |
919 | handle_edge_irq, "edge"); | 946 | handle_edge_irq, "edge"); |
947 | } | ||
948 | |||
949 | static int setup_ioapic_entry(int apic, int irq, | ||
950 | struct IO_APIC_route_entry *entry, | ||
951 | unsigned int destination, int trigger, | ||
952 | int polarity, int vector) | ||
953 | { | ||
954 | /* | ||
955 | * add it to the IO-APIC irq-routing table: | ||
956 | */ | ||
957 | memset(entry,0,sizeof(*entry)); | ||
958 | |||
959 | #ifdef CONFIG_INTR_REMAP | ||
960 | if (intr_remapping_enabled) { | ||
961 | struct intel_iommu *iommu = map_ioapic_to_ir(apic); | ||
962 | struct irte irte; | ||
963 | struct IR_IO_APIC_route_entry *ir_entry = | ||
964 | (struct IR_IO_APIC_route_entry *) entry; | ||
965 | int index; | ||
966 | |||
967 | if (!iommu) | ||
968 | panic("No mapping iommu for ioapic %d\n", apic); | ||
969 | |||
970 | index = alloc_irte(iommu, irq, 1); | ||
971 | if (index < 0) | ||
972 | panic("Failed to allocate IRTE for ioapic %d\n", apic); | ||
973 | |||
974 | memset(&irte, 0, sizeof(irte)); | ||
975 | |||
976 | irte.present = 1; | ||
977 | irte.dst_mode = INT_DEST_MODE; | ||
978 | irte.trigger_mode = trigger; | ||
979 | irte.dlvry_mode = INT_DELIVERY_MODE; | ||
980 | irte.vector = vector; | ||
981 | irte.dest_id = IRTE_DEST(destination); | ||
982 | |||
983 | modify_irte(irq, &irte); | ||
984 | |||
985 | ir_entry->index2 = (index >> 15) & 0x1; | ||
986 | ir_entry->zero = 0; | ||
987 | ir_entry->format = 1; | ||
988 | ir_entry->index = (index & 0x7fff); | ||
989 | } else | ||
990 | #endif | ||
991 | { | ||
992 | entry->delivery_mode = INT_DELIVERY_MODE; | ||
993 | entry->dest_mode = INT_DEST_MODE; | ||
994 | entry->dest = destination; | ||
920 | } | 995 | } |
996 | |||
997 | entry->mask = 0; /* enable IRQ */ | ||
998 | entry->trigger = trigger; | ||
999 | entry->polarity = polarity; | ||
1000 | entry->vector = vector; | ||
1001 | |||
1002 | /* Mask level triggered irqs. | ||
1003 | * Use IRQ_DELAYED_DISABLE for edge triggered irqs. | ||
1004 | */ | ||
1005 | if (trigger) | ||
1006 | entry->mask = 1; | ||
1007 | return 0; | ||
921 | } | 1008 | } |
922 | 1009 | ||
923 | static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq, | 1010 | static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq, |
@@ -942,24 +1029,15 @@ static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq, | |||
942 | apic, mp_ioapics[apic].mp_apicid, pin, cfg->vector, | 1029 | apic, mp_ioapics[apic].mp_apicid, pin, cfg->vector, |
943 | irq, trigger, polarity); | 1030 | irq, trigger, polarity); |
944 | 1031 | ||
945 | /* | ||
946 | * add it to the IO-APIC irq-routing table: | ||
947 | */ | ||
948 | memset(&entry,0,sizeof(entry)); | ||
949 | |||
950 | entry.delivery_mode = INT_DELIVERY_MODE; | ||
951 | entry.dest_mode = INT_DEST_MODE; | ||
952 | entry.dest = cpu_mask_to_apicid(mask); | ||
953 | entry.mask = 0; /* enable IRQ */ | ||
954 | entry.trigger = trigger; | ||
955 | entry.polarity = polarity; | ||
956 | entry.vector = cfg->vector; | ||
957 | 1032 | ||
958 | /* Mask level triggered irqs. | 1033 | if (setup_ioapic_entry(mp_ioapics[apic].mp_apicid, irq, &entry, |
959 | * Use IRQ_DELAYED_DISABLE for edge triggered irqs. | 1034 | cpu_mask_to_apicid(mask), trigger, polarity, |
960 | */ | 1035 | cfg->vector)) { |
961 | if (trigger) | 1036 | printk("Failed to setup ioapic entry for ioapic %d, pin %d\n", |
962 | entry.mask = 1; | 1037 | mp_ioapics[apic].mp_apicid, pin); |
1038 | __clear_irq_vector(irq); | ||
1039 | return; | ||
1040 | } | ||
963 | 1041 | ||
964 | ioapic_register_intr(irq, trigger); | 1042 | ioapic_register_intr(irq, trigger); |
965 | if (irq < 16) | 1043 | if (irq < 16) |
@@ -1011,6 +1089,9 @@ static void __init setup_timer_IRQ0_pin(unsigned int apic, unsigned int pin, | |||
1011 | { | 1089 | { |
1012 | struct IO_APIC_route_entry entry; | 1090 | struct IO_APIC_route_entry entry; |
1013 | 1091 | ||
1092 | if (intr_remapping_enabled) | ||
1093 | return; | ||
1094 | |||
1014 | memset(&entry, 0, sizeof(entry)); | 1095 | memset(&entry, 0, sizeof(entry)); |
1015 | 1096 | ||
1016 | /* | 1097 | /* |
@@ -1466,6 +1547,147 @@ static int ioapic_retrigger_irq(unsigned int irq) | |||
1466 | */ | 1547 | */ |
1467 | 1548 | ||
1468 | #ifdef CONFIG_SMP | 1549 | #ifdef CONFIG_SMP |
1550 | |||
1551 | #ifdef CONFIG_INTR_REMAP | ||
1552 | static void ir_irq_migration(struct work_struct *work); | ||
1553 | |||
1554 | static DECLARE_DELAYED_WORK(ir_migration_work, ir_irq_migration); | ||
1555 | |||
1556 | /* | ||
1557 | * Migrate the IO-APIC irq in the presence of intr-remapping. | ||
1558 | * | ||
1559 | * For edge triggered, irq migration is a simple atomic update(of vector | ||
1560 | * and cpu destination) of IRTE and flush the hardware cache. | ||
1561 | * | ||
1562 | * For level triggered, we need to modify the io-apic RTE aswell with the update | ||
1563 | * vector information, along with modifying IRTE with vector and destination. | ||
1564 | * So irq migration for level triggered is little bit more complex compared to | ||
1565 | * edge triggered migration. But the good news is, we use the same algorithm | ||
1566 | * for level triggered migration as we have today, only difference being, | ||
1567 | * we now initiate the irq migration from process context instead of the | ||
1568 | * interrupt context. | ||
1569 | * | ||
1570 | * In future, when we do a directed EOI (combined with cpu EOI broadcast | ||
1571 | * suppression) to the IO-APIC, level triggered irq migration will also be | ||
1572 | * as simple as edge triggered migration and we can do the irq migration | ||
1573 | * with a simple atomic update to IO-APIC RTE. | ||
1574 | */ | ||
1575 | static void migrate_ioapic_irq(int irq, cpumask_t mask) | ||
1576 | { | ||
1577 | struct irq_cfg *cfg = irq_cfg + irq; | ||
1578 | struct irq_desc *desc = irq_desc + irq; | ||
1579 | cpumask_t tmp, cleanup_mask; | ||
1580 | struct irte irte; | ||
1581 | int modify_ioapic_rte = desc->status & IRQ_LEVEL; | ||
1582 | unsigned int dest; | ||
1583 | unsigned long flags; | ||
1584 | |||
1585 | cpus_and(tmp, mask, cpu_online_map); | ||
1586 | if (cpus_empty(tmp)) | ||
1587 | return; | ||
1588 | |||
1589 | if (get_irte(irq, &irte)) | ||
1590 | return; | ||
1591 | |||
1592 | if (assign_irq_vector(irq, mask)) | ||
1593 | return; | ||
1594 | |||
1595 | cpus_and(tmp, cfg->domain, mask); | ||
1596 | dest = cpu_mask_to_apicid(tmp); | ||
1597 | |||
1598 | if (modify_ioapic_rte) { | ||
1599 | spin_lock_irqsave(&ioapic_lock, flags); | ||
1600 | __target_IO_APIC_irq(irq, dest, cfg->vector); | ||
1601 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
1602 | } | ||
1603 | |||
1604 | irte.vector = cfg->vector; | ||
1605 | irte.dest_id = IRTE_DEST(dest); | ||
1606 | |||
1607 | /* | ||
1608 | * Modified the IRTE and flushes the Interrupt entry cache. | ||
1609 | */ | ||
1610 | modify_irte(irq, &irte); | ||
1611 | |||
1612 | if (cfg->move_in_progress) { | ||
1613 | cpus_and(cleanup_mask, cfg->old_domain, cpu_online_map); | ||
1614 | cfg->move_cleanup_count = cpus_weight(cleanup_mask); | ||
1615 | send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR); | ||
1616 | cfg->move_in_progress = 0; | ||
1617 | } | ||
1618 | |||
1619 | irq_desc[irq].affinity = mask; | ||
1620 | } | ||
1621 | |||
1622 | static int migrate_irq_remapped_level(int irq) | ||
1623 | { | ||
1624 | int ret = -1; | ||
1625 | |||
1626 | mask_IO_APIC_irq(irq); | ||
1627 | |||
1628 | if (io_apic_level_ack_pending(irq)) { | ||
1629 | /* | ||
1630 | * Interrupt in progress. Migrating irq now will change the | ||
1631 | * vector information in the IO-APIC RTE and that will confuse | ||
1632 | * the EOI broadcast performed by cpu. | ||
1633 | * So, delay the irq migration to the next instance. | ||
1634 | */ | ||
1635 | schedule_delayed_work(&ir_migration_work, 1); | ||
1636 | goto unmask; | ||
1637 | } | ||
1638 | |||
1639 | /* everthing is clear. we have right of way */ | ||
1640 | migrate_ioapic_irq(irq, irq_desc[irq].pending_mask); | ||
1641 | |||
1642 | ret = 0; | ||
1643 | irq_desc[irq].status &= ~IRQ_MOVE_PENDING; | ||
1644 | cpus_clear(irq_desc[irq].pending_mask); | ||
1645 | |||
1646 | unmask: | ||
1647 | unmask_IO_APIC_irq(irq); | ||
1648 | return ret; | ||
1649 | } | ||
1650 | |||
1651 | static void ir_irq_migration(struct work_struct *work) | ||
1652 | { | ||
1653 | int irq; | ||
1654 | |||
1655 | for (irq = 0; irq < NR_IRQS; irq++) { | ||
1656 | struct irq_desc *desc = irq_desc + irq; | ||
1657 | if (desc->status & IRQ_MOVE_PENDING) { | ||
1658 | unsigned long flags; | ||
1659 | |||
1660 | spin_lock_irqsave(&desc->lock, flags); | ||
1661 | if (!desc->chip->set_affinity || | ||
1662 | !(desc->status & IRQ_MOVE_PENDING)) { | ||
1663 | desc->status &= ~IRQ_MOVE_PENDING; | ||
1664 | spin_unlock_irqrestore(&desc->lock, flags); | ||
1665 | continue; | ||
1666 | } | ||
1667 | |||
1668 | desc->chip->set_affinity(irq, | ||
1669 | irq_desc[irq].pending_mask); | ||
1670 | spin_unlock_irqrestore(&desc->lock, flags); | ||
1671 | } | ||
1672 | } | ||
1673 | } | ||
1674 | |||
1675 | /* | ||
1676 | * Migrates the IRQ destination in the process context. | ||
1677 | */ | ||
1678 | static void set_ir_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) | ||
1679 | { | ||
1680 | if (irq_desc[irq].status & IRQ_LEVEL) { | ||
1681 | irq_desc[irq].status |= IRQ_MOVE_PENDING; | ||
1682 | irq_desc[irq].pending_mask = mask; | ||
1683 | migrate_irq_remapped_level(irq); | ||
1684 | return; | ||
1685 | } | ||
1686 | |||
1687 | migrate_ioapic_irq(irq, mask); | ||
1688 | } | ||
1689 | #endif | ||
1690 | |||
1469 | asmlinkage void smp_irq_move_cleanup_interrupt(void) | 1691 | asmlinkage void smp_irq_move_cleanup_interrupt(void) |
1470 | { | 1692 | { |
1471 | unsigned vector, me; | 1693 | unsigned vector, me; |
@@ -1522,6 +1744,17 @@ static void irq_complete_move(unsigned int irq) | |||
1522 | #else | 1744 | #else |
1523 | static inline void irq_complete_move(unsigned int irq) {} | 1745 | static inline void irq_complete_move(unsigned int irq) {} |
1524 | #endif | 1746 | #endif |
1747 | #ifdef CONFIG_INTR_REMAP | ||
1748 | static void ack_x2apic_level(unsigned int irq) | ||
1749 | { | ||
1750 | ack_x2APIC_irq(); | ||
1751 | } | ||
1752 | |||
1753 | static void ack_x2apic_edge(unsigned int irq) | ||
1754 | { | ||
1755 | ack_x2APIC_irq(); | ||
1756 | } | ||
1757 | #endif | ||
1525 | 1758 | ||
1526 | static void ack_apic_edge(unsigned int irq) | 1759 | static void ack_apic_edge(unsigned int irq) |
1527 | { | 1760 | { |
@@ -1596,6 +1829,21 @@ static struct irq_chip ioapic_chip __read_mostly = { | |||
1596 | .retrigger = ioapic_retrigger_irq, | 1829 | .retrigger = ioapic_retrigger_irq, |
1597 | }; | 1830 | }; |
1598 | 1831 | ||
1832 | #ifdef CONFIG_INTR_REMAP | ||
1833 | static struct irq_chip ir_ioapic_chip __read_mostly = { | ||
1834 | .name = "IR-IO-APIC", | ||
1835 | .startup = startup_ioapic_irq, | ||
1836 | .mask = mask_IO_APIC_irq, | ||
1837 | .unmask = unmask_IO_APIC_irq, | ||
1838 | .ack = ack_x2apic_edge, | ||
1839 | .eoi = ack_x2apic_level, | ||
1840 | #ifdef CONFIG_SMP | ||
1841 | .set_affinity = set_ir_ioapic_affinity_irq, | ||
1842 | #endif | ||
1843 | .retrigger = ioapic_retrigger_irq, | ||
1844 | }; | ||
1845 | #endif | ||
1846 | |||
1599 | static inline void init_IO_APIC_traps(void) | 1847 | static inline void init_IO_APIC_traps(void) |
1600 | { | 1848 | { |
1601 | int irq; | 1849 | int irq; |
@@ -1783,6 +2031,8 @@ static inline void __init check_timer(void) | |||
1783 | * 8259A. | 2031 | * 8259A. |
1784 | */ | 2032 | */ |
1785 | if (pin1 == -1) { | 2033 | if (pin1 == -1) { |
2034 | if (intr_remapping_enabled) | ||
2035 | panic("BIOS bug: timer not connected to IO-APIC"); | ||
1786 | pin1 = pin2; | 2036 | pin1 = pin2; |
1787 | apic1 = apic2; | 2037 | apic1 = apic2; |
1788 | no_pin1 = 1; | 2038 | no_pin1 = 1; |
@@ -1809,6 +2059,8 @@ static inline void __init check_timer(void) | |||
1809 | clear_IO_APIC_pin(0, pin1); | 2059 | clear_IO_APIC_pin(0, pin1); |
1810 | goto out; | 2060 | goto out; |
1811 | } | 2061 | } |
2062 | if (intr_remapping_enabled) | ||
2063 | panic("timer doesn't work through Interrupt-remapped IO-APIC"); | ||
1812 | clear_IO_APIC_pin(apic1, pin1); | 2064 | clear_IO_APIC_pin(apic1, pin1); |
1813 | if (!no_pin1) | 2065 | if (!no_pin1) |
1814 | apic_printk(APIC_QUIET,KERN_ERR "..MP-BIOS bug: " | 2066 | apic_printk(APIC_QUIET,KERN_ERR "..MP-BIOS bug: " |
@@ -2401,6 +2653,10 @@ void __init setup_ioapic_dest(void) | |||
2401 | setup_IO_APIC_irq(ioapic, pin, irq, | 2653 | setup_IO_APIC_irq(ioapic, pin, irq, |
2402 | irq_trigger(irq_entry), | 2654 | irq_trigger(irq_entry), |
2403 | irq_polarity(irq_entry)); | 2655 | irq_polarity(irq_entry)); |
2656 | #ifdef CONFIG_INTR_REMAP | ||
2657 | else if (intr_remapping_enabled) | ||
2658 | set_ir_ioapic_affinity_irq(irq, TARGET_CPUS); | ||
2659 | #endif | ||
2404 | else | 2660 | else |
2405 | set_ioapic_affinity_irq(irq, TARGET_CPUS); | 2661 | set_ioapic_affinity_irq(irq, TARGET_CPUS); |
2406 | } | 2662 | } |
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index bddb4b19b6c7..32e55c7a9805 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c | |||
@@ -220,6 +220,16 @@ int flush_irte(int irq) | |||
220 | return 0; | 220 | return 0; |
221 | } | 221 | } |
222 | 222 | ||
223 | struct intel_iommu *map_ioapic_to_ir(int apic) | ||
224 | { | ||
225 | int i; | ||
226 | |||
227 | for (i = 0; i < MAX_IO_APICS; i++) | ||
228 | if (ir_ioapic[i].id == apic) | ||
229 | return ir_ioapic[i].iommu; | ||
230 | return NULL; | ||
231 | } | ||
232 | |||
223 | int free_irte(int irq) | 233 | int free_irte(int irq) |
224 | { | 234 | { |
225 | int index, i; | 235 | int index, i; |
diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h index bb54928373ca..aa746704a5c9 100644 --- a/include/asm-x86/apic.h +++ b/include/asm-x86/apic.h | |||
@@ -134,6 +134,15 @@ extern int get_physical_broadcast(void); | |||
134 | # define apic_write_around(x, y) apic_write_atomic((x), (y)) | 134 | # define apic_write_around(x, y) apic_write_atomic((x), (y)) |
135 | #endif | 135 | #endif |
136 | 136 | ||
137 | #ifdef CONFIG_X86_64 | ||
138 | static inline void ack_x2APIC_irq(void) | ||
139 | { | ||
140 | /* Docs say use 0 for future compatibility */ | ||
141 | native_apic_msr_write(APIC_EOI, 0); | ||
142 | } | ||
143 | #endif | ||
144 | |||
145 | |||
137 | static inline void ack_APIC_irq(void) | 146 | static inline void ack_APIC_irq(void) |
138 | { | 147 | { |
139 | /* | 148 | /* |
diff --git a/include/asm-x86/io_apic.h b/include/asm-x86/io_apic.h index 1c4a99d882f5..8dc2622714c8 100644 --- a/include/asm-x86/io_apic.h +++ b/include/asm-x86/io_apic.h | |||
@@ -107,6 +107,20 @@ struct IO_APIC_route_entry { | |||
107 | 107 | ||
108 | } __attribute__ ((packed)); | 108 | } __attribute__ ((packed)); |
109 | 109 | ||
110 | struct IR_IO_APIC_route_entry { | ||
111 | __u64 vector : 8, | ||
112 | zero : 3, | ||
113 | index2 : 1, | ||
114 | delivery_status : 1, | ||
115 | polarity : 1, | ||
116 | irr : 1, | ||
117 | trigger : 1, | ||
118 | mask : 1, | ||
119 | reserved : 31, | ||
120 | format : 1, | ||
121 | index : 15; | ||
122 | } __attribute__ ((packed)); | ||
123 | |||
110 | #ifdef CONFIG_X86_IO_APIC | 124 | #ifdef CONFIG_X86_IO_APIC |
111 | 125 | ||
112 | /* | 126 | /* |
diff --git a/include/asm-x86/irq_remapping.h b/include/asm-x86/irq_remapping.h new file mode 100644 index 000000000000..78242c6ffa58 --- /dev/null +++ b/include/asm-x86/irq_remapping.h | |||
@@ -0,0 +1,8 @@ | |||
1 | #ifndef _ASM_IRQ_REMAPPING_H | ||
2 | #define _ASM_IRQ_REMAPPING_H | ||
3 | |||
4 | extern int x2apic; | ||
5 | |||
6 | #define IRTE_DEST(dest) ((x2apic) ? dest : dest << 8) | ||
7 | |||
8 | #endif | ||
diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 324bbca85a26..bf41ffa74705 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h | |||
@@ -109,6 +109,7 @@ extern int flush_irte(int irq); | |||
109 | extern int free_irte(int irq); | 109 | extern int free_irte(int irq); |
110 | 110 | ||
111 | extern int irq_remapped(int irq); | 111 | extern int irq_remapped(int irq); |
112 | extern struct intel_iommu *map_ioapic_to_ir(int apic); | ||
112 | #else | 113 | #else |
113 | #define irq_remapped(irq) (0) | 114 | #define irq_remapped(irq) (0) |
114 | #define enable_intr_remapping(mode) (-1) | 115 | #define enable_intr_remapping(mode) (-1) |