aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2012-03-30 14:47:03 -0400
committerJoerg Roedel <joerg.roedel@amd.com>2012-05-07 08:34:59 -0400
commit4c1bad6a0af1e297c8d05365e65af89d8c7bf9d1 (patch)
treea369a0bfd4c744b67e218ef294753a1ccc38b13a
parent0c3f173a88c4ae3e4253427cf574a59ad5352918 (diff)
iommu/vt-d: Convert IR set_affinity function to remap_ops
The function to set interrupt affinity with interrupt remapping enabled is Intel specific too. So move it to the irq_remap_ops too. 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>
-rw-r--r--arch/x86/include/asm/intr_remapping.h9
-rw-r--r--arch/x86/kernel/apic/io_apic.c69
-rw-r--r--drivers/iommu/intel_intr_remapping.c54
-rw-r--r--drivers/iommu/intr_remapping.c9
-rw-r--r--drivers/iommu/intr_remapping.h6
5 files changed, 80 insertions, 67 deletions
diff --git a/arch/x86/include/asm/intr_remapping.h b/arch/x86/include/asm/intr_remapping.h
index a22e1f1ac7ec..ae933ecfd8f0 100644
--- a/arch/x86/include/asm/intr_remapping.h
+++ b/arch/x86/include/asm/intr_remapping.h
@@ -40,6 +40,9 @@ extern int intr_setup_ioapic_entry(int irq,
40 struct IO_APIC_route_entry *entry, 40 struct IO_APIC_route_entry *entry,
41 unsigned int destination, int vector, 41 unsigned int destination, int vector,
42 struct io_apic_irq_attr *attr); 42 struct io_apic_irq_attr *attr);
43extern int intr_set_affinity(struct irq_data *data,
44 const struct cpumask *mask,
45 bool force);
43 46
44#else /* CONFIG_IRQ_REMAP */ 47#else /* CONFIG_IRQ_REMAP */
45 48
@@ -59,6 +62,12 @@ static inline int intr_setup_ioapic_entry(int irq,
59{ 62{
60 return -ENODEV; 63 return -ENODEV;
61} 64}
65static inline int intr_set_affinity(struct irq_data *data,
66 const struct cpumask *mask,
67 bool force)
68{
69 return 0;
70}
62#endif /* CONFIG_IRQ_REMAP */ 71#endif /* CONFIG_IRQ_REMAP */
63 72
64#endif /* __X86_INTR_REMAPPING_H */ 73#endif /* __X86_INTR_REMAPPING_H */
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index e1ab625fb9ca..a97c79aa25cf 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2327,71 +2327,6 @@ ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
2327 return ret; 2327 return ret;
2328} 2328}
2329 2329
2330#ifdef CONFIG_IRQ_REMAP
2331
2332/*
2333 * Migrate the IO-APIC irq in the presence of intr-remapping.
2334 *
2335 * For both level and edge triggered, irq migration is a simple atomic
2336 * update(of vector and cpu destination) of IRTE and flush the hardware cache.
2337 *
2338 * For level triggered, we eliminate the io-apic RTE modification (with the
2339 * updated vector information), by using a virtual vector (io-apic pin number).
2340 * Real vector that is used for interrupting cpu will be coming from
2341 * the interrupt-remapping table entry.
2342 *
2343 * As the migration is a simple atomic update of IRTE, the same mechanism
2344 * is used to migrate MSI irq's in the presence of interrupt-remapping.
2345 */
2346static int
2347ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
2348 bool force)
2349{
2350 struct irq_cfg *cfg = data->chip_data;
2351 unsigned int dest, irq = data->irq;
2352 struct irte irte;
2353
2354 if (!cpumask_intersects(mask, cpu_online_mask))
2355 return -EINVAL;
2356
2357 if (get_irte(irq, &irte))
2358 return -EBUSY;
2359
2360 if (assign_irq_vector(irq, cfg, mask))
2361 return -EBUSY;
2362
2363 dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask);
2364
2365 irte.vector = cfg->vector;
2366 irte.dest_id = IRTE_DEST(dest);
2367
2368 /*
2369 * Atomically updates the IRTE with the new destination, vector
2370 * and flushes the interrupt entry cache.
2371 */
2372 modify_irte(irq, &irte);
2373
2374 /*
2375 * After this point, all the interrupts will start arriving
2376 * at the new destination. So, time to cleanup the previous
2377 * vector allocation.
2378 */
2379 if (cfg->move_in_progress)
2380 send_cleanup_vector(cfg);
2381
2382 cpumask_copy(data->affinity, mask);
2383 return 0;
2384}
2385
2386#else
2387static inline int
2388ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
2389 bool force)
2390{
2391 return 0;
2392}
2393#endif
2394
2395asmlinkage void smp_irq_move_cleanup_interrupt(void) 2330asmlinkage void smp_irq_move_cleanup_interrupt(void)
2396{ 2331{
2397 unsigned vector, me; 2332 unsigned vector, me;
@@ -2636,7 +2571,7 @@ static void irq_remap_modify_chip_defaults(struct irq_chip *chip)
2636 chip->irq_eoi = ir_ack_apic_level; 2571 chip->irq_eoi = ir_ack_apic_level;
2637 2572
2638#ifdef CONFIG_SMP 2573#ifdef CONFIG_SMP
2639 chip->irq_set_affinity = ir_ioapic_set_affinity; 2574 chip->irq_set_affinity = intr_set_affinity;
2640#endif 2575#endif
2641} 2576}
2642#endif /* CONFIG_IRQ_REMAP */ 2577#endif /* CONFIG_IRQ_REMAP */
@@ -3826,7 +3761,7 @@ void __init setup_ioapic_dest(void)
3826 mask = apic->target_cpus(); 3761 mask = apic->target_cpus();
3827 3762
3828 if (intr_remapping_enabled) 3763 if (intr_remapping_enabled)
3829 ir_ioapic_set_affinity(idata, mask, false); 3764 intr_set_affinity(idata, mask, false);
3830 else 3765 else
3831 ioapic_set_affinity(idata, mask, false); 3766 ioapic_set_affinity(idata, mask, false);
3832 } 3767 }
diff --git a/drivers/iommu/intel_intr_remapping.c b/drivers/iommu/intel_intr_remapping.c
index f495eba4b6ab..25372c1f3c8c 100644
--- a/drivers/iommu/intel_intr_remapping.c
+++ b/drivers/iommu/intel_intr_remapping.c
@@ -901,6 +901,59 @@ static int intel_setup_ioapic_entry(int irq,
901 return 0; 901 return 0;
902} 902}
903 903
904/*
905 * Migrate the IO-APIC irq in the presence of intr-remapping.
906 *
907 * For both level and edge triggered, irq migration is a simple atomic
908 * update(of vector and cpu destination) of IRTE and flush the hardware cache.
909 *
910 * For level triggered, we eliminate the io-apic RTE modification (with the
911 * updated vector information), by using a virtual vector (io-apic pin number).
912 * Real vector that is used for interrupting cpu will be coming from
913 * the interrupt-remapping table entry.
914 *
915 * As the migration is a simple atomic update of IRTE, the same mechanism
916 * is used to migrate MSI irq's in the presence of interrupt-remapping.
917 */
918static int
919intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
920 bool force)
921{
922 struct irq_cfg *cfg = data->chip_data;
923 unsigned int dest, irq = data->irq;
924 struct irte irte;
925
926 if (!cpumask_intersects(mask, cpu_online_mask))
927 return -EINVAL;
928
929 if (get_irte(irq, &irte))
930 return -EBUSY;
931
932 if (assign_irq_vector(irq, cfg, mask))
933 return -EBUSY;
934
935 dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask);
936
937 irte.vector = cfg->vector;
938 irte.dest_id = IRTE_DEST(dest);
939
940 /*
941 * Atomically updates the IRTE with the new destination, vector
942 * and flushes the interrupt entry cache.
943 */
944 modify_irte(irq, &irte);
945
946 /*
947 * After this point, all the interrupts will start arriving
948 * at the new destination. So, time to cleanup the previous
949 * vector allocation.
950 */
951 if (cfg->move_in_progress)
952 send_cleanup_vector(cfg);
953
954 cpumask_copy(data->affinity, mask);
955 return 0;
956}
904 957
905struct irq_remap_ops intel_irq_remap_ops = { 958struct irq_remap_ops intel_irq_remap_ops = {
906 .supported = intel_intr_remapping_supported, 959 .supported = intel_intr_remapping_supported,
@@ -910,4 +963,5 @@ struct irq_remap_ops intel_irq_remap_ops = {
910 .hardware_reenable = reenable_intr_remapping, 963 .hardware_reenable = reenable_intr_remapping,
911 .enable_faulting = enable_drhd_fault_handling, 964 .enable_faulting = enable_drhd_fault_handling,
912 .setup_ioapic_entry = intel_setup_ioapic_entry, 965 .setup_ioapic_entry = intel_setup_ioapic_entry,
966 .set_affinity = intel_ioapic_set_affinity,
913}; 967};
diff --git a/drivers/iommu/intr_remapping.c b/drivers/iommu/intr_remapping.c
index 739148ab2538..2f4f27ffb861 100644
--- a/drivers/iommu/intr_remapping.c
+++ b/drivers/iommu/intr_remapping.c
@@ -110,3 +110,12 @@ int intr_setup_ioapic_entry(int irq,
110 return remap_ops->setup_ioapic_entry(irq, entry, destination, 110 return remap_ops->setup_ioapic_entry(irq, entry, destination,
111 vector, attr); 111 vector, attr);
112} 112}
113
114int intr_set_affinity(struct irq_data *data, const struct cpumask *mask,
115 bool force)
116{
117 if (!remap_ops || !remap_ops->set_affinity)
118 return 0;
119
120 return remap_ops->set_affinity(data, mask, force);
121}
diff --git a/drivers/iommu/intr_remapping.h b/drivers/iommu/intr_remapping.h
index e8994f2b3bbe..e0bc6e0ba1fb 100644
--- a/drivers/iommu/intr_remapping.h
+++ b/drivers/iommu/intr_remapping.h
@@ -26,6 +26,8 @@
26 26
27struct IO_APIC_route_entry; 27struct IO_APIC_route_entry;
28struct io_apic_irq_attr; 28struct io_apic_irq_attr;
29struct irq_data;
30struct cpumask;
29 31
30extern int disable_intremap; 32extern int disable_intremap;
31extern int disable_sourceid_checking; 33extern int disable_sourceid_checking;
@@ -54,6 +56,10 @@ struct irq_remap_ops {
54 int (*setup_ioapic_entry)(int irq, struct IO_APIC_route_entry *, 56 int (*setup_ioapic_entry)(int irq, struct IO_APIC_route_entry *,
55 unsigned int, int, 57 unsigned int, int,
56 struct io_apic_irq_attr *); 58 struct io_apic_irq_attr *);
59
60 /* Set the CPU affinity of a remapped interrupt */
61 int (*set_affinity)(struct irq_data *data, const struct cpumask *mask,
62 bool force);
57}; 63};
58 64
59extern struct irq_remap_ops intel_irq_remap_ops; 65extern struct irq_remap_ops intel_irq_remap_ops;