aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/intel_intr_remapping.c
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 /drivers/iommu/intel_intr_remapping.c
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>
Diffstat (limited to 'drivers/iommu/intel_intr_remapping.c')
-rw-r--r--drivers/iommu/intel_intr_remapping.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/drivers/iommu/intel_intr_remapping.c b/drivers/iommu/intel_intr_remapping.c
index f495eba4b6a..25372c1f3c8 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};