]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
genirq/msi: Refactor iommu_dma_compose_msi_msg()
authorJason Gunthorpe <jgg@nvidia.com>
Thu, 20 Feb 2025 01:31:37 +0000 (17:31 -0800)
committerJason Gunthorpe <jgg@nvidia.com>
Fri, 21 Feb 2025 14:04:12 +0000 (10:04 -0400)
The two-step process to translate the MSI address involves two functions,
iommu_dma_prepare_msi() and iommu_dma_compose_msi_msg().

Previously iommu_dma_compose_msi_msg() needed to be in the iommu layer as
it had to dereference the opaque cookie pointer. Now, the previous patch
changed the cookie pointer into an integer so there is no longer any need
for the iommu layer to be involved.

Further, the call sites of iommu_dma_compose_msi_msg() all follow the same
pattern of setting an MSI message address_hi/lo to non-translated and then
immediately calling iommu_dma_compose_msi_msg().

Refactor iommu_dma_compose_msi_msg() into msi_msg_set_addr() that directly
accepts the u64 version of the address and simplifies all the callers.

Move the new helper to linux/msi.h since it has nothing to do with iommu.

Aside from refactoring, this logically prepares for the next patch, which
allows multiple implementation options for iommu_dma_prepare_msi(). So, it
does not make sense to have the iommu_dma_compose_msi_msg() in dma-iommu.c
as it no longer provides the only iommu_dma_prepare_msi() implementation.

Link: https://patch.msgid.link/r/eda62a9bafa825e9cdabd7ddc61ad5a21c32af24.1740014950.git.nicolinc@nvidia.com
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/iommu/dma-iommu.c
drivers/irqchip/irq-gic-v2m.c
drivers/irqchip/irq-gic-v3-its.c
drivers/irqchip/irq-gic-v3-mbi.c
drivers/irqchip/irq-ls-scfg-msi.c
include/linux/iommu.h
include/linux/msi.h

index 0f0caf59023c792c3c6b0c4ff091c5347312238c..bf91e014d179147ac4b612529be29372712c3e40 100644 (file)
@@ -1836,24 +1836,6 @@ int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr)
        return 0;
 }
 
-/**
- * iommu_dma_compose_msi_msg() - Apply translation to an MSI message
- * @desc: MSI descriptor prepared by iommu_dma_prepare_msi()
- * @msg: MSI message containing target physical address
- */
-void iommu_dma_compose_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
-{
-#ifdef CONFIG_IRQ_MSI_IOMMU
-       if (desc->iommu_msi_shift) {
-               u64 msi_iova = desc->iommu_msi_iova << desc->iommu_msi_shift;
-
-               msg->address_hi = upper_32_bits(msi_iova);
-               msg->address_lo = lower_32_bits(msi_iova) |
-                                 (msg->address_lo & ((1 << desc->iommu_msi_shift) - 1));
-       }
-#endif
-}
-
 static int iommu_dma_init(void)
 {
        if (is_kdump_kernel())
index be35c5349986aa64094fd37474fdda2f896cf7e3..57e0470e0d1335c18b6fa745da9a4a66431c50ba 100644 (file)
@@ -87,9 +87,6 @@ static void gicv2m_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
        struct v2m_data *v2m = irq_data_get_irq_chip_data(data);
        phys_addr_t addr = gicv2m_get_msi_addr(v2m, data->hwirq);
 
-       msg->address_hi = upper_32_bits(addr);
-       msg->address_lo = lower_32_bits(addr);
-
        if (v2m->flags & GICV2M_GRAVITON_ADDRESS_ONLY)
                msg->data = 0;
        else
@@ -97,7 +94,7 @@ static void gicv2m_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
        if (v2m->flags & GICV2M_NEEDS_SPI_OFFSET)
                msg->data -= v2m->spi_offset;
 
-       iommu_dma_compose_msi_msg(irq_data_get_msi_desc(data), msg);
+       msi_msg_set_addr(irq_data_get_msi_desc(data), msg, addr);
 }
 
 static struct irq_chip gicv2m_irq_chip = {
index 8c3ec5734f1ef47decdf231e50e5d06fe49cb9eb..ce0bf70b9eaf89762419415b7e8303a14f026884 100644 (file)
@@ -1809,17 +1809,10 @@ static u64 its_irq_get_msi_base(struct its_device *its_dev)
 static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
 {
        struct its_device *its_dev = irq_data_get_irq_chip_data(d);
-       struct its_node *its;
-       u64 addr;
-
-       its = its_dev->its;
-       addr = its->get_msi_base(its_dev);
-
-       msg->address_lo         = lower_32_bits(addr);
-       msg->address_hi         = upper_32_bits(addr);
-       msg->data               = its_get_event_id(d);
 
-       iommu_dma_compose_msi_msg(irq_data_get_msi_desc(d), msg);
+       msg->data = its_get_event_id(d);
+       msi_msg_set_addr(irq_data_get_msi_desc(d), msg,
+                        its_dev->its->get_msi_base(its_dev));
 }
 
 static int its_irq_set_irqchip_state(struct irq_data *d,
index 3fe870f8ee1744fdd087a73ce1fd4d665871d8de..a6510128611e01145d5f6f29e33c7a8ad3016a35 100644 (file)
@@ -147,22 +147,18 @@ static const struct irq_domain_ops mbi_domain_ops = {
 
 static void mbi_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
 {
-       msg[0].address_hi = upper_32_bits(mbi_phys_base + GICD_SETSPI_NSR);
-       msg[0].address_lo = lower_32_bits(mbi_phys_base + GICD_SETSPI_NSR);
        msg[0].data = data->parent_data->hwirq;
-
-       iommu_dma_compose_msi_msg(irq_data_get_msi_desc(data), msg);
+       msi_msg_set_addr(irq_data_get_msi_desc(data), &msg[0],
+                        mbi_phys_base + GICD_SETSPI_NSR);
 }
 
 static void mbi_compose_mbi_msg(struct irq_data *data, struct msi_msg *msg)
 {
        mbi_compose_msi_msg(data, msg);
 
-       msg[1].address_hi = upper_32_bits(mbi_phys_base + GICD_CLRSPI_NSR);
-       msg[1].address_lo = lower_32_bits(mbi_phys_base + GICD_CLRSPI_NSR);
        msg[1].data = data->parent_data->hwirq;
-
-       iommu_dma_compose_msi_msg(irq_data_get_msi_desc(data), &msg[1]);
+       msi_msg_set_addr(irq_data_get_msi_desc(data), &msg[1],
+                        mbi_phys_base + GICD_CLRSPI_NSR);
 }
 
 static bool mbi_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
index c0e1aafe468c321f30b680f6556e1597f49077fc..3cb80796cc7ccaa5a940e11a39ae056f29a7e522 100644 (file)
@@ -87,8 +87,6 @@ static void ls_scfg_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
 {
        struct ls_scfg_msi *msi_data = irq_data_get_irq_chip_data(data);
 
-       msg->address_hi = upper_32_bits(msi_data->msiir_addr);
-       msg->address_lo = lower_32_bits(msi_data->msiir_addr);
        msg->data = data->hwirq;
 
        if (msi_affinity_flag) {
@@ -98,7 +96,8 @@ static void ls_scfg_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
                msg->data |= cpumask_first(mask);
        }
 
-       iommu_dma_compose_msi_msg(irq_data_get_msi_desc(data), msg);
+       msi_msg_set_addr(irq_data_get_msi_desc(data), msg,
+                        msi_data->msiir_addr);
 }
 
 static int ls_scfg_msi_set_affinity(struct irq_data *irq_data,
index 38c65e92ecd091975c42e630e7db50a4133166c4..caee952febd4f9357c76628aa5bdbce7cac34786 100644 (file)
@@ -1508,7 +1508,6 @@ static inline void iommu_debugfs_setup(void) {}
 int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base);
 
 int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr);
-void iommu_dma_compose_msi_msg(struct msi_desc *desc, struct msi_msg *msg);
 
 #else /* CONFIG_IOMMU_DMA */
 
@@ -1524,11 +1523,6 @@ static inline int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_a
 {
        return 0;
 }
-
-static inline void iommu_dma_compose_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
-{
-}
-
 #endif /* CONFIG_IOMMU_DMA */
 
 /*
index fc4f3774c3af6ea9b40cc5401d73ac504b878c53..8d97b890faeca2d50f02c3f4a2857c9aebf646c3 100644 (file)
@@ -299,6 +299,34 @@ static inline void msi_desc_set_iommu_msi_iova(struct msi_desc *desc, u64 msi_io
 #endif
 }
 
+/**
+ * msi_msg_set_addr() - Set MSI address in an MSI message
+ *
+ * @desc:      MSI descriptor that may carry an IOVA base address for MSI via @iommu_msi_iova/shift
+ * @msg:       Target MSI message to set its address_hi and address_lo
+ * @msi_addr:  Physical address to set the MSI message
+ *
+ * Notes:
+ *  - Override @msi_addr using the IOVA base address in the @desc if @iommu_msi_shift is set
+ *  - Otherwise, simply set @msi_addr to @msg
+ */
+static inline void msi_msg_set_addr(struct msi_desc *desc, struct msi_msg *msg,
+                                   phys_addr_t msi_addr)
+{
+#ifdef CONFIG_IRQ_MSI_IOMMU
+       if (desc->iommu_msi_shift) {
+               u64 msi_iova = desc->iommu_msi_iova << desc->iommu_msi_shift;
+
+               msg->address_hi = upper_32_bits(msi_iova);
+               msg->address_lo = lower_32_bits(msi_iova) |
+                                 (msi_addr & ((1 << desc->iommu_msi_shift) - 1));
+               return;
+       }
+#endif
+       msg->address_hi = upper_32_bits(msi_addr);
+       msg->address_lo = lower_32_bits(msi_addr);
+}
+
 int msi_domain_insert_msi_desc(struct device *dev, unsigned int domid,
                               struct msi_desc *init_desc);
 /**