aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2012-03-30 14:47:02 -0400
committerJoerg Roedel <joerg.roedel@amd.com>2012-05-07 08:34:59 -0400
commit0c3f173a88c4ae3e4253427cf574a59ad5352918 (patch)
treed34364dc8d7926de75ec486ce579b478d23098e3 /arch/x86
parent4f3d8b67ad3090f9fb72f8235d21cde53cd24b79 (diff)
iommu/vt-d: Convert IR ioapic-setup to use remap_ops
The IOAPIC setup routine for interrupt remapping is VT-d specific. Move it to the irq_remap_ops and add a call helper function. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> Acked-by: Yinghai Lu <yinghai@kernel.org> Cc: David Woodhouse <dwmw2@infradead.org> Cc: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/include/asm/intr_remapping.h15
-rw-r--r--arch/x86/kernel/apic/io_apic.c68
2 files changed, 16 insertions, 67 deletions
diff --git a/arch/x86/include/asm/intr_remapping.h b/arch/x86/include/asm/intr_remapping.h
index 55aa892a53e3..a22e1f1ac7ec 100644
--- a/arch/x86/include/asm/intr_remapping.h
+++ b/arch/x86/include/asm/intr_remapping.h
@@ -24,6 +24,9 @@
24 24
25#ifdef CONFIG_IRQ_REMAP 25#ifdef CONFIG_IRQ_REMAP
26 26
27struct IO_APIC_route_entry;
28struct io_apic_irq_attr;
29
27extern int intr_remapping_enabled; 30extern int intr_remapping_enabled;
28 31
29extern void setup_intr_remapping(void); 32extern void setup_intr_remapping(void);
@@ -33,6 +36,10 @@ extern int intr_hardware_enable(void);
33extern void intr_hardware_disable(void); 36extern void intr_hardware_disable(void);
34extern int intr_hardware_reenable(int); 37extern int intr_hardware_reenable(int);
35extern int intr_enable_fault_handling(void); 38extern int intr_enable_fault_handling(void);
39extern int intr_setup_ioapic_entry(int irq,
40 struct IO_APIC_route_entry *entry,
41 unsigned int destination, int vector,
42 struct io_apic_irq_attr *attr);
36 43
37#else /* CONFIG_IRQ_REMAP */ 44#else /* CONFIG_IRQ_REMAP */
38 45
@@ -45,7 +52,13 @@ static inline int intr_hardware_enable(void) { return -ENODEV; }
45static inline void intr_hardware_disable(void) { } 52static inline void intr_hardware_disable(void) { }
46static inline int intr_hardware_reenable(int eim) { return -ENODEV; } 53static inline int intr_hardware_reenable(int eim) { return -ENODEV; }
47static inline int intr_enable_fault_handling(void) { return -ENODEV; } 54static inline int intr_enable_fault_handling(void) { return -ENODEV; }
48 55static inline int intr_setup_ioapic_entry(int irq,
56 struct IO_APIC_route_entry *entry,
57 unsigned int destination, int vector,
58 struct io_apic_irq_attr *attr)
59{
60 return -ENODEV;
61}
49#endif /* CONFIG_IRQ_REMAP */ 62#endif /* CONFIG_IRQ_REMAP */
50 63
51#endif /* __X86_INTR_REMAPPING_H */ 64#endif /* __X86_INTR_REMAPPING_H */
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 1151fdccaad6..e1ab625fb9ca 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1362,77 +1362,13 @@ static void ioapic_register_intr(unsigned int irq, struct irq_cfg *cfg,
1362 fasteoi ? "fasteoi" : "edge"); 1362 fasteoi ? "fasteoi" : "edge");
1363} 1363}
1364 1364
1365
1366static int setup_ir_ioapic_entry(int irq,
1367 struct IR_IO_APIC_route_entry *entry,
1368 unsigned int destination, int vector,
1369 struct io_apic_irq_attr *attr)
1370{
1371 int index;
1372 struct irte irte;
1373 int ioapic_id = mpc_ioapic_id(attr->ioapic);
1374 struct intel_iommu *iommu = map_ioapic_to_ir(ioapic_id);
1375
1376 if (!iommu) {
1377 pr_warn("No mapping iommu for ioapic %d\n", ioapic_id);
1378 return -ENODEV;
1379 }
1380
1381 index = alloc_irte(iommu, irq, 1);
1382 if (index < 0) {
1383 pr_warn("Failed to allocate IRTE for ioapic %d\n", ioapic_id);
1384 return -ENOMEM;
1385 }
1386
1387 prepare_irte(&irte, vector, destination);
1388
1389 /* Set source-id of interrupt request */
1390 set_ioapic_sid(&irte, ioapic_id);
1391
1392 modify_irte(irq, &irte);
1393
1394 apic_printk(APIC_VERBOSE, KERN_DEBUG "IOAPIC[%d]: "
1395 "Set IRTE entry (P:%d FPD:%d Dst_Mode:%d "
1396 "Redir_hint:%d Trig_Mode:%d Dlvry_Mode:%X "
1397 "Avail:%X Vector:%02X Dest:%08X "
1398 "SID:%04X SQ:%X SVT:%X)\n",
1399 attr->ioapic, irte.present, irte.fpd, irte.dst_mode,
1400 irte.redir_hint, irte.trigger_mode, irte.dlvry_mode,
1401 irte.avail, irte.vector, irte.dest_id,
1402 irte.sid, irte.sq, irte.svt);
1403
1404 memset(entry, 0, sizeof(*entry));
1405
1406 entry->index2 = (index >> 15) & 0x1;
1407 entry->zero = 0;
1408 entry->format = 1;
1409 entry->index = (index & 0x7fff);
1410 /*
1411 * IO-APIC RTE will be configured with virtual vector.
1412 * irq handler will do the explicit EOI to the io-apic.
1413 */
1414 entry->vector = attr->ioapic_pin;
1415 entry->mask = 0; /* enable IRQ */
1416 entry->trigger = attr->trigger;
1417 entry->polarity = attr->polarity;
1418
1419 /* Mask level triggered irqs.
1420 * Use IRQ_DELAYED_DISABLE for edge triggered irqs.
1421 */
1422 if (attr->trigger)
1423 entry->mask = 1;
1424
1425 return 0;
1426}
1427
1428static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry, 1365static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry,
1429 unsigned int destination, int vector, 1366 unsigned int destination, int vector,
1430 struct io_apic_irq_attr *attr) 1367 struct io_apic_irq_attr *attr)
1431{ 1368{
1432 if (intr_remapping_enabled) 1369 if (intr_remapping_enabled)
1433 return setup_ir_ioapic_entry(irq, 1370 return intr_setup_ioapic_entry(irq, entry, destination,
1434 (struct IR_IO_APIC_route_entry *)entry, 1371 vector, attr);
1435 destination, vector, attr);
1436 1372
1437 memset(entry, 0, sizeof(*entry)); 1373 memset(entry, 0, sizeof(*entry));
1438 1374