[tip: irq/core] genirq/msi: Make msi_get_virq() device domain aware

From: tip-bot2 for Ahmed S. Darwish
Date: Mon Dec 05 2022 - 13:28:39 EST


The following commit has been merged into the irq/core branch of tip:

Commit-ID: 98043704f375f63a47efeff123ab92fcf34b95e6
Gitweb: https://git.kernel.org/tip/98043704f375f63a47efeff123ab92fcf34b95e6
Author: Ahmed S. Darwish <darwi@xxxxxxxxxxxxx>
AuthorDate: Fri, 25 Nov 2022 00:24:25 +01:00
Committer: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
CommitterDate: Mon, 05 Dec 2022 19:20:59 +01:00

genirq/msi: Make msi_get_virq() device domain aware

In preparation of the upcoming per device multi MSI domain support, change
the interface to support lookups based on domain id and zero based index
within the domain.

Signed-off-by: Ahmed S. Darwish <darwi@xxxxxxxxxxxxx>
Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Reviewed-by: Kevin Tian <kevin.tian@xxxxxxxxx>
Acked-by: Marc Zyngier <maz@xxxxxxxxxx>
Link: https://lore.kernel.org/r/20221124230314.044613697@xxxxxxxxxxxxx

---
include/linux/msi_api.h | 14 +++++++++++++-
kernel/irq/msi.c | 19 +++++++++++++------
2 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/include/linux/msi_api.h b/include/linux/msi_api.h
index 4dbbce6..8640171 100644
--- a/include/linux/msi_api.h
+++ b/include/linux/msi_api.h
@@ -18,6 +18,18 @@ enum msi_domain_ids {
MSI_MAX_DEVICE_IRQDOMAINS,
};

-unsigned int msi_get_virq(struct device *dev, unsigned int index);
+unsigned int msi_domain_get_virq(struct device *dev, unsigned int domid, unsigned int index);
+
+/**
+ * msi_get_virq - Lookup the Linux interrupt number for a MSI index on the default interrupt domain
+ * @dev: Device for which the lookup happens
+ * @index: The MSI index to lookup
+ *
+ * Return: The Linux interrupt number on success (> 0), 0 if not found
+ */
+static inline unsigned int msi_get_virq(struct device *dev, unsigned int index)
+{
+ return msi_domain_get_virq(dev, MSI_DEFAULT_DOMAIN, index);
+}

#endif
diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c
index ec08d1f..e1593c1 100644
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -337,26 +337,32 @@ struct msi_desc *msi_next_desc(struct device *dev, unsigned int domid,
EXPORT_SYMBOL_GPL(msi_next_desc);

/**
- * msi_get_virq - Return Linux interrupt number of a MSI interrupt
+ * msi_domain_get_virq - Lookup the Linux interrupt number for a MSI index on a interrupt domain
* @dev: Device to operate on
+ * @domid: Domain ID of the interrupt domain associated to the device
* @index: MSI interrupt index to look for (0-based)
*
* Return: The Linux interrupt number on success (> 0), 0 if not found
*/
-unsigned int msi_get_virq(struct device *dev, unsigned int index)
+unsigned int msi_domain_get_virq(struct device *dev, unsigned int domid, unsigned int index)
{
struct msi_desc *desc;
unsigned int ret = 0;
+ bool pcimsi = false;
struct xarray *xa;
- bool pcimsi;

if (!dev->msi.data)
return 0;

- pcimsi = dev_is_pci(dev) ? to_pci_dev(dev)->msi_enabled : false;
+ if (WARN_ON_ONCE(index > MSI_MAX_INDEX || domid >= MSI_MAX_DEVICE_IRQDOMAINS))
+ return 0;
+
+ /* This check is only valid for the PCI default MSI domain */
+ if (dev_is_pci(dev) && domid == MSI_DEFAULT_DOMAIN)
+ pcimsi = to_pci_dev(dev)->msi_enabled;

msi_lock_descs(dev);
- xa = &dev->msi.data->__domains[MSI_DEFAULT_DOMAIN].store;
+ xa = &dev->msi.data->__domains[domid].store;
desc = xa_load(xa, pcimsi ? 0 : index);
if (desc && desc->irq) {
/*
@@ -371,10 +377,11 @@ unsigned int msi_get_virq(struct device *dev, unsigned int index)
ret = desc->irq;
}
}
+
msi_unlock_descs(dev);
return ret;
}
-EXPORT_SYMBOL_GPL(msi_get_virq);
+EXPORT_SYMBOL_GPL(msi_domain_get_virq);

#ifdef CONFIG_SYSFS
static struct attribute *msi_dev_attrs[] = {