Skip to content

Commit

Permalink
genirq/msi: Refactor iommu_dma_compose_msi_msg()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jason Gunthorpe committed Feb 21, 2025
1 parent 1f7df3a commit 9349887
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 49 deletions.
18 changes: 0 additions & 18 deletions drivers/iommu/dma-iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
5 changes: 1 addition & 4 deletions drivers/irqchip/irq-gic-v2m.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,14 @@ 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
msg->data = data->hwirq;
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 = {
Expand Down
13 changes: 3 additions & 10 deletions drivers/irqchip/irq-gic-v3-its.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
12 changes: 4 additions & 8 deletions drivers/irqchip/irq-gic-v3-mbi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 2 additions & 3 deletions drivers/irqchip/irq-ls-scfg-msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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,
Expand Down
6 changes: 0 additions & 6 deletions include/linux/iommu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand All @@ -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 */

/*
Expand Down
28 changes: 28 additions & 0 deletions include/linux/msi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
/**
Expand Down

0 comments on commit 9349887

Please sign in to comment.