diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2012-03-30 14:47:03 -0400 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2012-05-07 08:34:59 -0400 |
commit | 4c1bad6a0af1e297c8d05365e65af89d8c7bf9d1 (patch) | |
tree | a369a0bfd4c744b67e218ef294753a1ccc38b13a | |
parent | 0c3f173a88c4ae3e4253427cf574a59ad5352918 (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.h | 9 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 69 | ||||
-rw-r--r-- | drivers/iommu/intel_intr_remapping.c | 54 | ||||
-rw-r--r-- | drivers/iommu/intr_remapping.c | 9 | ||||
-rw-r--r-- | drivers/iommu/intr_remapping.h | 6 |
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); |
43 | extern 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 | } |
65 | static 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 | */ | ||
2346 | static int | ||
2347 | ir_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 | ||
2387 | static inline int | ||
2388 | ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, | ||
2389 | bool force) | ||
2390 | { | ||
2391 | return 0; | ||
2392 | } | ||
2393 | #endif | ||
2394 | |||
2395 | asmlinkage void smp_irq_move_cleanup_interrupt(void) | 2330 | asmlinkage 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 | */ | ||
918 | static int | ||
919 | intel_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 | ||
905 | struct irq_remap_ops intel_irq_remap_ops = { | 958 | struct 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 | |||
114 | int 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 | ||
27 | struct IO_APIC_route_entry; | 27 | struct IO_APIC_route_entry; |
28 | struct io_apic_irq_attr; | 28 | struct io_apic_irq_attr; |
29 | struct irq_data; | ||
30 | struct cpumask; | ||
29 | 31 | ||
30 | extern int disable_intremap; | 32 | extern int disable_intremap; |
31 | extern int disable_sourceid_checking; | 33 | extern 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 | ||
59 | extern struct irq_remap_ops intel_irq_remap_ops; | 65 | extern struct irq_remap_ops intel_irq_remap_ops; |