diff options
| -rw-r--r-- | arch/ia64/include/asm/irq_remapping.h | 4 | ||||
| -rw-r--r-- | arch/x86/include/asm/irq_remapping.h | 120 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/apic.c | 30 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 297 | ||||
| -rw-r--r-- | drivers/iommu/Makefile | 2 | ||||
| -rw-r--r-- | drivers/iommu/dmar.c | 9 | ||||
| -rw-r--r-- | drivers/iommu/intel-iommu.c | 3 | ||||
| -rw-r--r-- | drivers/iommu/intel_irq_remapping.c (renamed from drivers/iommu/intr_remapping.c) | 355 | ||||
| -rw-r--r-- | drivers/iommu/intr_remapping.h | 17 | ||||
| -rw-r--r-- | drivers/iommu/irq_remapping.c | 164 | ||||
| -rw-r--r-- | drivers/iommu/irq_remapping.h | 88 | ||||
| -rw-r--r-- | include/linux/dmar.h | 85 |
12 files changed, 724 insertions, 450 deletions
diff --git a/arch/ia64/include/asm/irq_remapping.h b/arch/ia64/include/asm/irq_remapping.h new file mode 100644 index 000000000000..a8687b1d8906 --- /dev/null +++ b/arch/ia64/include/asm/irq_remapping.h | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | #ifndef __IA64_INTR_REMAPPING_H | ||
| 2 | #define __IA64_INTR_REMAPPING_H | ||
| 3 | #define irq_remapping_enabled 0 | ||
| 4 | #endif | ||
diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h index 47d99934580f..dcb0c7231028 100644 --- a/arch/x86/include/asm/irq_remapping.h +++ b/arch/x86/include/asm/irq_remapping.h | |||
| @@ -1,45 +1,103 @@ | |||
| 1 | #ifndef _ASM_X86_IRQ_REMAPPING_H | 1 | /* |
| 2 | #define _ASM_X86_IRQ_REMAPPING_H | 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 | ||
| 5 | 24 | ||
| 6 | #ifdef CONFIG_IRQ_REMAP | 25 | #ifdef CONFIG_IRQ_REMAP |
| 7 | static void irq_remap_modify_chip_defaults(struct irq_chip *chip); | 26 | |
| 8 | static inline void prepare_irte(struct irte *irte, int vector, | 27 | struct IO_APIC_route_entry; |
| 9 | unsigned int dest) | 28 | struct io_apic_irq_attr; |
| 29 | struct pci_dev; | ||
| 30 | |||
| 31 | extern int irq_remapping_enabled; | ||
| 32 | |||
| 33 | extern void setup_irq_remapping_ops(void); | ||
| 34 | extern int irq_remapping_supported(void); | ||
| 35 | extern int irq_remapping_prepare(void); | ||
| 36 | extern int irq_remapping_enable(void); | ||
| 37 | extern void irq_remapping_disable(void); | ||
| 38 | extern int irq_remapping_reenable(int); | ||
| 39 | extern int irq_remap_enable_fault_handling(void); | ||
| 40 | extern int setup_ioapic_remapped_entry(int irq, | ||
| 41 | struct IO_APIC_route_entry *entry, | ||
| 42 | unsigned int destination, | ||
| 43 | int vector, | ||
| 44 | struct io_apic_irq_attr *attr); | ||
| 45 | extern int set_remapped_irq_affinity(struct irq_data *data, | ||
| 46 | const struct cpumask *mask, | ||
| 47 | bool force); | ||
| 48 | extern void free_remapped_irq(int irq); | ||
| 49 | extern void compose_remapped_msi_msg(struct pci_dev *pdev, | ||
| 50 | unsigned int irq, unsigned int dest, | ||
| 51 | struct msi_msg *msg, u8 hpet_id); | ||
| 52 | extern int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec); | ||
| 53 | extern int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq, | ||
| 54 | int index, int sub_handle); | ||
| 55 | extern int setup_hpet_msi_remapped(unsigned int irq, unsigned int id); | ||
| 56 | |||
| 57 | #else /* CONFIG_IRQ_REMAP */ | ||
| 58 | |||
| 59 | #define irq_remapping_enabled 0 | ||
| 60 | |||
| 61 | static inline void setup_irq_remapping_ops(void) { } | ||
| 62 | static inline int irq_remapping_supported(void) { return 0; } | ||
| 63 | static inline int irq_remapping_prepare(void) { return -ENODEV; } | ||
| 64 | static inline int irq_remapping_enable(void) { return -ENODEV; } | ||
| 65 | static inline void irq_remapping_disable(void) { } | ||
| 66 | static inline int irq_remapping_reenable(int eim) { return -ENODEV; } | ||
| 67 | static inline int irq_remap_enable_fault_handling(void) { return -ENODEV; } | ||
| 68 | static inline int setup_ioapic_remapped_entry(int irq, | ||
| 69 | struct IO_APIC_route_entry *entry, | ||
| 70 | unsigned int destination, | ||
| 71 | int vector, | ||
| 72 | struct io_apic_irq_attr *attr) | ||
| 73 | { | ||
| 74 | return -ENODEV; | ||
| 75 | } | ||
| 76 | static inline int set_remapped_irq_affinity(struct irq_data *data, | ||
| 77 | const struct cpumask *mask, | ||
| 78 | bool force) | ||
| 10 | { | 79 | { |
| 11 | memset(irte, 0, sizeof(*irte)); | 80 | return 0; |
| 12 | |||
| 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 | } | 81 | } |
| 28 | static inline bool irq_remapped(struct irq_cfg *cfg) | 82 | static inline void free_remapped_irq(int irq) { } |
| 83 | static inline void compose_remapped_msi_msg(struct pci_dev *pdev, | ||
| 84 | unsigned int irq, unsigned int dest, | ||
| 85 | struct msi_msg *msg, u8 hpet_id) | ||
| 29 | { | 86 | { |
| 30 | return cfg->irq_2_iommu.iommu != NULL; | ||
| 31 | } | 87 | } |
| 32 | #else | 88 | static inline int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec) |
| 33 | static void prepare_irte(struct irte *irte, int vector, unsigned int dest) | ||
| 34 | { | 89 | { |
| 90 | return -ENODEV; | ||
| 35 | } | 91 | } |
| 36 | static inline bool irq_remapped(struct irq_cfg *cfg) | 92 | static inline int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq, |
| 93 | int index, int sub_handle) | ||
| 37 | { | 94 | { |
| 38 | return false; | 95 | return -ENODEV; |
| 39 | } | 96 | } |
| 40 | static inline void irq_remap_modify_chip_defaults(struct irq_chip *chip) | 97 | static inline int setup_hpet_msi_remapped(unsigned int irq, unsigned int id) |
| 41 | { | 98 | { |
| 99 | return -ENODEV; | ||
| 42 | } | 100 | } |
| 43 | #endif | 101 | #endif /* CONFIG_IRQ_REMAP */ |
| 44 | 102 | ||
| 45 | #endif /* _ASM_X86_IRQ_REMAPPING_H */ | 103 | #endif /* __X86_IRQ_REMAPPING_H */ |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index edc24480469f..3722179a49db 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <linux/smp.h> | 35 | #include <linux/smp.h> |
| 36 | #include <linux/mm.h> | 36 | #include <linux/mm.h> |
| 37 | 37 | ||
| 38 | #include <asm/irq_remapping.h> | ||
| 38 | #include <asm/perf_event.h> | 39 | #include <asm/perf_event.h> |
| 39 | #include <asm/x86_init.h> | 40 | #include <asm/x86_init.h> |
| 40 | #include <asm/pgalloc.h> | 41 | #include <asm/pgalloc.h> |
| @@ -1441,8 +1442,8 @@ void __init bsp_end_local_APIC_setup(void) | |||
| 1441 | * Now that local APIC setup is completed for BP, configure the fault | 1442 | * Now that local APIC setup is completed for BP, configure the fault |
| 1442 | * handling for interrupt remapping. | 1443 | * handling for interrupt remapping. |
| 1443 | */ | 1444 | */ |
| 1444 | if (intr_remapping_enabled) | 1445 | if (irq_remapping_enabled) |
| 1445 | enable_drhd_fault_handling(); | 1446 | irq_remap_enable_fault_handling(); |
| 1446 | 1447 | ||
| 1447 | } | 1448 | } |
| 1448 | 1449 | ||
| @@ -1517,7 +1518,7 @@ void enable_x2apic(void) | |||
| 1517 | int __init enable_IR(void) | 1518 | int __init enable_IR(void) |
| 1518 | { | 1519 | { |
| 1519 | |||
