These new functions use the supplied IOMMU in order to map and unmap MSI translation register(s). Signed-off-by: Pavel Fedin <p.fedin@xxxxxxxxxxx> --- drivers/irqchip/irq-gic-v3-its.c | 31 +++++++++++++++++++++++++++++++ include/linux/irqchip/arm-gic-v3.h | 2 ++ include/linux/msi.h | 12 ++++++++++++ 3 files changed, 45 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index e23d1d1..b97dfd7 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -29,6 +29,7 @@ #include <linux/of_platform.h> #include <linux/percpu.h> #include <linux/slab.h> +#include <linux/vfio.h> #include <linux/irqchip.h> #include <linux/irqchip/arm-gic-v3.h> @@ -1257,8 +1258,38 @@ out: return 0; } +#if IS_ENABLED(CONFIG_VFIO) + +static int its_vfio_map(struct irq_domain *domain, + const struct vfio_iommu_driver_ops *ops, + void *iommu_data) +{ + struct msi_domain_info *msi_info = msi_get_domain_info(domain); + struct its_node *its = msi_info->data; + u64 addr = its->phys_base + GIC_V3_ITS_CONTROL_SIZE; + + return ops->map(iommu_data, addr, addr, 1, IOMMU_READ|IOMMU_WRITE); +} + +static void its_vfio_unmap(struct irq_domain *domain, + const struct vfio_iommu_driver_ops *ops, + void *iommu_data) +{ + struct msi_domain_info *msi_info = msi_get_domain_info(domain); + struct its_node *its = msi_info->data; + u64 addr = its->phys_base + GIC_V3_ITS_CONTROL_SIZE; + + ops->unmap(iommu_data, addr, 1); +} + +#endif + static struct msi_domain_ops its_msi_domain_ops = { .msi_prepare = its_msi_prepare, +#if IS_ENABLED(CONFIG_VFIO) + .vfio_map = its_vfio_map, + .vfio_unmap = its_vfio_unmap, +#endif }; static int its_irq_gic_domain_alloc(struct irq_domain *domain, diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index bff3eee..dfd2bed 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -241,6 +241,8 @@ #define GITS_BASER_TYPE_RESERVED6 6 #define GITS_BASER_TYPE_RESERVED7 7 +#define GIC_V3_ITS_CONTROL_SIZE 0x10000 + /* * ITS commands */ diff --git a/include/linux/msi.h b/include/linux/msi.h index f71a25e..48faea9 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -155,6 +155,8 @@ void arch_restore_msi_irqs(struct pci_dev *dev); void default_teardown_msi_irqs(struct pci_dev *dev); void default_restore_msi_irqs(struct pci_dev *dev); +struct vfio_iommu_driver_ops; + struct msi_controller { struct module *owner; struct device *dev; @@ -189,6 +191,8 @@ struct msi_domain_info; * @msi_finish: Optional callbacl to finalize the allocation * @set_desc: Set the msi descriptor for an interrupt * @handle_error: Optional error handler if the allocation fails + * @vfio_map: Map the MSI hardware for VFIO + * @vfio_unmap: Unmap the MSI hardware for VFIO * * @get_hwirq, @msi_init and @msi_free are callbacks used by * msi_create_irq_domain() and related interfaces @@ -218,6 +222,14 @@ struct msi_domain_ops { struct msi_desc *desc); int (*handle_error)(struct irq_domain *domain, struct msi_desc *desc, int error); +#if IS_ENABLED(CONFIG_VFIO) + int (*vfio_map)(struct irq_domain *domain, + const struct vfio_iommu_driver_ops *ops, + void *iommu_data); + void (*vfio_unmap)(struct irq_domain *domain, + const struct vfio_iommu_driver_ops *ops, + void *iommu_data); +#endif }; /** -- 2.4.4 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html