[PATCH 2/3] PCI: endpoint: pci-ep-msi: Make embedded doorbell IRQ exclusive
From: Koichiro Den
Date: Tue Jul 28 2026 - 13:51:08 EST
Embedded doorbells may use the same virq for several messages. This does
not mean the IRQ itself should be shared. Consumers only need to request
each distinct virq once, as vNTB and pci-epf-test already do.
IRQF_SHARED would let different EPFs register handlers for the same IRQ.
The embedded doorbell interface cannot tell which EPF a write targets,
so every handler would handle it.
Only the first EPF can allocate doorbells today, so this cannot happen
yet. Drop IRQF_SHARED before extending the embedded backend to non-first
EPFs. A second request for the same IRQ will then fail with -EBUSY
instead of attaching another handler.
Signed-off-by: Koichiro Den <den@xxxxxxxxxxxxx>
---
drivers/pci/endpoint/pci-ep-msi.c | 9 +++++----
include/linux/pci-epf.h | 3 ++-
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/pci/endpoint/pci-ep-msi.c b/drivers/pci/endpoint/pci-ep-msi.c
index 0855c7930abb..a123a189b4e6 100644
--- a/drivers/pci/endpoint/pci-ep-msi.c
+++ b/drivers/pci/endpoint/pci-ep-msi.c
@@ -10,7 +10,6 @@
#include <linux/cleanup.h>
#include <linux/device.h>
#include <linux/export.h>
-#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/module.h>
#include <linux/msi.h>
@@ -112,8 +111,11 @@ static int pci_epf_alloc_doorbell_embedded(struct pci_epf *epf, u16 num_db)
*
* Still, pci_epf_alloc_doorbell() allows requesting multiple doorbells.
* For such backends we replicate the same address/data for each entry
- * and mark the IRQ as shared (IRQF_SHARED). Consumers must treat them
- * as equivalent "kick" doorbells.
+ * as equivalent "kick" doorbells. Consumers must request each distinct
+ * IRQ only once.
+ *
+ * Keep the IRQ exclusive because the source cannot identify which EPF
+ * rang the doorbell.
*/
for (i = 0; i < num_db; i++)
msg[i] = (struct pci_epf_doorbell_msg) {
@@ -121,7 +123,6 @@ static int pci_epf_alloc_doorbell_embedded(struct pci_epf *epf, u16 num_db)
.msg.address_hi = (u32)(addr >> 32),
.msg.data = doorbell->u.db_mmio.data,
.virq = doorbell->u.db_mmio.irq,
- .irq_flags = IRQF_SHARED,
.type = PCI_EPF_DOORBELL_EMBEDDED,
.bar = doorbell->bar,
.offset = (doorbell->bar == NO_BAR) ? 0 :
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 8a6c64a35890..e5b9a79beb93 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -163,7 +163,8 @@ enum pci_epf_doorbell_type {
* For MSI-backed doorbells this is the MSI message, while for
* "embedded" doorbells this represents an MMIO write that asserts
* an interrupt on the EP side.
- * @virq: IRQ number of this doorbell message
+ * @virq: IRQ number of this doorbell message. Multiple messages may use the
+ * same IRQ; consumers must request each distinct IRQ only once.
* @irq_flags: Required flags for request_irq()/request_threaded_irq().
* Callers may OR-in additional flags (e.g. IRQF_ONESHOT).
* @type: Doorbell type.
--
2.51.0