diff options
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 44 | ||||
-rw-r--r-- | arch/x86/kernel/apic/probe_64.c | 2 | ||||
-rw-r--r-- | include/linux/dmar.h | 45 |
3 files changed, 48 insertions, 43 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index e074eac5bd35..cf27795c641c 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -554,16 +554,12 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq | |||
554 | 554 | ||
555 | apic = entry->apic; | 555 | apic = entry->apic; |
556 | pin = entry->pin; | 556 | pin = entry->pin; |
557 | #ifdef CONFIG_INTR_REMAP | ||
558 | /* | 557 | /* |
559 | * With interrupt-remapping, destination information comes | 558 | * With interrupt-remapping, destination information comes |
560 | * from interrupt-remapping table entry. | 559 | * from interrupt-remapping table entry. |
561 | */ | 560 | */ |
562 | if (!irq_remapped(irq)) | 561 | if (!irq_remapped(irq)) |
563 | io_apic_write(apic, 0x11 + pin*2, dest); | 562 | io_apic_write(apic, 0x11 + pin*2, dest); |
564 | #else | ||
565 | io_apic_write(apic, 0x11 + pin*2, dest); | ||
566 | #endif | ||
567 | reg = io_apic_read(apic, 0x10 + pin*2); | 563 | reg = io_apic_read(apic, 0x10 + pin*2); |
568 | reg &= ~IO_APIC_REDIR_VECTOR_MASK; | 564 | reg &= ~IO_APIC_REDIR_VECTOR_MASK; |
569 | reg |= vector; | 565 | reg |= vector; |
@@ -1419,9 +1415,8 @@ void __setup_vector_irq(int cpu) | |||
1419 | } | 1415 | } |
1420 | 1416 | ||
1421 | static struct irq_chip ioapic_chip; | 1417 | static struct irq_chip ioapic_chip; |
1422 | #ifdef CONFIG_INTR_REMAP | ||
1423 | static struct irq_chip ir_ioapic_chip; | 1418 | static struct irq_chip ir_ioapic_chip; |
1424 | #endif | 1419 | static struct irq_chip msi_ir_chip; |
1425 | 1420 | ||
1426 | #define IOAPIC_AUTO -1 | 1421 | #define IOAPIC_AUTO -1 |
1427 | #define IOAPIC_EDGE 0 | 1422 | #define IOAPIC_EDGE 0 |
@@ -1460,7 +1455,6 @@ static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long t | |||
1460 | else | 1455 | else |
1461 | desc->status &= ~IRQ_LEVEL; | 1456 | desc->status &= ~IRQ_LEVEL; |
1462 | 1457 | ||
1463 | #ifdef CONFIG_INTR_REMAP | ||
1464 | if (irq_remapped(irq)) { | 1458 | if (irq_remapped(irq)) { |
1465 | desc->status |= IRQ_MOVE_PCNTXT; | 1459 | desc->status |= IRQ_MOVE_PCNTXT; |
1466 | if (trigger) | 1460 | if (trigger) |
@@ -1472,7 +1466,7 @@ static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long t | |||
1472 | handle_edge_irq, "edge"); | 1466 | handle_edge_irq, "edge"); |
1473 | return; | 1467 | return; |
1474 | } | 1468 | } |
1475 | #endif | 1469 | |
1476 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || | 1470 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || |
1477 | trigger == IOAPIC_LEVEL) | 1471 | trigger == IOAPIC_LEVEL) |
1478 | set_irq_chip_and_handler_name(irq, &ioapic_chip, | 1472 | set_irq_chip_and_handler_name(irq, &ioapic_chip, |
@@ -1493,7 +1487,6 @@ int setup_ioapic_entry(int apic_id, int irq, | |||
1493 | */ | 1487 | */ |
1494 | memset(entry,0,sizeof(*entry)); | 1488 | memset(entry,0,sizeof(*entry)); |
1495 | 1489 | ||
1496 | #ifdef CONFIG_INTR_REMAP | ||
1497 | if (intr_remapping_enabled) { | 1490 | if (intr_remapping_enabled) { |
1498 | struct intel_iommu *iommu = map_ioapic_to_ir(apic_id); | 1491 | struct intel_iommu *iommu = map_ioapic_to_ir(apic_id); |
1499 | struct irte irte; | 1492 | struct irte irte; |
@@ -1535,9 +1528,7 @@ int setup_ioapic_entry(int apic_id, int irq, | |||
1535 | * irq handler will do the explicit EOI to the io-apic. | 1528 | * irq handler will do the explicit EOI to the io-apic. |
1536 | */ | 1529 | */ |
1537 | ir_entry->vector = pin; | 1530 | ir_entry->vector = pin; |
1538 | } else | 1531 | } else { |
1539 | #endif | ||
1540 | { | ||
1541 | entry->delivery_mode = apic->irq_delivery_mode; | 1532 | entry->delivery_mode = apic->irq_delivery_mode; |
1542 | entry->dest_mode = apic->irq_dest_mode; | 1533 | entry->dest_mode = apic->irq_dest_mode; |
1543 | entry->dest = destination; | 1534 | entry->dest = destination; |
@@ -1662,10 +1653,8 @@ static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin, | |||
1662 | { | 1653 | { |
1663 | struct IO_APIC_route_entry entry; | 1654 | struct IO_APIC_route_entry entry; |
1664 | 1655 | ||
1665 | #ifdef CONFIG_INTR_REMAP | ||
1666 | if (intr_remapping_enabled) | 1656 | if (intr_remapping_enabled) |
1667 | return; | 1657 | return; |
1668 | #endif | ||
1669 | 1658 | ||
1670 | memset(&entry, 0, sizeof(entry)); | 1659 | memset(&entry, 0, sizeof(entry)); |
1671 | 1660 | ||
@@ -2395,6 +2384,11 @@ static void set_ir_ioapic_affinity_irq(unsigned int irq, | |||
2395 | 2384 | ||
2396 | set_ir_ioapic_affinity_irq_desc(desc, mask); | 2385 | set_ir_ioapic_affinity_irq_desc(desc, mask); |
2397 | } | 2386 | } |
2387 | #else | ||
2388 | static inline void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc, | ||
2389 | const struct cpumask *mask) | ||
2390 | { | ||
2391 | } | ||
2398 | #endif | 2392 | #endif |
2399 | 2393 | ||
2400 | asmlinkage void smp_irq_move_cleanup_interrupt(void) | 2394 | asmlinkage void smp_irq_move_cleanup_interrupt(void) |
@@ -2883,10 +2877,8 @@ static inline void __init check_timer(void) | |||
2883 | * 8259A. | 2877 | * 8259A. |
2884 | */ | 2878 | */ |
2885 | if (pin1 == -1) { | 2879 | if (pin1 == -1) { |
2886 | #ifdef CONFIG_INTR_REMAP | ||
2887 | if (intr_remapping_enabled) | 2880 | if (intr_remapping_enabled) |
2888 | panic("BIOS bug: timer not connected to IO-APIC"); | 2881 | panic("BIOS bug: timer not connected to IO-APIC"); |
2889 | #endif | ||
2890 | pin1 = pin2; | 2882 | pin1 = pin2; |
2891 | apic1 = apic2; | 2883 | apic1 = apic2; |
2892 | no_pin1 = 1; | 2884 | no_pin1 = 1; |
@@ -2922,10 +2914,8 @@ static inline void __init check_timer(void) | |||
2922 | clear_IO_APIC_pin(0, pin1); | 2914 | clear_IO_APIC_pin(0, pin1); |
2923 | goto out; | 2915 | goto out; |
2924 | } | 2916 | } |
2925 | #ifdef CONFIG_INTR_REMAP | ||
2926 | if (intr_remapping_enabled) | 2917 | if (intr_remapping_enabled) |
2927 | panic("timer doesn't work through Interrupt-remapped IO-APIC"); | 2918 | panic("timer doesn't work through Interrupt-remapped IO-APIC"); |
2928 | #endif | ||
2929 | local_irq_disable(); | 2919 | local_irq_disable(); |
2930 | clear_IO_APIC_pin(apic1, pin1); | 2920 | clear_IO_APIC_pin(apic1, pin1); |
2931 | if (!no_pin1) | 2921 | if (!no_pin1) |
@@ -3219,9 +3209,7 @@ void destroy_irq(unsigned int irq) | |||
3219 | if (desc) | 3209 | if (desc) |
3220 | desc->chip_data = cfg; | 3210 | desc->chip_data = cfg; |
3221 | 3211 | ||
3222 | #ifdef CONFIG_INTR_REMAP | ||
3223 | free_irte(irq); | 3212 | free_irte(irq); |
3224 | #endif | ||
3225 | spin_lock_irqsave(&vector_lock, flags); | 3213 | spin_lock_irqsave(&vector_lock, flags); |
3226 | __clear_irq_vector(irq, cfg); | 3214 | __clear_irq_vector(irq, cfg); |
3227 | spin_unlock_irqrestore(&vector_lock, flags); | 3215 | spin_unlock_irqrestore(&vector_lock, flags); |
@@ -3247,7 +3235,6 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms | |||
3247 | 3235 | ||
3248 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); | 3236 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); |
3249 | 3237 | ||
3250 | #ifdef CONFIG_INTR_REMAP | ||
3251 | if (irq_remapped(irq)) { | 3238 | if (irq_remapped(irq)) { |
3252 | struct irte irte; | 3239 | struct irte irte; |
3253 | int ir_index; | 3240 | int ir_index; |
@@ -3273,9 +3260,7 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms | |||
3273 | MSI_ADDR_IR_SHV | | 3260 | MSI_ADDR_IR_SHV | |
3274 | MSI_ADDR_IR_INDEX1(ir_index) | | 3261 | MSI_ADDR_IR_INDEX1(ir_index) | |
3275 | MSI_ADDR_IR_INDEX2(ir_index); | 3262 | MSI_ADDR_IR_INDEX2(ir_index); |
3276 | } else | 3263 | } else { |
3277 | #endif | ||
3278 | { | ||
3279 | if (x2apic_enabled()) | 3264 | if (x2apic_enabled()) |
3280 | msg->address_hi = MSI_ADDR_BASE_HI | | 3265 | msg->address_hi = MSI_ADDR_BASE_HI | |
3281 | MSI_ADDR_EXT_DEST_ID(dest); | 3266 | MSI_ADDR_EXT_DEST_ID(dest); |
@@ -3392,6 +3377,7 @@ static struct irq_chip msi_ir_chip = { | |||
3392 | #endif | 3377 | #endif |
3393 | .retrigger = ioapic_retrigger_irq, | 3378 | .retrigger = ioapic_retrigger_irq, |
3394 | }; | 3379 | }; |
3380 | #endif | ||
3395 | 3381 | ||
3396 | /* | 3382 | /* |
3397 | * Map the PCI dev to the corresponding remapping hardware unit | 3383 | * Map the PCI dev to the corresponding remapping hardware unit |
@@ -3419,7 +3405,6 @@ static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec) | |||
3419 | } | 3405 | } |
3420 | return index; | 3406 | return index; |
3421 | } | 3407 | } |
3422 | #endif | ||
3423 | 3408 | ||
3424 | static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) | 3409 | static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) |
3425 | { | 3410 | { |
@@ -3433,7 +3418,6 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) | |||
3433 | set_irq_msi(irq, msidesc); | 3418 | set_irq_msi(irq, msidesc); |
3434 | write_msi_msg(irq, &msg); | 3419 | write_msi_msg(irq, &msg); |
3435 | 3420 | ||
3436 | #ifdef CONFIG_INTR_REMAP | ||
3437 | if (irq_remapped(irq)) { | 3421 | if (irq_remapped(irq)) { |
3438 | struct irq_desc *desc = irq_to_desc(irq); | 3422 | struct irq_desc *desc = irq_to_desc(irq); |
3439 | /* | 3423 | /* |
@@ -3442,7 +3426,6 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) | |||
3442 | desc->status |= IRQ_MOVE_PCNTXT; | 3426 | desc->status |= IRQ_MOVE_PCNTXT; |
3443 | set_irq_chip_and_handler_name(irq, &msi_ir_chip, handle_edge_irq, "edge"); | 3427 | set_irq_chip_and_handler_name(irq, &msi_ir_chip, handle_edge_irq, "edge"); |
3444 | } else | 3428 | } else |
3445 | #endif | ||
3446 | set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); | 3429 | set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); |
3447 | 3430 | ||
3448 | dev_printk(KERN_DEBUG, &dev->dev, "irq %d for MSI/MSI-X\n", irq); | 3431 | dev_printk(KERN_DEBUG, &dev->dev, "irq %d for MSI/MSI-X\n", irq); |
@@ -3456,11 +3439,8 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
3456 | int ret, sub_handle; | 3439 | int ret, sub_handle; |
3457 | struct msi_desc *msidesc; | 3440 | struct msi_desc *msidesc; |
3458 | unsigned int irq_want; | 3441 | unsigned int irq_want; |
3459 | |||
3460 | #ifdef CONFIG_INTR_REMAP | ||
3461 | struct intel_iommu *iommu = 0; | 3442 | struct intel_iommu *iommu = 0; |
3462 | int index = 0; | 3443 | int index = 0; |
3463 | #endif | ||
3464 | 3444 | ||
3465 | irq_want = nr_irqs_gsi; | 3445 | irq_want = nr_irqs_gsi; |
3466 | sub_handle = 0; | 3446 | sub_handle = 0; |
@@ -3469,7 +3449,6 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
3469 | if (irq == 0) | 3449 | if (irq == 0) |
3470 | return -1; | 3450 | return -1; |
3471 | irq_want = irq + 1; | 3451 | irq_want = irq + 1; |
3472 | #ifdef CONFIG_INTR_REMAP | ||
3473 | if (!intr_remapping_enabled) | 3452 | if (!intr_remapping_enabled) |
3474 | goto no_ir; | 3453 | goto no_ir; |
3475 | 3454 | ||
@@ -3497,7 +3476,6 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
3497 | set_irte_irq(irq, iommu, index, sub_handle); | 3476 | set_irte_irq(irq, iommu, index, sub_handle); |
3498 | } | 3477 | } |
3499 | no_ir: | 3478 | no_ir: |
3500 | #endif | ||
3501 | ret = setup_msi_irq(dev, msidesc, irq); | 3479 | ret = setup_msi_irq(dev, msidesc, irq); |
3502 | if (ret < 0) | 3480 | if (ret < 0) |
3503 | goto error; | 3481 | goto error; |
@@ -4032,11 +4010,9 @@ void __init setup_ioapic_dest(void) | |||
4032 | else | 4010 | else |
4033 | mask = apic->target_cpus(); | 4011 | mask = apic->target_cpus(); |
4034 | 4012 | ||
4035 | #ifdef CONFIG_INTR_REMAP | ||
4036 | if (intr_remapping_enabled) | 4013 | if (intr_remapping_enabled) |
4037 | set_ir_ioapic_affinity_irq_desc(desc, mask); | 4014 | set_ir_ioapic_affinity_irq_desc(desc, mask); |
4038 | else | 4015 | else |
4039 | #endif | ||
4040 | set_ioapic_affinity_irq_desc(desc, mask); | 4016 | set_ioapic_affinity_irq_desc(desc, mask); |
4041 | } | 4017 | } |
4042 | 4018 | ||
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c index 8297c2b8ed20..1783652bb0e5 100644 --- a/arch/x86/kernel/apic/probe_64.c +++ b/arch/x86/kernel/apic/probe_64.c | |||
@@ -69,14 +69,12 @@ void __init default_setup_apic_routing(void) | |||
69 | printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); | 69 | printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); |
70 | } | 70 | } |
71 | 71 | ||
72 | #ifdef CONFIG_X86_X2APIC | ||
73 | /* | 72 | /* |
74 | * Now that apic routing model is selected, configure the | 73 | * Now that apic routing model is selected, configure the |
75 | * fault handling for intr remapping. | 74 | * fault handling for intr remapping. |
76 | */ | 75 | */ |
77 | if (intr_remapping_enabled) | 76 | if (intr_remapping_enabled) |
78 | enable_drhd_fault_handling(); | 77 | enable_drhd_fault_handling(); |
79 | #endif | ||
80 | } | 78 | } |
81 | 79 | ||
82 | /* Same for both flat and physical. */ | 80 | /* Same for both flat and physical. */ |
diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 8a035aec14a9..2f3427468956 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h | |||
@@ -26,9 +26,8 @@ | |||
26 | #include <linux/msi.h> | 26 | #include <linux/msi.h> |
27 | #include <linux/irqreturn.h> | 27 | #include <linux/irqreturn.h> |
28 | 28 | ||
29 | #if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP) | ||
30 | struct intel_iommu; | 29 | struct intel_iommu; |
31 | 30 | #if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP) | |
32 | struct dmar_drhd_unit { | 31 | struct dmar_drhd_unit { |
33 | struct list_head list; /* list of drhd units */ | 32 | struct list_head list; /* list of drhd units */ |
34 | struct acpi_dmar_header *hdr; /* ACPI header */ | 33 | struct acpi_dmar_header *hdr; /* ACPI header */ |
@@ -52,7 +51,6 @@ extern int dmar_dev_scope_init(void); | |||
52 | extern void detect_intel_iommu(void); | 51 | extern void detect_intel_iommu(void); |
53 | extern int enable_drhd_fault_handling(void); | 52 | extern int enable_drhd_fault_handling(void); |
54 | 53 | ||
55 | |||
56 | extern int parse_ioapics_under_ir(void); | 54 | extern int parse_ioapics_under_ir(void); |
57 | extern int alloc_iommu(struct dmar_drhd_unit *); | 55 | extern int alloc_iommu(struct dmar_drhd_unit *); |
58 | #else | 56 | #else |
@@ -65,12 +63,12 @@ static inline int dmar_table_init(void) | |||
65 | { | 63 | { |
66 | return -ENODEV; | 64 | return -ENODEV; |
67 | } | 65 | } |
66 | static inline int enable_drhd_fault_handling(void) | ||
67 | { | ||
68 | return -1; | ||
69 | } | ||
68 | #endif /* !CONFIG_DMAR && !CONFIG_INTR_REMAP */ | 70 | #endif /* !CONFIG_DMAR && !CONFIG_INTR_REMAP */ |
69 | 71 | ||
70 | #ifdef CONFIG_INTR_REMAP | ||
71 | extern int intr_remapping_enabled; | ||
72 | extern int enable_intr_remapping(int); | ||
73 | |||
74 | struct irte { | 72 | struct irte { |
75 | union { | 73 | union { |
76 | struct { | 74 | struct { |
@@ -99,6 +97,10 @@ struct irte { | |||
99 | __u64 high; | 97 | __u64 high; |
100 | }; | 98 | }; |
101 | }; | 99 | }; |
100 | #ifdef CONFIG_INTR_REMAP | ||
101 | extern int intr_remapping_enabled; | ||
102 | extern int enable_intr_remapping(int); | ||
103 | |||
102 | extern int get_irte(int irq, struct irte *entry); | 104 | extern int get_irte(int irq, struct irte *entry); |
103 | extern int modify_irte(int irq, struct irte *irte_modified); | 105 | extern int modify_irte(int irq, struct irte *irte_modified); |
104 | extern int alloc_irte(struct intel_iommu *iommu, int irq, u16 count); | 106 | extern int alloc_irte(struct intel_iommu *iommu, int irq, u16 count); |
@@ -113,6 +115,35 @@ extern int irq_remapped(int irq); | |||
113 | extern struct intel_iommu *map_dev_to_ir(struct pci_dev *dev); | 115 | extern struct intel_iommu *map_dev_to_ir(struct pci_dev *dev); |
114 | extern struct intel_iommu *map_ioapic_to_ir(int apic); | 116 | extern struct intel_iommu *map_ioapic_to_ir(int apic); |
115 | #else | 117 | #else |
118 | static inline int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) | ||
119 | { | ||
120 | return -1; | ||
121 | } | ||
122 | static inline int modify_irte(int irq, struct irte *irte_modified) | ||
123 | { | ||
124 | return -1; | ||
125 | } | ||
126 | static inline int free_irte(int irq) | ||
127 | { | ||
128 | return -1; | ||
129 | } | ||
130 | static inline int map_irq_to_irte_handle(int irq, u16 *sub_handle) | ||
131 | { | ||
132 | return -1; | ||
133 | } | ||
134 | static inline int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, | ||
135 | u16 sub_handle) | ||
136 | { | ||
137 | return -1; | ||
138 | } | ||
139 | static inline struct intel_iommu *map_dev_to_ir(struct pci_dev *dev) | ||
140 | { | ||
141 | return NULL; | ||
142 | } | ||
143 | static inline struct intel_iommu *map_ioapic_to_ir(int apic) | ||
144 | { | ||
145 | return NULL; | ||
146 | } | ||
116 | #define irq_remapped(irq) (0) | 147 | #define irq_remapped(irq) (0) |
117 | #define enable_intr_remapping(mode) (-1) | 148 | #define enable_intr_remapping(mode) (-1) |
118 | #define intr_remapping_enabled (0) | 149 | #define intr_remapping_enabled (0) |