* [PATCH 0/3] PCI: endpoint: Support vNTB as a non-first EPF
@ 2026-07-28 17:23 Koichiro Den
2026-07-28 17:23 ` [PATCH 1/3] PCI: endpoint: pci-epf-vntb: Pass PF/VF number when BAR programming Koichiro Den
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Koichiro Den @ 2026-07-28 17:23 UTC (permalink / raw)
To: Manivannan Sadhasivam, Frank Li, Niklas Cassel,
Krzysztof Wilczyński, Kishon Vijay Abraham I, Bjorn Helgaas,
Jon Mason, Dave Jiang, Allen Hubbe
Cc: linux-pci, ntb, linux-kernel
Hi,
This series allows a vNTB endpoint function to be instantiated as PF1+.
vntb_epf_mw_set_trans() programs the memory-window BAR with hardcoded
function numbers (0, 0), so binding the EPF to any other function
programs the wrong one. Patch 1 resolves it.
The platform-MSI doorbell path can currently populate messages only for
the first EPF attached to the EPC. Supporting multiple EPFs in that path
requires separate work. This series leaves it unchanged and lets a
non-first EPF use the embedded doorbell instead.
The embedded-doorbell auxiliary-resource interface is
vendor-independent. Its current DesignWare provider exposes one EPC-wide
source. Since the generic interface cannot identify which EPF's peer
issued a write to a shared source, patch 2 makes the IRQ exclusive.
Patch 3 lets non-first EPFs try the embedded doorbell. If another EPF
has already requested the IRQ, vNTB retains its polling fallback.
I tested the embedded doorbell path on R-Car S4 with the proposed DMA
endpoint function as PF0 and vNTB as PF1.
Best regards,
Koichiro
Koichiro Den (3):
PCI: endpoint: pci-epf-vntb: Pass PF/VF number when BAR programming
PCI: endpoint: pci-ep-msi: Make embedded doorbell IRQ exclusive
PCI: endpoint: pci-ep-msi: Let non-first EPFs use embedded doorbells
drivers/pci/endpoint/functions/pci-epf-vntb.c | 3 +-
drivers/pci/endpoint/pci-ep-msi.c | 40 ++++++++++---------
include/linux/pci-epf.h | 3 +-
3 files changed, 26 insertions(+), 20 deletions(-)
base-commit: e6ff30150738af5c7aa20fad08b74cbf9b86d3a2
--
2.51.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/3] PCI: endpoint: pci-epf-vntb: Pass PF/VF number when BAR programming
2026-07-28 17:23 [PATCH 0/3] PCI: endpoint: Support vNTB as a non-first EPF Koichiro Den
@ 2026-07-28 17:23 ` Koichiro Den
2026-07-28 17:38 ` sashiko-bot
2026-07-28 19:18 ` Frank Li
2026-07-28 17:23 ` [PATCH 2/3] PCI: endpoint: pci-ep-msi: Make embedded doorbell IRQ exclusive Koichiro Den
2026-07-28 17:23 ` [PATCH 3/3] PCI: endpoint: pci-ep-msi: Let non-first EPFs use embedded doorbells Koichiro Den
2 siblings, 2 replies; 10+ messages in thread
From: Koichiro Den @ 2026-07-28 17:23 UTC (permalink / raw)
To: Manivannan Sadhasivam, Frank Li, Niklas Cassel,
Krzysztof Wilczyński, Kishon Vijay Abraham I, Bjorn Helgaas,
Jon Mason, Dave Jiang, Allen Hubbe
Cc: linux-pci, ntb, linux-kernel
vntb_epf_mw_set_trans() programs the memory-window BAR through
pci_epc_set_bar() with hardcoded function numbers (0, 0), so the BAR
lands on the wrong function whenever the vNTB EPF is bound to anything
but PF0. The other BAR programming sites in the vNTB driver already pass
the EPF's own numbers.
Pass the EPF's own func_no/vfunc_no here as well.
Fixes: e35f56bb0330 ("PCI: endpoint: Support NTB transfer between RC and EP")
Signed-off-by: Koichiro Den <den@valinux.co.jp>
---
drivers/pci/endpoint/functions/pci-epf-vntb.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
index c3caec927d74..fba65abfb6b2 100644
--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
+++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
@@ -1427,7 +1427,8 @@ static int vntb_epf_mw_set_trans(struct ntb_dev *ndev, int pidx, int idx,
epf_bar->barno = barno;
epf_bar->size = size;
- ret = pci_epc_set_bar(ntb->epf->epc, 0, 0, epf_bar);
+ ret = pci_epc_set_bar(ntb->epf->epc, ntb->epf->func_no,
+ ntb->epf->vfunc_no, epf_bar);
if (ret) {
dev_err(dev, "failure set mw trans\n");
return ret;
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/3] PCI: endpoint: pci-ep-msi: Make embedded doorbell IRQ exclusive
2026-07-28 17:23 [PATCH 0/3] PCI: endpoint: Support vNTB as a non-first EPF Koichiro Den
2026-07-28 17:23 ` [PATCH 1/3] PCI: endpoint: pci-epf-vntb: Pass PF/VF number when BAR programming Koichiro Den
@ 2026-07-28 17:23 ` Koichiro Den
2026-07-28 17:28 ` sashiko-bot
2026-07-28 19:23 ` Frank Li
2026-07-28 17:23 ` [PATCH 3/3] PCI: endpoint: pci-ep-msi: Let non-first EPFs use embedded doorbells Koichiro Den
2 siblings, 2 replies; 10+ messages in thread
From: Koichiro Den @ 2026-07-28 17:23 UTC (permalink / raw)
To: Manivannan Sadhasivam, Frank Li, Niklas Cassel,
Krzysztof Wilczyński, Kishon Vijay Abraham I, Bjorn Helgaas,
Jon Mason, Dave Jiang, Allen Hubbe
Cc: linux-pci, ntb, linux-kernel
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@valinux.co.jp>
---
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
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/3] PCI: endpoint: pci-ep-msi: Let non-first EPFs use embedded doorbells
2026-07-28 17:23 [PATCH 0/3] PCI: endpoint: Support vNTB as a non-first EPF Koichiro Den
2026-07-28 17:23 ` [PATCH 1/3] PCI: endpoint: pci-epf-vntb: Pass PF/VF number when BAR programming Koichiro Den
2026-07-28 17:23 ` [PATCH 2/3] PCI: endpoint: pci-ep-msi: Make embedded doorbell IRQ exclusive Koichiro Den
@ 2026-07-28 17:23 ` Koichiro Den
2026-07-28 17:38 ` sashiko-bot
2026-07-28 19:26 ` Frank Li
2 siblings, 2 replies; 10+ messages in thread
From: Koichiro Den @ 2026-07-28 17:23 UTC (permalink / raw)
To: Manivannan Sadhasivam, Frank Li, Niklas Cassel,
Krzysztof Wilczyński, Kishon Vijay Abraham I, Bjorn Helgaas,
Jon Mason, Dave Jiang, Allen Hubbe
Cc: linux-pci, ntb, linux-kernel
pci_epf_alloc_doorbell() rejects every EPF that is not the first one
attached to the EPC because the MSI-backed path can populate doorbell
messages only for that EPF. This also prevents non-first EPFs from using
the embedded doorbell backend.
Keep the MSI-backed path limited to the first attached EPF. Let
non-first EPFs skip it and try the embedded doorbell directly. The
embedded IRQ is exclusive, so a second embedded user fails to request
the IRQ instead of receiving another EPF's notifications.
Signed-off-by: Koichiro Den <den@valinux.co.jp>
---
drivers/pci/endpoint/pci-ep-msi.c | 31 +++++++++++++++++--------------
1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/drivers/pci/endpoint/pci-ep-msi.c b/drivers/pci/endpoint/pci-ep-msi.c
index a123a189b4e6..5ea7eef9794f 100644
--- a/drivers/pci/endpoint/pci-ep-msi.c
+++ b/drivers/pci/endpoint/pci-ep-msi.c
@@ -199,28 +199,31 @@ static int pci_epf_alloc_doorbell_msi(struct pci_epf *epf, u16 num_db)
int pci_epf_alloc_doorbell(struct pci_epf *epf, u16 num_db)
{
struct pci_epc *epc = epf->epc;
+ struct pci_epf *first_epf;
struct device *dev = &epf->dev;
int ret;
- /* TODO: Multi-EPF support */
- if (list_first_entry_or_null(&epc->pci_epf, struct pci_epf, list) != epf) {
- dev_err(dev, "Doorbell doesn't support multiple EPF\n");
- return -EINVAL;
- }
-
if (epf->db_msg)
return -EBUSY;
- ret = pci_epf_alloc_doorbell_msi(epf, num_db);
- if (!ret)
- return 0;
-
/*
- * Fall back to embedded doorbell only when platform MSI is unavailable
- * for this EPC.
+ * The MSI-backed doorbell path currently targets the first EPF attached
+ * to the EPC. Let non-first EPFs try the embedded doorbell instead.
*/
- if (ret != -ENODEV)
- return ret;
+ first_epf = list_first_entry_or_null(&epc->pci_epf, struct pci_epf,
+ list);
+ if (first_epf == epf) {
+ ret = pci_epf_alloc_doorbell_msi(epf, num_db);
+ if (!ret)
+ return 0;
+
+ /*
+ * Fall back to embedded doorbell only when platform MSI is
+ * unavailable for this EPC.
+ */
+ if (ret != -ENODEV)
+ return ret;
+ }
ret = pci_epf_alloc_doorbell_embedded(epf, num_db);
if (ret) {
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] PCI: endpoint: pci-ep-msi: Make embedded doorbell IRQ exclusive
2026-07-28 17:23 ` [PATCH 2/3] PCI: endpoint: pci-ep-msi: Make embedded doorbell IRQ exclusive Koichiro Den
@ 2026-07-28 17:28 ` sashiko-bot
2026-07-28 19:23 ` Frank Li
1 sibling, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-07-28 17:28 UTC (permalink / raw)
To: Koichiro Den; +Cc: linux-pci, ntb
> 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@valinux.co.jp>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260728172306.2751813-1-den@valinux.co.jp?part=2
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] PCI: endpoint: pci-ep-msi: Let non-first EPFs use embedded doorbells
2026-07-28 17:23 ` [PATCH 3/3] PCI: endpoint: pci-ep-msi: Let non-first EPFs use embedded doorbells Koichiro Den
@ 2026-07-28 17:38 ` sashiko-bot
2026-07-28 19:26 ` Frank Li
1 sibling, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-07-28 17:38 UTC (permalink / raw)
To: Koichiro Den; +Cc: linux-pci, ntb
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Missing cleanup of doorbell IRQ and message memory in `pci_epf_test_unbind` leads to a Use-After-Free.
--
--- Patch [3]: [PATCH 3/3] PCI: endpoint: pci-ep-msi: Let non-first EPFs use embedded doorbells ---
commit 5b37917c476823bd8dce57c08e171daf54ed33f5
Author: Koichiro Den <den@valinux.co.jp>
PCI: endpoint: pci-ep-msi: Let non-first EPFs use embedded doorbells
This patch allows non-first endpoint functions attached to an endpoint
controller to utilize embedded doorbells. It removes the restriction that
only the first endpoint function can allocate doorbells, falling back to
the embedded doorbell path directly for subsequent functions.
> diff --git a/drivers/pci/endpoint/pci-ep-msi.c b/drivers/pci/endpoint/pci-ep-msi.c
> index a123a189b4e65..5ea7eef9794f7 100644
> --- a/drivers/pci/endpoint/pci-ep-msi.c
> +++ b/drivers/pci/endpoint/pci-ep-msi.c
> @@ -199,28 +199,31 @@ static int pci_epf_alloc_doorbell_msi(struct pci_epf *epf, u16 num_db)
> int pci_epf_alloc_doorbell(struct pci_epf *epf, u16 num_db)
> {
[ ... ]
> /*
> - * Fall back to embedded doorbell only when platform MSI is unavailable
> - * for this EPC.
> + * The MSI-backed doorbell path currently targets the first EPF attached
> + * to the EPC. Let non-first EPFs try the embedded doorbell instead.
> */
> - if (ret != -ENODEV)
> - return ret;
> + first_epf = list_first_entry_or_null(&epc->pci_epf, struct pci_epf,
> + list);
> + if (first_epf == epf) {
> + ret = pci_epf_alloc_doorbell_msi(epf, num_db);
> + if (!ret)
> + return 0;
> +
> + /*
> + * Fall back to embedded doorbell only when platform MSI is
> + * unavailable for this EPC.
> + */
> + if (ret != -ENODEV)
> + return ret;
> + }
>
> ret = pci_epf_alloc_doorbell_embedded(epf, num_db);
> if (ret) {
[Severity: High]
This is a pre-existing issue, but as this patch makes it possible for more
devices to allocate doorbells, can this lead to a use-after-free when an
endpoint is unbound while a doorbell is active?
Looking at pci_epf_test_unbind() in drivers/pci/endpoint/functions/pci-epf-test.c:
drivers/pci/endpoint/functions/pci-epf-test.c:pci_epf_test_unbind() {
struct pci_epf_test *epf_test = epf_get_drvdata(epf);
struct pci_epc *epc = epf->epc;
cancel_delayed_work_sync(&epf_test->cmd_handler);
if (epc->init_complete) {
pci_epf_test_clean_dma_chan(epf_test);
pci_epf_test_clear_bar(epf);
}
pci_epf_test_free_space(epf);
}
If the host sends a command to enable the doorbell, a doorbell is allocated
and an IRQ is requested via request_threaded_irq().
If the user then unbinds the driver via configfs, pci_epf_test_unbind()
does not check for or clean up the active doorbell. This means free_irq()
and pci_epf_free_doorbell() are not called.
When the endpoint function device is later destroyed via configfs rmdir,
the epf_test structure is freed. However, the IRQ handler remains
registered with the freed epf_test pointer.
Does this allow a remote host to trigger a use-after-free kernel panic by
sending an MSI doorbell interrupt to the endpoint after unbind?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260728172306.2751813-1-den@valinux.co.jp?part=3
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] PCI: endpoint: pci-epf-vntb: Pass PF/VF number when BAR programming
2026-07-28 17:23 ` [PATCH 1/3] PCI: endpoint: pci-epf-vntb: Pass PF/VF number when BAR programming Koichiro Den
@ 2026-07-28 17:38 ` sashiko-bot
2026-07-28 19:18 ` Frank Li
1 sibling, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-07-28 17:38 UTC (permalink / raw)
To: Koichiro Den; +Cc: ntb, linux-pci
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [High] An off-by-one loop initialization error in `epf_ntb_init_epc_bar()` leaves memory window BARs beyond the first one unassigned (`NO_BAR` or `-1`). This results in negative array indexing and out-of-bounds memory accesses when `epf_ntb_mw_bar_init()` and `vntb_epf_mw_set_trans()` index into `ntb->epf->bar[barno]`.
- [High] Missing NULL checks for `epc_features` returned by `pci_epc_get_features()`, leading to a kernel panic if the underlying EPC driver does not implement the `.get_features` callback.
- [High] The virtual PCI driver `vntb_pci_driver` lacks a `.remove` callback, resulting in resource leaks of the virtual PCI bus and Use-After-Free of the NTB device structures upon module unload or EPF unbind.
--
--- Patch [1]: [PATCH 1/3] PCI: endpoint: pci-epf-vntb: Pass PF/VF number when BAR programming ---
commit fc9ce298c179bf87e88da3f2964f2fbbd870806a
Author: Koichiro Den <den@valinux.co.jp>
PCI: endpoint: pci-epf-vntb: Pass PF/VF number when BAR programming
This commit updates vntb_epf_mw_set_trans() to pass the endpoint function's
own func_no and vfunc_no instead of hardcoded zeros when programming the
memory-window BAR. This ensures the BAR is correctly configured when the
virtual NTB endpoint function is bound to a function other than PF0.
> diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
> index c3caec927d748..fba65abfb6b21 100644
> --- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
> +++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
> @@ -1427,7 +1427,8 @@ static int vntb_epf_mw_set_trans(struct ntb_dev *ndev, int pidx, int idx,
> epf_bar->barno = barno;
> epf_bar->size = size;
[Severity: High]
This isn't a bug introduced by this patch, but is it possible for barno to
be -1 here, leading to an out-of-bounds write?
Looking at epf_ntb_init_epc_bar(), the loop iterating over optional memory
window BARs incorrectly starts from BAR_MW1 instead of BAR_MW2:
drivers/pci/endpoint/functions/pci-epf-vntb.c:epf_ntb_init_epc_bar() {
...
for (bar = BAR_MW1, i = 1; i < num_mws; bar++, i++) {
...
}
If a user configures num_mws > 1, this leaves BAR_MW2 unassigned (-1). Later,
when vntb_epf_mw_set_trans() is called for idx = 1, barno is evaluated as -1.
Will epf_bar = &ntb->epf->bar[barno] then access out of bounds and corrupt
memory?
> - ret = pci_epc_set_bar(ntb->epf->epc, 0, 0, epf_bar);
> + ret = pci_epc_set_bar(ntb->epf->epc, ntb->epf->func_no,
> + ntb->epf->vfunc_no, epf_bar);
> if (ret) {
> dev_err(dev, "failure set mw trans\n");
> return ret;
Also, while reviewing this file, I noticed a few other pre-existing issues:
[Severity: High]
This is a pre-existing issue, but how is the case where epc_features returns
NULL handled?
drivers/pci/endpoint/functions/pci-epf-vntb.c:epf_ntb_configure_interrupt() {
...
epc_features = pci_epc_get_features(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no);
if (!(epc_features->msix_capable || epc_features->msi_capable)) {
...
}
If the underlying EPC driver lacks the .get_features callback,
pci_epc_get_features() returns NULL, which would cause a NULL pointer
dereference here. A similar dereference happens in
epf_ntb_config_spad_bar_alloc().
[Severity: High]
This is a pre-existing issue, but does vntb_pci_driver intentionally omit a
.remove callback?
drivers/pci/endpoint/functions/pci-epf-vntb.c:
static struct pci_driver vntb_pci_driver = {
.name = "pci-vntb",
.id_table = pci_vntb_table,
.probe = pci_vntb_probe,
};
When epf_ntb_unbind() unregisters this driver:
drivers/pci/endpoint/functions/pci-epf-vntb.c:epf_ntb_unbind() {
...
pci_unregister_driver(&vntb_pci_driver);
}
Since there is no .remove callback, ntb_unregister_device() is never called to
clean up the virtual PCI bus and its associated devices. Could this lead to a
resource leak and dangling sysdata pointers upon module unload or EPF unbind?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260728172306.2751813-1-den@valinux.co.jp?part=1
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] PCI: endpoint: pci-epf-vntb: Pass PF/VF number when BAR programming
2026-07-28 17:23 ` [PATCH 1/3] PCI: endpoint: pci-epf-vntb: Pass PF/VF number when BAR programming Koichiro Den
2026-07-28 17:38 ` sashiko-bot
@ 2026-07-28 19:18 ` Frank Li
1 sibling, 0 replies; 10+ messages in thread
From: Frank Li @ 2026-07-28 19:18 UTC (permalink / raw)
To: Koichiro Den
Cc: Manivannan Sadhasivam, Frank Li, Niklas Cassel,
Krzysztof Wilczyński, Kishon Vijay Abraham I, Bjorn Helgaas,
Jon Mason, Dave Jiang, Allen Hubbe, linux-pci, ntb, linux-kernel
On Wed, Jul 29, 2026 at 02:23:04AM +0900, Koichiro Den wrote:
> vntb_epf_mw_set_trans() programs the memory-window BAR through
> pci_epc_set_bar() with hardcoded function numbers (0, 0), so the BAR
> lands on the wrong function whenever the vNTB EPF is bound to anything
> but PF0. The other BAR programming sites in the vNTB driver already pass
> the EPF's own numbers.
>
> Pass the EPF's own func_no/vfunc_no here as well.
>
> Fixes: e35f56bb0330 ("PCI: endpoint: Support NTB transfer between RC and EP")
> Signed-off-by: Koichiro Den <den@valinux.co.jp>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/pci/endpoint/functions/pci-epf-vntb.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
> index c3caec927d74..fba65abfb6b2 100644
> --- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
> +++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
> @@ -1427,7 +1427,8 @@ static int vntb_epf_mw_set_trans(struct ntb_dev *ndev, int pidx, int idx,
> epf_bar->barno = barno;
> epf_bar->size = size;
>
> - ret = pci_epc_set_bar(ntb->epf->epc, 0, 0, epf_bar);
> + ret = pci_epc_set_bar(ntb->epf->epc, ntb->epf->func_no,
> + ntb->epf->vfunc_no, epf_bar);
> if (ret) {
> dev_err(dev, "failure set mw trans\n");
> return ret;
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] PCI: endpoint: pci-ep-msi: Make embedded doorbell IRQ exclusive
2026-07-28 17:23 ` [PATCH 2/3] PCI: endpoint: pci-ep-msi: Make embedded doorbell IRQ exclusive Koichiro Den
2026-07-28 17:28 ` sashiko-bot
@ 2026-07-28 19:23 ` Frank Li
1 sibling, 0 replies; 10+ messages in thread
From: Frank Li @ 2026-07-28 19:23 UTC (permalink / raw)
To: Koichiro Den
Cc: Manivannan Sadhasivam, Frank Li, Niklas Cassel,
Krzysztof Wilczyński, Kishon Vijay Abraham I, Bjorn Helgaas,
Jon Mason, Dave Jiang, Allen Hubbe, linux-pci, ntb, linux-kernel
On Wed, Jul 29, 2026 at 02:23:05AM +0900, Koichiro Den wrote:
> 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@valinux.co.jp>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> 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
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] PCI: endpoint: pci-ep-msi: Let non-first EPFs use embedded doorbells
2026-07-28 17:23 ` [PATCH 3/3] PCI: endpoint: pci-ep-msi: Let non-first EPFs use embedded doorbells Koichiro Den
2026-07-28 17:38 ` sashiko-bot
@ 2026-07-28 19:26 ` Frank Li
1 sibling, 0 replies; 10+ messages in thread
From: Frank Li @ 2026-07-28 19:26 UTC (permalink / raw)
To: Koichiro Den
Cc: Manivannan Sadhasivam, Frank Li, Niklas Cassel,
Krzysztof Wilczyński, Kishon Vijay Abraham I, Bjorn Helgaas,
Jon Mason, Dave Jiang, Allen Hubbe, linux-pci, ntb, linux-kernel
On Wed, Jul 29, 2026 at 02:23:06AM +0900, Koichiro Den wrote:
> pci_epf_alloc_doorbell() rejects every EPF that is not the first one
> attached to the EPC because the MSI-backed path can populate doorbell
> messages only for that EPF. This also prevents non-first EPFs from using
> the embedded doorbell backend.
>
> Keep the MSI-backed path limited to the first attached EPF. Let
> non-first EPFs skip it and try the embedded doorbell directly. The
> embedded IRQ is exclusive, so a second embedded user fails to request
> the IRQ instead of receiving another EPF's notifications.
>
> Signed-off-by: Koichiro Den <den@valinux.co.jp>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/pci/endpoint/pci-ep-msi.c | 31 +++++++++++++++++--------------
> 1 file changed, 17 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/pci/endpoint/pci-ep-msi.c b/drivers/pci/endpoint/pci-ep-msi.c
> index a123a189b4e6..5ea7eef9794f 100644
> --- a/drivers/pci/endpoint/pci-ep-msi.c
> +++ b/drivers/pci/endpoint/pci-ep-msi.c
> @@ -199,28 +199,31 @@ static int pci_epf_alloc_doorbell_msi(struct pci_epf *epf, u16 num_db)
> int pci_epf_alloc_doorbell(struct pci_epf *epf, u16 num_db)
> {
> struct pci_epc *epc = epf->epc;
> + struct pci_epf *first_epf;
> struct device *dev = &epf->dev;
> int ret;
>
> - /* TODO: Multi-EPF support */
> - if (list_first_entry_or_null(&epc->pci_epf, struct pci_epf, list) != epf) {
> - dev_err(dev, "Doorbell doesn't support multiple EPF\n");
> - return -EINVAL;
> - }
> -
> if (epf->db_msg)
> return -EBUSY;
>
> - ret = pci_epf_alloc_doorbell_msi(epf, num_db);
> - if (!ret)
> - return 0;
> -
> /*
> - * Fall back to embedded doorbell only when platform MSI is unavailable
> - * for this EPC.
> + * The MSI-backed doorbell path currently targets the first EPF attached
> + * to the EPC. Let non-first EPFs try the embedded doorbell instead.
> */
> - if (ret != -ENODEV)
> - return ret;
> + first_epf = list_first_entry_or_null(&epc->pci_epf, struct pci_epf,
> + list);
> + if (first_epf == epf) {
> + ret = pci_epf_alloc_doorbell_msi(epf, num_db);
> + if (!ret)
> + return 0;
> +
> + /*
> + * Fall back to embedded doorbell only when platform MSI is
> + * unavailable for this EPC.
> + */
> + if (ret != -ENODEV)
> + return ret;
> + }
>
> ret = pci_epf_alloc_doorbell_embedded(epf, num_db);
> if (ret) {
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-07-28 19:26 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-28 17:23 [PATCH 0/3] PCI: endpoint: Support vNTB as a non-first EPF Koichiro Den
2026-07-28 17:23 ` [PATCH 1/3] PCI: endpoint: pci-epf-vntb: Pass PF/VF number when BAR programming Koichiro Den
2026-07-28 17:38 ` sashiko-bot
2026-07-28 19:18 ` Frank Li
2026-07-28 17:23 ` [PATCH 2/3] PCI: endpoint: pci-ep-msi: Make embedded doorbell IRQ exclusive Koichiro Den
2026-07-28 17:28 ` sashiko-bot
2026-07-28 19:23 ` Frank Li
2026-07-28 17:23 ` [PATCH 3/3] PCI: endpoint: pci-ep-msi: Let non-first EPFs use embedded doorbells Koichiro Den
2026-07-28 17:38 ` sashiko-bot
2026-07-28 19:26 ` Frank Li
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox