* [PATCH v2 0/3] PCI: endpoint: pci-epf-vntb: allow arbitrary BAR mapping
@ 2025-06-03 17:03 Jerome Brunet
2025-06-03 17:03 ` [PATCH v2 1/3] PCI: endpoint: pci-epf-vntb: Return an error code on bar init Jerome Brunet
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Jerome Brunet @ 2025-06-03 17:03 UTC (permalink / raw)
To: Jon Mason, Dave Jiang, Allen Hubbe, Manivannan Sadhasivam,
Kishon Vijay Abraham I, Bjorn Helgaas, Frank Li,
Krzysztof Wilczyński, Krzysztof Wilczyński
Cc: ntb, linux-pci, linux-kernel, Jerome Brunet
The patchset allows arbitrary BAR mapping for vNTB PCI endpoint function.
This was developed for the Renesas platform with requires a mapping that
was not possible before:
* BAR0 (1MB): CTRL+SPAD
* BAR2 (1MB): MW0
* BAR4 (256B): Doorbell
It is possible to setup the host side driver with the mapping above without any
functional change but it makes sense to also add arbitrary mapping support
there. This is will be sent in a dedicated series.
The patchset should not change anything for existing users.
Possible next steps:
- Align the NTB endpoint function: I'd be happy to propose something there
but I would only be able to compile test it since I do not have the HW
to test it.
- Expose BAR configuration in the CTRL registers: I've been doodling with
the idea to add a few extra registers in the CTRL region to describe
the BAR mapping of the other regions. That way, there would less chance
for the 2 sides to become mis-aligned. I'm not certain it makes sense and
would welcome others opinion on this :)
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
Changes in v2:
- Align commit description casing style
- Delay adding MW4 enumeration to patch 3
- Apply renaming suggestion on patch 3
- Dropped patch 4 for the NTB: will be re-sent separately.
- Link to v1: https://lore.kernel.org/r/20250505-pci-vntb-bar-mapping-v1-0-0e0d12b2fa71@baylibre.com
---
Jerome Brunet (3):
PCI: endpoint: pci-epf-vntb: Return an error code on bar init
PCI: endpoint: pci-epf-vntb: Align mw naming with config names
PCI: endpoint: pci-epf-vntb: Allow BAR assignment via configfs
drivers/pci/endpoint/functions/pci-epf-vntb.c | 141 +++++++++++++++++++++++---
1 file changed, 129 insertions(+), 12 deletions(-)
---
base-commit: db2e86db6ec76de51aff24fb0ae43987d4c02355
change-id: 20250505-pci-vntb-bar-mapping-3cc3ff624e76
Best regards,
--
Jerome
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 1/3] PCI: endpoint: pci-epf-vntb: Return an error code on bar init
2025-06-03 17:03 [PATCH v2 0/3] PCI: endpoint: pci-epf-vntb: allow arbitrary BAR mapping Jerome Brunet
@ 2025-06-03 17:03 ` Jerome Brunet
2025-06-03 17:03 ` [PATCH v2 2/3] PCI: endpoint: pci-epf-vntb: Align mw naming with config names Jerome Brunet
` (2 subsequent siblings)
3 siblings, 0 replies; 9+ messages in thread
From: Jerome Brunet @ 2025-06-03 17:03 UTC (permalink / raw)
To: Jon Mason, Dave Jiang, Allen Hubbe, Manivannan Sadhasivam,
Kishon Vijay Abraham I, Bjorn Helgaas, Frank Li,
Krzysztof Wilczyński, Krzysztof Wilczyński
Cc: ntb, linux-pci, linux-kernel, Jerome Brunet
According the function documentation of epf_ntb_init_epc_bar(),
the function should return an error code on error. However, it
returns -1 when no BAR is available.
Return -EINVAL instead.
Fixes: e35f56bb0330 ("PCI: endpoint: Support NTB transfer between RC and EP")
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/pci/endpoint/functions/pci-epf-vntb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
index e4da3fdb000723e3adad01f0ddf230ecc0e572a7..35fa0a21fc91100a5539bff775e7ebc25e1fb9c1 100644
--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
+++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
@@ -680,7 +680,7 @@ static int epf_ntb_init_epc_bar(struct epf_ntb *ntb)
barno = pci_epc_get_next_free_bar(epc_features, barno);
if (barno < 0) {
dev_err(dev, "Fail to get NTB function BAR\n");
- return barno;
+ return -EINVAL;
}
ntb->epf_ntb_bar[bar] = barno;
}
--
2.47.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 2/3] PCI: endpoint: pci-epf-vntb: Align mw naming with config names
2025-06-03 17:03 [PATCH v2 0/3] PCI: endpoint: pci-epf-vntb: allow arbitrary BAR mapping Jerome Brunet
2025-06-03 17:03 ` [PATCH v2 1/3] PCI: endpoint: pci-epf-vntb: Return an error code on bar init Jerome Brunet
@ 2025-06-03 17:03 ` Jerome Brunet
2025-06-03 19:43 ` Frank Li
2025-06-03 17:03 ` [PATCH v2 3/3] PCI: endpoint: pci-epf-vntb: Allow BAR assignment via configfs Jerome Brunet
2025-06-23 12:06 ` [PATCH v2 0/3] PCI: endpoint: pci-epf-vntb: allow arbitrary BAR mapping Manivannan Sadhasivam
3 siblings, 1 reply; 9+ messages in thread
From: Jerome Brunet @ 2025-06-03 17:03 UTC (permalink / raw)
To: Jon Mason, Dave Jiang, Allen Hubbe, Manivannan Sadhasivam,
Kishon Vijay Abraham I, Bjorn Helgaas, Frank Li,
Krzysztof Wilczyński, Krzysztof Wilczyński
Cc: ntb, linux-pci, linux-kernel, Jerome Brunet
The config file related to the memory windows start the numbering of
the MW from 1. The other NTB function does the same, yet the enumeration
defining the BARs of the vNTB function starts numbering the MW from 0.
Both numbering are fine I suppose but mixing the two is a bit confusing.
The configfs file being the interface with userspace, lets keep that stable
and consistently start the numbering of the MW from 1.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/pci/endpoint/functions/pci-epf-vntb.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
index 35fa0a21fc91100a5539bff775e7ebc25e1fb9c1..2198282a80a40774047502a37f0288ca396bdb0e 100644
--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
+++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
@@ -70,9 +70,9 @@ static struct workqueue_struct *kpcintb_workqueue;
enum epf_ntb_bar {
BAR_CONFIG,
BAR_DB,
- BAR_MW0,
BAR_MW1,
BAR_MW2,
+ BAR_MW3,
};
/*
@@ -576,7 +576,7 @@ static int epf_ntb_mw_bar_init(struct epf_ntb *ntb)
for (i = 0; i < ntb->num_mws; i++) {
size = ntb->mws_size[i];
- barno = ntb->epf_ntb_bar[BAR_MW0 + i];
+ barno = ntb->epf_ntb_bar[BAR_MW1 + i];
ntb->epf->bar[barno].barno = barno;
ntb->epf->bar[barno].size = size;
@@ -629,7 +629,7 @@ static void epf_ntb_mw_bar_clear(struct epf_ntb *ntb, int num_mws)
int i;
for (i = 0; i < num_mws; i++) {
- barno = ntb->epf_ntb_bar[BAR_MW0 + i];
+ barno = ntb->epf_ntb_bar[BAR_MW1 + i];
pci_epc_clear_bar(ntb->epf->epc,
ntb->epf->func_no,
ntb->epf->vfunc_no,
@@ -676,7 +676,7 @@ static int epf_ntb_init_epc_bar(struct epf_ntb *ntb)
epc_features = pci_epc_get_features(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no);
/* These are required BARs which are mandatory for NTB functionality */
- for (bar = BAR_CONFIG; bar <= BAR_MW0; bar++, barno++) {
+ for (bar = BAR_CONFIG; bar <= BAR_MW1; bar++, barno++) {
barno = pci_epc_get_next_free_bar(epc_features, barno);
if (barno < 0) {
dev_err(dev, "Fail to get NTB function BAR\n");
@@ -1048,7 +1048,7 @@ static int vntb_epf_mw_set_trans(struct ntb_dev *ndev, int pidx, int idx,
struct device *dev;
dev = &ntb->ntb.dev;
- barno = ntb->epf_ntb_bar[BAR_MW0 + idx];
+ barno = ntb->epf_ntb_bar[BAR_MW1 + idx];
epf_bar = &ntb->epf->bar[barno];
epf_bar->phys_addr = addr;
epf_bar->barno = barno;
--
2.47.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 3/3] PCI: endpoint: pci-epf-vntb: Allow BAR assignment via configfs
2025-06-03 17:03 [PATCH v2 0/3] PCI: endpoint: pci-epf-vntb: allow arbitrary BAR mapping Jerome Brunet
2025-06-03 17:03 ` [PATCH v2 1/3] PCI: endpoint: pci-epf-vntb: Return an error code on bar init Jerome Brunet
2025-06-03 17:03 ` [PATCH v2 2/3] PCI: endpoint: pci-epf-vntb: Align mw naming with config names Jerome Brunet
@ 2025-06-03 17:03 ` Jerome Brunet
2025-06-03 19:46 ` Frank Li
2025-06-30 20:38 ` Bjorn Helgaas
2025-06-23 12:06 ` [PATCH v2 0/3] PCI: endpoint: pci-epf-vntb: allow arbitrary BAR mapping Manivannan Sadhasivam
3 siblings, 2 replies; 9+ messages in thread
From: Jerome Brunet @ 2025-06-03 17:03 UTC (permalink / raw)
To: Jon Mason, Dave Jiang, Allen Hubbe, Manivannan Sadhasivam,
Kishon Vijay Abraham I, Bjorn Helgaas, Frank Li,
Krzysztof Wilczyński, Krzysztof Wilczyński
Cc: ntb, linux-pci, linux-kernel, Jerome Brunet
The current BAR configuration for the PCI vNTB endpoint function allocates
BARs in order, which lacks flexibility and does not account for
platform-specific quirks. This is problematic on Renesas platforms, where
BAR_4 is a fixed 256B region that ends up being used for MW1, despite being
better suited for doorbells.
Add new configfs attributes to allow users to specify arbitrary BAR
assignments. If no configuration is provided, the driver retains its
original behavior of sequential BAR allocation, preserving compatibility
with existing userspace setups.
This enables use cases such as assigning BAR_2 for MW1 and using the
limited BAR_4 for doorbells on Renesas platforms.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/pci/endpoint/functions/pci-epf-vntb.c | 131 ++++++++++++++++++++++++--
1 file changed, 124 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
index 2198282a80a40774047502a37f0288ca396bdb0e..7475d87659b1c70aa41b0999eabfa661f4ceed39 100644
--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
+++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
@@ -73,6 +73,8 @@ enum epf_ntb_bar {
BAR_MW1,
BAR_MW2,
BAR_MW3,
+ BAR_MW4,
+ VNTB_BAR_NUM,
};
/*
@@ -132,7 +134,7 @@ struct epf_ntb {
bool linkup;
u32 spad_size;
- enum pci_barno epf_ntb_bar[6];
+ enum pci_barno epf_ntb_bar[VNTB_BAR_NUM];
struct epf_ntb_ctrl *reg;
@@ -654,6 +656,62 @@ static void epf_ntb_epc_destroy(struct epf_ntb *ntb)
pci_epc_put(ntb->epf->epc);
}
+
+/**
+ * epf_ntb_is_bar_used() - Check if a bar is used in the ntb configuration
+ * @ntb: NTB device that facilitates communication between HOST and VHOST
+ * @barno: Checked bar number
+ *
+ * Returns: true if used, false if free.
+ */
+static bool epf_ntb_is_bar_used(struct epf_ntb *ntb,
+ enum pci_barno barno)
+{
+ int i;
+
+ for (i = 0; i < VNTB_BAR_NUM; i++) {
+ if (ntb->epf_ntb_bar[i] == barno)
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * epf_ntb_find_bar() - Assign BAR number when no configuration is provided
+ * @epc_features: The features provided by the EPC specific to this EPF
+ * @ntb: NTB device that facilitates communication between HOST and VHOST
+ * @barno: Bar start index
+ *
+ * When the BAR configuration was not provided through the userspace
+ * configuration, automatically assign BAR as it has been historically
+ * done by this endpoint function.
+ *
+ * Returns: the BAR number found, if any. -1 otherwise
+ */
+static int epf_ntb_find_bar(struct epf_ntb *ntb,
+ const struct pci_epc_features *epc_features,
+ enum epf_ntb_bar bar,
+ enum pci_barno barno)
+{
+ while (ntb->epf_ntb_bar[bar] < 0) {
+ barno = pci_epc_get_next_free_bar(epc_features, barno);
+ if (barno < 0)
+ break; /* No more BAR available */
+
+ /*
+ * Verify if the BAR found is not already assigned
+ * through the provided configuration
+ */
+ if (!epf_ntb_is_bar_used(ntb, barno))
+ ntb->epf_ntb_bar[bar] = barno;
+
+ barno += 1;
+ }
+
+ return barno;
+}
+
/**
* epf_ntb_init_epc_bar() - Identify BARs to be used for each of the NTB
* constructs (scratchpad region, doorbell, memorywindow)
@@ -676,23 +734,21 @@ static int epf_ntb_init_epc_bar(struct epf_ntb *ntb)
epc_features = pci_epc_get_features(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no);
/* These are required BARs which are mandatory for NTB functionality */
- for (bar = BAR_CONFIG; bar <= BAR_MW1; bar++, barno++) {
- barno = pci_epc_get_next_free_bar(epc_features, barno);
+ for (bar = BAR_CONFIG; bar <= BAR_MW1; bar++) {
+ barno = epf_ntb_find_bar(ntb, epc_features, bar, barno);
if (barno < 0) {
dev_err(dev, "Fail to get NTB function BAR\n");
return -EINVAL;
}
- ntb->epf_ntb_bar[bar] = barno;
}
/* These are optional BARs which don't impact NTB functionality */
- for (bar = BAR_MW1, i = 1; i < num_mws; bar++, barno++, i++) {
- barno = pci_epc_get_next_free_bar(epc_features, barno);
+ for (bar = BAR_MW1, i = 1; i < num_mws; bar++, i++) {
+ barno = epf_ntb_find_bar(ntb, epc_features, bar, barno);
if (barno < 0) {
ntb->num_mws = i;
dev_dbg(dev, "BAR not available for > MW%d\n", i + 1);
}
- ntb->epf_ntb_bar[bar] = barno;
}
return 0;
@@ -860,6 +916,37 @@ static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
return len; \
}
+#define EPF_NTB_BAR_R(_name, _id) \
+ static ssize_t epf_ntb_##_name##_show(struct config_item *item, \
+ char *page) \
+ { \
+ struct config_group *group = to_config_group(item); \
+ struct epf_ntb *ntb = to_epf_ntb(group); \
+ \
+ return sprintf(page, "%d\n", ntb->epf_ntb_bar[_id]); \
+ }
+
+#define EPF_NTB_BAR_W(_name, _id) \
+ static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
+ const char *page, size_t len) \
+ { \
+ struct config_group *group = to_config_group(item); \
+ struct epf_ntb *ntb = to_epf_ntb(group); \
+ int val; \
+ int ret; \
+ \
+ ret = kstrtoint(page, 0, &val); \
+ if (ret) \
+ return ret; \
+ \
+ if (val < NO_BAR || val > BAR_5) \
+ return -EINVAL; \
+ \
+ ntb->epf_ntb_bar[_id] = val; \
+ \
+ return len; \
+ }
+
static ssize_t epf_ntb_num_mws_store(struct config_item *item,
const char *page, size_t len)
{
@@ -899,6 +986,18 @@ EPF_NTB_MW_R(mw3)
EPF_NTB_MW_W(mw3)
EPF_NTB_MW_R(mw4)
EPF_NTB_MW_W(mw4)
+EPF_NTB_BAR_R(ctrl_bar, BAR_CONFIG)
+EPF_NTB_BAR_W(ctrl_bar, BAR_CONFIG)
+EPF_NTB_BAR_R(db_bar, BAR_DB)
+EPF_NTB_BAR_W(db_bar, BAR_DB)
+EPF_NTB_BAR_R(mw1_bar, BAR_MW1)
+EPF_NTB_BAR_W(mw1_bar, BAR_MW1)
+EPF_NTB_BAR_R(mw2_bar, BAR_MW1)
+EPF_NTB_BAR_W(mw2_bar, BAR_MW1)
+EPF_NTB_BAR_R(mw3_bar, BAR_MW3)
+EPF_NTB_BAR_W(mw3_bar, BAR_MW3)
+EPF_NTB_BAR_R(mw4_bar, BAR_MW4)
+EPF_NTB_BAR_W(mw4_bar, BAR_MW4)
CONFIGFS_ATTR(epf_ntb_, spad_count);
CONFIGFS_ATTR(epf_ntb_, db_count);
@@ -910,6 +1009,12 @@ CONFIGFS_ATTR(epf_ntb_, mw4);
CONFIGFS_ATTR(epf_ntb_, vbus_number);
CONFIGFS_ATTR(epf_ntb_, vntb_pid);
CONFIGFS_ATTR(epf_ntb_, vntb_vid);
+CONFIGFS_ATTR(epf_ntb_, ctrl_bar);
+CONFIGFS_ATTR(epf_ntb_, db_bar);
+CONFIGFS_ATTR(epf_ntb_, mw1_bar);
+CONFIGFS_ATTR(epf_ntb_, mw2_bar);
+CONFIGFS_ATTR(epf_ntb_, mw3_bar);
+CONFIGFS_ATTR(epf_ntb_, mw4_bar);
static struct configfs_attribute *epf_ntb_attrs[] = {
&epf_ntb_attr_spad_count,
@@ -922,6 +1027,12 @@ static struct configfs_attribute *epf_ntb_attrs[] = {
&epf_ntb_attr_vbus_number,
&epf_ntb_attr_vntb_pid,
&epf_ntb_attr_vntb_vid,
+ &epf_ntb_attr_ctrl_bar,
+ &epf_ntb_attr_db_bar,
+ &epf_ntb_attr_mw1_bar,
+ &epf_ntb_attr_mw2_bar,
+ &epf_ntb_attr_mw3_bar,
+ &epf_ntb_attr_mw4_bar,
NULL,
};
@@ -1379,6 +1490,7 @@ static int epf_ntb_probe(struct pci_epf *epf,
{
struct epf_ntb *ntb;
struct device *dev;
+ int i;
dev = &epf->dev;
@@ -1389,6 +1501,11 @@ static int epf_ntb_probe(struct pci_epf *epf,
epf->header = &epf_ntb_header;
ntb->epf = epf;
ntb->vbus_number = 0xff;
+
+ /* Initially, no bar is assigned */
+ for (i = 0; i < VNTB_BAR_NUM; i++)
+ ntb->epf_ntb_bar[i] = NO_BAR;
+
epf_set_drvdata(epf, ntb);
dev_info(dev, "pci-ep epf driver loaded\n");
--
2.47.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/3] PCI: endpoint: pci-epf-vntb: Align mw naming with config names
2025-06-03 17:03 ` [PATCH v2 2/3] PCI: endpoint: pci-epf-vntb: Align mw naming with config names Jerome Brunet
@ 2025-06-03 19:43 ` Frank Li
0 siblings, 0 replies; 9+ messages in thread
From: Frank Li @ 2025-06-03 19:43 UTC (permalink / raw)
To: Jerome Brunet
Cc: Jon Mason, Dave Jiang, Allen Hubbe, Manivannan Sadhasivam,
Kishon Vijay Abraham I, Bjorn Helgaas, Krzysztof Wilczyński,
ntb, linux-pci, linux-kernel
On Tue, Jun 03, 2025 at 07:03:39PM +0200, Jerome Brunet wrote:
> The config file related to the memory windows start the numbering of
> the MW from 1. The other NTB function does the same, yet the enumeration
> defining the BARs of the vNTB function starts numbering the MW from 0.
>
> Both numbering are fine I suppose but mixing the two is a bit confusing.
> The configfs file being the interface with userspace, lets keep that stable
> and consistently start the numbering of the MW from 1.
>
> Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> ---
> drivers/pci/endpoint/functions/pci-epf-vntb.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
> index 35fa0a21fc91100a5539bff775e7ebc25e1fb9c1..2198282a80a40774047502a37f0288ca396bdb0e 100644
> --- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
> +++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
> @@ -70,9 +70,9 @@ static struct workqueue_struct *kpcintb_workqueue;
> enum epf_ntb_bar {
> BAR_CONFIG,
> BAR_DB,
> - BAR_MW0,
> BAR_MW1,
> BAR_MW2,
> + BAR_MW3,
> };
>
> /*
> @@ -576,7 +576,7 @@ static int epf_ntb_mw_bar_init(struct epf_ntb *ntb)
>
> for (i = 0; i < ntb->num_mws; i++) {
> size = ntb->mws_size[i];
> - barno = ntb->epf_ntb_bar[BAR_MW0 + i];
> + barno = ntb->epf_ntb_bar[BAR_MW1 + i];
>
> ntb->epf->bar[barno].barno = barno;
> ntb->epf->bar[barno].size = size;
> @@ -629,7 +629,7 @@ static void epf_ntb_mw_bar_clear(struct epf_ntb *ntb, int num_mws)
> int i;
>
> for (i = 0; i < num_mws; i++) {
> - barno = ntb->epf_ntb_bar[BAR_MW0 + i];
> + barno = ntb->epf_ntb_bar[BAR_MW1 + i];
> pci_epc_clear_bar(ntb->epf->epc,
> ntb->epf->func_no,
> ntb->epf->vfunc_no,
> @@ -676,7 +676,7 @@ static int epf_ntb_init_epc_bar(struct epf_ntb *ntb)
> epc_features = pci_epc_get_features(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no);
>
> /* These are required BARs which are mandatory for NTB functionality */
> - for (bar = BAR_CONFIG; bar <= BAR_MW0; bar++, barno++) {
> + for (bar = BAR_CONFIG; bar <= BAR_MW1; bar++, barno++) {
> barno = pci_epc_get_next_free_bar(epc_features, barno);
> if (barno < 0) {
> dev_err(dev, "Fail to get NTB function BAR\n");
> @@ -1048,7 +1048,7 @@ static int vntb_epf_mw_set_trans(struct ntb_dev *ndev, int pidx, int idx,
> struct device *dev;
>
> dev = &ntb->ntb.dev;
> - barno = ntb->epf_ntb_bar[BAR_MW0 + idx];
> + barno = ntb->epf_ntb_bar[BAR_MW1 + idx];
> epf_bar = &ntb->epf->bar[barno];
> epf_bar->phys_addr = addr;
> epf_bar->barno = barno;
>
> --
> 2.47.2
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 3/3] PCI: endpoint: pci-epf-vntb: Allow BAR assignment via configfs
2025-06-03 17:03 ` [PATCH v2 3/3] PCI: endpoint: pci-epf-vntb: Allow BAR assignment via configfs Jerome Brunet
@ 2025-06-03 19:46 ` Frank Li
2025-06-30 20:38 ` Bjorn Helgaas
1 sibling, 0 replies; 9+ messages in thread
From: Frank Li @ 2025-06-03 19:46 UTC (permalink / raw)
To: Jerome Brunet
Cc: Jon Mason, Dave Jiang, Allen Hubbe, Manivannan Sadhasivam,
Kishon Vijay Abraham I, Bjorn Helgaas, Krzysztof Wilczyński,
ntb, linux-pci, linux-kernel
On Tue, Jun 03, 2025 at 07:03:40PM +0200, Jerome Brunet wrote:
> The current BAR configuration for the PCI vNTB endpoint function allocates
> BARs in order, which lacks flexibility and does not account for
> platform-specific quirks. This is problematic on Renesas platforms, where
> BAR_4 is a fixed 256B region that ends up being used for MW1, despite being
> better suited for doorbells.
>
> Add new configfs attributes to allow users to specify arbitrary BAR
> assignments. If no configuration is provided, the driver retains its
> original behavior of sequential BAR allocation, preserving compatibility
> with existing userspace setups.
>
> This enables use cases such as assigning BAR_2 for MW1 and using the
> limited BAR_4 for doorbells on Renesas platforms.
>
> Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> ---
> drivers/pci/endpoint/functions/pci-epf-vntb.c | 131 ++++++++++++++++++++++++--
> 1 file changed, 124 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
> index 2198282a80a40774047502a37f0288ca396bdb0e..7475d87659b1c70aa41b0999eabfa661f4ceed39 100644
> --- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
> +++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
> @@ -73,6 +73,8 @@ enum epf_ntb_bar {
> BAR_MW1,
> BAR_MW2,
> BAR_MW3,
> + BAR_MW4,
> + VNTB_BAR_NUM,
> };
>
> /*
> @@ -132,7 +134,7 @@ struct epf_ntb {
> bool linkup;
> u32 spad_size;
>
> - enum pci_barno epf_ntb_bar[6];
> + enum pci_barno epf_ntb_bar[VNTB_BAR_NUM];
>
> struct epf_ntb_ctrl *reg;
>
> @@ -654,6 +656,62 @@ static void epf_ntb_epc_destroy(struct epf_ntb *ntb)
> pci_epc_put(ntb->epf->epc);
> }
>
> +
> +/**
> + * epf_ntb_is_bar_used() - Check if a bar is used in the ntb configuration
> + * @ntb: NTB device that facilitates communication between HOST and VHOST
> + * @barno: Checked bar number
> + *
> + * Returns: true if used, false if free.
> + */
> +static bool epf_ntb_is_bar_used(struct epf_ntb *ntb,
> + enum pci_barno barno)
> +{
> + int i;
> +
> + for (i = 0; i < VNTB_BAR_NUM; i++) {
> + if (ntb->epf_ntb_bar[i] == barno)
> + return true;
> + }
> +
> + return false;
> +}
> +
> +/**
> + * epf_ntb_find_bar() - Assign BAR number when no configuration is provided
> + * @epc_features: The features provided by the EPC specific to this EPF
> + * @ntb: NTB device that facilitates communication between HOST and VHOST
> + * @barno: Bar start index
> + *
> + * When the BAR configuration was not provided through the userspace
> + * configuration, automatically assign BAR as it has been historically
> + * done by this endpoint function.
> + *
> + * Returns: the BAR number found, if any. -1 otherwise
> + */
> +static int epf_ntb_find_bar(struct epf_ntb *ntb,
> + const struct pci_epc_features *epc_features,
> + enum epf_ntb_bar bar,
> + enum pci_barno barno)
> +{
> + while (ntb->epf_ntb_bar[bar] < 0) {
> + barno = pci_epc_get_next_free_bar(epc_features, barno);
> + if (barno < 0)
> + break; /* No more BAR available */
> +
> + /*
> + * Verify if the BAR found is not already assigned
> + * through the provided configuration
> + */
> + if (!epf_ntb_is_bar_used(ntb, barno))
> + ntb->epf_ntb_bar[bar] = barno;
> +
> + barno += 1;
> + }
> +
> + return barno;
> +}
> +
> /**
> * epf_ntb_init_epc_bar() - Identify BARs to be used for each of the NTB
> * constructs (scratchpad region, doorbell, memorywindow)
> @@ -676,23 +734,21 @@ static int epf_ntb_init_epc_bar(struct epf_ntb *ntb)
> epc_features = pci_epc_get_features(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no);
>
> /* These are required BARs which are mandatory for NTB functionality */
> - for (bar = BAR_CONFIG; bar <= BAR_MW1; bar++, barno++) {
> - barno = pci_epc_get_next_free_bar(epc_features, barno);
> + for (bar = BAR_CONFIG; bar <= BAR_MW1; bar++) {
> + barno = epf_ntb_find_bar(ntb, epc_features, bar, barno);
> if (barno < 0) {
> dev_err(dev, "Fail to get NTB function BAR\n");
> return -EINVAL;
> }
> - ntb->epf_ntb_bar[bar] = barno;
> }
>
> /* These are optional BARs which don't impact NTB functionality */
> - for (bar = BAR_MW1, i = 1; i < num_mws; bar++, barno++, i++) {
> - barno = pci_epc_get_next_free_bar(epc_features, barno);
> + for (bar = BAR_MW1, i = 1; i < num_mws; bar++, i++) {
> + barno = epf_ntb_find_bar(ntb, epc_features, bar, barno);
> if (barno < 0) {
> ntb->num_mws = i;
> dev_dbg(dev, "BAR not available for > MW%d\n", i + 1);
> }
> - ntb->epf_ntb_bar[bar] = barno;
> }
>
> return 0;
> @@ -860,6 +916,37 @@ static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
> return len; \
> }
>
> +#define EPF_NTB_BAR_R(_name, _id) \
> + static ssize_t epf_ntb_##_name##_show(struct config_item *item, \
> + char *page) \
> + { \
> + struct config_group *group = to_config_group(item); \
> + struct epf_ntb *ntb = to_epf_ntb(group); \
> + \
> + return sprintf(page, "%d\n", ntb->epf_ntb_bar[_id]); \
> + }
> +
> +#define EPF_NTB_BAR_W(_name, _id) \
> + static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
> + const char *page, size_t len) \
> + { \
> + struct config_group *group = to_config_group(item); \
> + struct epf_ntb *ntb = to_epf_ntb(group); \
> + int val; \
> + int ret; \
> + \
> + ret = kstrtoint(page, 0, &val); \
> + if (ret) \
> + return ret; \
> + \
> + if (val < NO_BAR || val > BAR_5) \
> + return -EINVAL; \
> + \
> + ntb->epf_ntb_bar[_id] = val; \
> + \
> + return len; \
> + }
> +
> static ssize_t epf_ntb_num_mws_store(struct config_item *item,
> const char *page, size_t len)
> {
> @@ -899,6 +986,18 @@ EPF_NTB_MW_R(mw3)
> EPF_NTB_MW_W(mw3)
> EPF_NTB_MW_R(mw4)
> EPF_NTB_MW_W(mw4)
> +EPF_NTB_BAR_R(ctrl_bar, BAR_CONFIG)
> +EPF_NTB_BAR_W(ctrl_bar, BAR_CONFIG)
> +EPF_NTB_BAR_R(db_bar, BAR_DB)
> +EPF_NTB_BAR_W(db_bar, BAR_DB)
> +EPF_NTB_BAR_R(mw1_bar, BAR_MW1)
> +EPF_NTB_BAR_W(mw1_bar, BAR_MW1)
> +EPF_NTB_BAR_R(mw2_bar, BAR_MW1)
> +EPF_NTB_BAR_W(mw2_bar, BAR_MW1)
> +EPF_NTB_BAR_R(mw3_bar, BAR_MW3)
> +EPF_NTB_BAR_W(mw3_bar, BAR_MW3)
> +EPF_NTB_BAR_R(mw4_bar, BAR_MW4)
> +EPF_NTB_BAR_W(mw4_bar, BAR_MW4)
>
> CONFIGFS_ATTR(epf_ntb_, spad_count);
> CONFIGFS_ATTR(epf_ntb_, db_count);
> @@ -910,6 +1009,12 @@ CONFIGFS_ATTR(epf_ntb_, mw4);
> CONFIGFS_ATTR(epf_ntb_, vbus_number);
> CONFIGFS_ATTR(epf_ntb_, vntb_pid);
> CONFIGFS_ATTR(epf_ntb_, vntb_vid);
> +CONFIGFS_ATTR(epf_ntb_, ctrl_bar);
> +CONFIGFS_ATTR(epf_ntb_, db_bar);
> +CONFIGFS_ATTR(epf_ntb_, mw1_bar);
> +CONFIGFS_ATTR(epf_ntb_, mw2_bar);
> +CONFIGFS_ATTR(epf_ntb_, mw3_bar);
> +CONFIGFS_ATTR(epf_ntb_, mw4_bar);
>
> static struct configfs_attribute *epf_ntb_attrs[] = {
> &epf_ntb_attr_spad_count,
> @@ -922,6 +1027,12 @@ static struct configfs_attribute *epf_ntb_attrs[] = {
> &epf_ntb_attr_vbus_number,
> &epf_ntb_attr_vntb_pid,
> &epf_ntb_attr_vntb_vid,
> + &epf_ntb_attr_ctrl_bar,
> + &epf_ntb_attr_db_bar,
> + &epf_ntb_attr_mw1_bar,
> + &epf_ntb_attr_mw2_bar,
> + &epf_ntb_attr_mw3_bar,
> + &epf_ntb_attr_mw4_bar,
> NULL,
> };
>
> @@ -1379,6 +1490,7 @@ static int epf_ntb_probe(struct pci_epf *epf,
> {
> struct epf_ntb *ntb;
> struct device *dev;
> + int i;
>
> dev = &epf->dev;
>
> @@ -1389,6 +1501,11 @@ static int epf_ntb_probe(struct pci_epf *epf,
> epf->header = &epf_ntb_header;
> ntb->epf = epf;
> ntb->vbus_number = 0xff;
> +
> + /* Initially, no bar is assigned */
> + for (i = 0; i < VNTB_BAR_NUM; i++)
> + ntb->epf_ntb_bar[i] = NO_BAR;
> +
> epf_set_drvdata(epf, ntb);
>
> dev_info(dev, "pci-ep epf driver loaded\n");
>
> --
> 2.47.2
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 0/3] PCI: endpoint: pci-epf-vntb: allow arbitrary BAR mapping
2025-06-03 17:03 [PATCH v2 0/3] PCI: endpoint: pci-epf-vntb: allow arbitrary BAR mapping Jerome Brunet
` (2 preceding siblings ...)
2025-06-03 17:03 ` [PATCH v2 3/3] PCI: endpoint: pci-epf-vntb: Allow BAR assignment via configfs Jerome Brunet
@ 2025-06-23 12:06 ` Manivannan Sadhasivam
3 siblings, 0 replies; 9+ messages in thread
From: Manivannan Sadhasivam @ 2025-06-23 12:06 UTC (permalink / raw)
To: Jon Mason, Dave Jiang, Allen Hubbe, Kishon Vijay Abraham I,
Bjorn Helgaas, Frank Li, Krzysztof Wilczyński,
Krzysztof Wilczyński, Manivannan Sadhasivam, Jerome Brunet
Cc: ntb, linux-pci, linux-kernel
On Tue, 03 Jun 2025 19:03:37 +0200, Jerome Brunet wrote:
> The patchset allows arbitrary BAR mapping for vNTB PCI endpoint function.
>
> This was developed for the Renesas platform with requires a mapping that
> was not possible before:
> * BAR0 (1MB): CTRL+SPAD
> * BAR2 (1MB): MW0
> * BAR4 (256B): Doorbell
>
> [...]
Applied, thanks!
[1/3] PCI: endpoint: pci-epf-vntb: Return an error code on bar init
commit: 7ea488cce73263231662e426639dd3e836537068
[2/3] PCI: endpoint: pci-epf-vntb: Align mw naming with config names
commit: a079d83c4afd4896f7f29bd9e807cb382043b360
[3/3] PCI: endpoint: pci-epf-vntb: Allow BAR assignment via configfs
commit: a0cc6e6fd072616315147ac68a12672d5a2fa223
Best regards,
--
Manivannan Sadhasivam <mani@kernel.org>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 3/3] PCI: endpoint: pci-epf-vntb: Allow BAR assignment via configfs
2025-06-03 17:03 ` [PATCH v2 3/3] PCI: endpoint: pci-epf-vntb: Allow BAR assignment via configfs Jerome Brunet
2025-06-03 19:46 ` Frank Li
@ 2025-06-30 20:38 ` Bjorn Helgaas
2025-07-01 7:37 ` Jerome Brunet
1 sibling, 1 reply; 9+ messages in thread
From: Bjorn Helgaas @ 2025-06-30 20:38 UTC (permalink / raw)
To: Jerome Brunet
Cc: Jon Mason, Dave Jiang, Allen Hubbe, Manivannan Sadhasivam,
Kishon Vijay Abraham I, Bjorn Helgaas, Frank Li,
Krzysztof Wilczyński, ntb, linux-pci, linux-kernel
On Tue, Jun 03, 2025 at 07:03:40PM +0200, Jerome Brunet wrote:
> The current BAR configuration for the PCI vNTB endpoint function allocates
> BARs in order, which lacks flexibility and does not account for
> platform-specific quirks. This is problematic on Renesas platforms, where
> BAR_4 is a fixed 256B region that ends up being used for MW1, despite being
> better suited for doorbells.
>
> Add new configfs attributes to allow users to specify arbitrary BAR
> assignments. If no configuration is provided, the driver retains its
> original behavior of sequential BAR allocation, preserving compatibility
> with existing userspace setups.
>
> This enables use cases such as assigning BAR_2 for MW1 and using the
> limited BAR_4 for doorbells on Renesas platforms.
Is there any documentation for how to use this new feature?
> Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
> ---
> drivers/pci/endpoint/functions/pci-epf-vntb.c | 131 ++++++++++++++++++++++++--
> 1 file changed, 124 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
> index 2198282a80a40774047502a37f0288ca396bdb0e..7475d87659b1c70aa41b0999eabfa661f4ceed39 100644
> --- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
> +++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
> @@ -73,6 +73,8 @@ enum epf_ntb_bar {
> BAR_MW1,
> BAR_MW2,
> BAR_MW3,
> + BAR_MW4,
> + VNTB_BAR_NUM,
> };
>
> /*
> @@ -132,7 +134,7 @@ struct epf_ntb {
> bool linkup;
> u32 spad_size;
>
> - enum pci_barno epf_ntb_bar[6];
> + enum pci_barno epf_ntb_bar[VNTB_BAR_NUM];
>
> struct epf_ntb_ctrl *reg;
>
> @@ -654,6 +656,62 @@ static void epf_ntb_epc_destroy(struct epf_ntb *ntb)
> pci_epc_put(ntb->epf->epc);
> }
>
> +
> +/**
> + * epf_ntb_is_bar_used() - Check if a bar is used in the ntb configuration
> + * @ntb: NTB device that facilitates communication between HOST and VHOST
> + * @barno: Checked bar number
> + *
> + * Returns: true if used, false if free.
> + */
> +static bool epf_ntb_is_bar_used(struct epf_ntb *ntb,
> + enum pci_barno barno)
> +{
> + int i;
> +
> + for (i = 0; i < VNTB_BAR_NUM; i++) {
> + if (ntb->epf_ntb_bar[i] == barno)
> + return true;
> + }
> +
> + return false;
> +}
> +
> +/**
> + * epf_ntb_find_bar() - Assign BAR number when no configuration is provided
> + * @epc_features: The features provided by the EPC specific to this EPF
> + * @ntb: NTB device that facilitates communication between HOST and VHOST
> + * @barno: Bar start index
> + *
> + * When the BAR configuration was not provided through the userspace
> + * configuration, automatically assign BAR as it has been historically
> + * done by this endpoint function.
> + *
> + * Returns: the BAR number found, if any. -1 otherwise
> + */
> +static int epf_ntb_find_bar(struct epf_ntb *ntb,
> + const struct pci_epc_features *epc_features,
> + enum epf_ntb_bar bar,
> + enum pci_barno barno)
> +{
> + while (ntb->epf_ntb_bar[bar] < 0) {
> + barno = pci_epc_get_next_free_bar(epc_features, barno);
> + if (barno < 0)
> + break; /* No more BAR available */
> +
> + /*
> + * Verify if the BAR found is not already assigned
> + * through the provided configuration
> + */
> + if (!epf_ntb_is_bar_used(ntb, barno))
> + ntb->epf_ntb_bar[bar] = barno;
> +
> + barno += 1;
> + }
> +
> + return barno;
> +}
> +
> /**
> * epf_ntb_init_epc_bar() - Identify BARs to be used for each of the NTB
> * constructs (scratchpad region, doorbell, memorywindow)
> @@ -676,23 +734,21 @@ static int epf_ntb_init_epc_bar(struct epf_ntb *ntb)
> epc_features = pci_epc_get_features(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no);
>
> /* These are required BARs which are mandatory for NTB functionality */
> - for (bar = BAR_CONFIG; bar <= BAR_MW1; bar++, barno++) {
> - barno = pci_epc_get_next_free_bar(epc_features, barno);
> + for (bar = BAR_CONFIG; bar <= BAR_MW1; bar++) {
> + barno = epf_ntb_find_bar(ntb, epc_features, bar, barno);
> if (barno < 0) {
> dev_err(dev, "Fail to get NTB function BAR\n");
> return -EINVAL;
> }
> - ntb->epf_ntb_bar[bar] = barno;
> }
>
> /* These are optional BARs which don't impact NTB functionality */
> - for (bar = BAR_MW1, i = 1; i < num_mws; bar++, barno++, i++) {
> - barno = pci_epc_get_next_free_bar(epc_features, barno);
> + for (bar = BAR_MW1, i = 1; i < num_mws; bar++, i++) {
> + barno = epf_ntb_find_bar(ntb, epc_features, bar, barno);
> if (barno < 0) {
> ntb->num_mws = i;
> dev_dbg(dev, "BAR not available for > MW%d\n", i + 1);
> }
> - ntb->epf_ntb_bar[bar] = barno;
> }
>
> return 0;
> @@ -860,6 +916,37 @@ static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
> return len; \
> }
>
> +#define EPF_NTB_BAR_R(_name, _id) \
> + static ssize_t epf_ntb_##_name##_show(struct config_item *item, \
> + char *page) \
> + { \
> + struct config_group *group = to_config_group(item); \
> + struct epf_ntb *ntb = to_epf_ntb(group); \
> + \
> + return sprintf(page, "%d\n", ntb->epf_ntb_bar[_id]); \
> + }
> +
> +#define EPF_NTB_BAR_W(_name, _id) \
> + static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
> + const char *page, size_t len) \
> + { \
> + struct config_group *group = to_config_group(item); \
> + struct epf_ntb *ntb = to_epf_ntb(group); \
> + int val; \
> + int ret; \
> + \
> + ret = kstrtoint(page, 0, &val); \
> + if (ret) \
> + return ret; \
> + \
> + if (val < NO_BAR || val > BAR_5) \
> + return -EINVAL; \
> + \
> + ntb->epf_ntb_bar[_id] = val; \
> + \
> + return len; \
> + }
> +
> static ssize_t epf_ntb_num_mws_store(struct config_item *item,
> const char *page, size_t len)
> {
> @@ -899,6 +986,18 @@ EPF_NTB_MW_R(mw3)
> EPF_NTB_MW_W(mw3)
> EPF_NTB_MW_R(mw4)
> EPF_NTB_MW_W(mw4)
> +EPF_NTB_BAR_R(ctrl_bar, BAR_CONFIG)
> +EPF_NTB_BAR_W(ctrl_bar, BAR_CONFIG)
> +EPF_NTB_BAR_R(db_bar, BAR_DB)
> +EPF_NTB_BAR_W(db_bar, BAR_DB)
> +EPF_NTB_BAR_R(mw1_bar, BAR_MW1)
> +EPF_NTB_BAR_W(mw1_bar, BAR_MW1)
> +EPF_NTB_BAR_R(mw2_bar, BAR_MW1)
> +EPF_NTB_BAR_W(mw2_bar, BAR_MW1)
> +EPF_NTB_BAR_R(mw3_bar, BAR_MW3)
> +EPF_NTB_BAR_W(mw3_bar, BAR_MW3)
> +EPF_NTB_BAR_R(mw4_bar, BAR_MW4)
> +EPF_NTB_BAR_W(mw4_bar, BAR_MW4)
>
> CONFIGFS_ATTR(epf_ntb_, spad_count);
> CONFIGFS_ATTR(epf_ntb_, db_count);
> @@ -910,6 +1009,12 @@ CONFIGFS_ATTR(epf_ntb_, mw4);
> CONFIGFS_ATTR(epf_ntb_, vbus_number);
> CONFIGFS_ATTR(epf_ntb_, vntb_pid);
> CONFIGFS_ATTR(epf_ntb_, vntb_vid);
> +CONFIGFS_ATTR(epf_ntb_, ctrl_bar);
> +CONFIGFS_ATTR(epf_ntb_, db_bar);
> +CONFIGFS_ATTR(epf_ntb_, mw1_bar);
> +CONFIGFS_ATTR(epf_ntb_, mw2_bar);
> +CONFIGFS_ATTR(epf_ntb_, mw3_bar);
> +CONFIGFS_ATTR(epf_ntb_, mw4_bar);
>
> static struct configfs_attribute *epf_ntb_attrs[] = {
> &epf_ntb_attr_spad_count,
> @@ -922,6 +1027,12 @@ static struct configfs_attribute *epf_ntb_attrs[] = {
> &epf_ntb_attr_vbus_number,
> &epf_ntb_attr_vntb_pid,
> &epf_ntb_attr_vntb_vid,
> + &epf_ntb_attr_ctrl_bar,
> + &epf_ntb_attr_db_bar,
> + &epf_ntb_attr_mw1_bar,
> + &epf_ntb_attr_mw2_bar,
> + &epf_ntb_attr_mw3_bar,
> + &epf_ntb_attr_mw4_bar,
> NULL,
> };
>
> @@ -1379,6 +1490,7 @@ static int epf_ntb_probe(struct pci_epf *epf,
> {
> struct epf_ntb *ntb;
> struct device *dev;
> + int i;
>
> dev = &epf->dev;
>
> @@ -1389,6 +1501,11 @@ static int epf_ntb_probe(struct pci_epf *epf,
> epf->header = &epf_ntb_header;
> ntb->epf = epf;
> ntb->vbus_number = 0xff;
> +
> + /* Initially, no bar is assigned */
> + for (i = 0; i < VNTB_BAR_NUM; i++)
> + ntb->epf_ntb_bar[i] = NO_BAR;
> +
> epf_set_drvdata(epf, ntb);
>
> dev_info(dev, "pci-ep epf driver loaded\n");
>
> --
> 2.47.2
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 3/3] PCI: endpoint: pci-epf-vntb: Allow BAR assignment via configfs
2025-06-30 20:38 ` Bjorn Helgaas
@ 2025-07-01 7:37 ` Jerome Brunet
0 siblings, 0 replies; 9+ messages in thread
From: Jerome Brunet @ 2025-07-01 7:37 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Jon Mason, Dave Jiang, Allen Hubbe, Manivannan Sadhasivam,
Kishon Vijay Abraham I, Bjorn Helgaas, Frank Li,
Krzysztof Wilczyński, ntb, linux-pci, linux-kernel
On Mon 30 Jun 2025 at 15:38, Bjorn Helgaas <helgaas@kernel.org> wrote:
> On Tue, Jun 03, 2025 at 07:03:40PM +0200, Jerome Brunet wrote:
>> The current BAR configuration for the PCI vNTB endpoint function allocates
>> BARs in order, which lacks flexibility and does not account for
>> platform-specific quirks. This is problematic on Renesas platforms, where
>> BAR_4 is a fixed 256B region that ends up being used for MW1, despite being
>> better suited for doorbells.
>>
>> Add new configfs attributes to allow users to specify arbitrary BAR
>> assignments. If no configuration is provided, the driver retains its
>> original behavior of sequential BAR allocation, preserving compatibility
>> with existing userspace setups.
>>
>> This enables use cases such as assigning BAR_2 for MW1 and using the
>> limited BAR_4 for doorbells on Renesas platforms.
>
> Is there any documentation for how to use this new feature?
Indeed no. Thanks for the reminder.
Section 9.8.2 is no longer relevant with that change, I'll
try to add some explanation there.
>
>> Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
>> ---
>> drivers/pci/endpoint/functions/pci-epf-vntb.c | 131 ++++++++++++++++++++++++--
>> 1 file changed, 124 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
>> index 2198282a80a40774047502a37f0288ca396bdb0e..7475d87659b1c70aa41b0999eabfa661f4ceed39 100644
>> --- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
>> +++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
>> @@ -73,6 +73,8 @@ enum epf_ntb_bar {
>> BAR_MW1,
>> BAR_MW2,
>> BAR_MW3,
>> + BAR_MW4,
>> + VNTB_BAR_NUM,
>> };
>>
>> /*
>> @@ -132,7 +134,7 @@ struct epf_ntb {
>> bool linkup;
>> u32 spad_size;
>>
>> - enum pci_barno epf_ntb_bar[6];
>> + enum pci_barno epf_ntb_bar[VNTB_BAR_NUM];
>>
>> struct epf_ntb_ctrl *reg;
>>
>> @@ -654,6 +656,62 @@ static void epf_ntb_epc_destroy(struct epf_ntb *ntb)
>> pci_epc_put(ntb->epf->epc);
>> }
>>
>> +
>> +/**
>> + * epf_ntb_is_bar_used() - Check if a bar is used in the ntb configuration
>> + * @ntb: NTB device that facilitates communication between HOST and VHOST
>> + * @barno: Checked bar number
>> + *
>> + * Returns: true if used, false if free.
>> + */
>> +static bool epf_ntb_is_bar_used(struct epf_ntb *ntb,
>> + enum pci_barno barno)
>> +{
>> + int i;
>> +
>> + for (i = 0; i < VNTB_BAR_NUM; i++) {
>> + if (ntb->epf_ntb_bar[i] == barno)
>> + return true;
>> + }
>> +
>> + return false;
>> +}
>> +
>> +/**
>> + * epf_ntb_find_bar() - Assign BAR number when no configuration is provided
>> + * @epc_features: The features provided by the EPC specific to this EPF
>> + * @ntb: NTB device that facilitates communication between HOST and VHOST
>> + * @barno: Bar start index
>> + *
>> + * When the BAR configuration was not provided through the userspace
>> + * configuration, automatically assign BAR as it has been historically
>> + * done by this endpoint function.
>> + *
>> + * Returns: the BAR number found, if any. -1 otherwise
>> + */
>> +static int epf_ntb_find_bar(struct epf_ntb *ntb,
>> + const struct pci_epc_features *epc_features,
>> + enum epf_ntb_bar bar,
>> + enum pci_barno barno)
>> +{
>> + while (ntb->epf_ntb_bar[bar] < 0) {
>> + barno = pci_epc_get_next_free_bar(epc_features, barno);
>> + if (barno < 0)
>> + break; /* No more BAR available */
>> +
>> + /*
>> + * Verify if the BAR found is not already assigned
>> + * through the provided configuration
>> + */
>> + if (!epf_ntb_is_bar_used(ntb, barno))
>> + ntb->epf_ntb_bar[bar] = barno;
>> +
>> + barno += 1;
>> + }
>> +
>> + return barno;
>> +}
>> +
>> /**
>> * epf_ntb_init_epc_bar() - Identify BARs to be used for each of the NTB
>> * constructs (scratchpad region, doorbell, memorywindow)
>> @@ -676,23 +734,21 @@ static int epf_ntb_init_epc_bar(struct epf_ntb *ntb)
>> epc_features = pci_epc_get_features(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no);
>>
>> /* These are required BARs which are mandatory for NTB functionality */
>> - for (bar = BAR_CONFIG; bar <= BAR_MW1; bar++, barno++) {
>> - barno = pci_epc_get_next_free_bar(epc_features, barno);
>> + for (bar = BAR_CONFIG; bar <= BAR_MW1; bar++) {
>> + barno = epf_ntb_find_bar(ntb, epc_features, bar, barno);
>> if (barno < 0) {
>> dev_err(dev, "Fail to get NTB function BAR\n");
>> return -EINVAL;
>> }
>> - ntb->epf_ntb_bar[bar] = barno;
>> }
>>
>> /* These are optional BARs which don't impact NTB functionality */
>> - for (bar = BAR_MW1, i = 1; i < num_mws; bar++, barno++, i++) {
>> - barno = pci_epc_get_next_free_bar(epc_features, barno);
>> + for (bar = BAR_MW1, i = 1; i < num_mws; bar++, i++) {
>> + barno = epf_ntb_find_bar(ntb, epc_features, bar, barno);
>> if (barno < 0) {
>> ntb->num_mws = i;
>> dev_dbg(dev, "BAR not available for > MW%d\n", i + 1);
>> }
>> - ntb->epf_ntb_bar[bar] = barno;
>> }
>>
>> return 0;
>> @@ -860,6 +916,37 @@ static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
>> return len; \
>> }
>>
>> +#define EPF_NTB_BAR_R(_name, _id) \
>> + static ssize_t epf_ntb_##_name##_show(struct config_item *item, \
>> + char *page) \
>> + { \
>> + struct config_group *group = to_config_group(item); \
>> + struct epf_ntb *ntb = to_epf_ntb(group); \
>> + \
>> + return sprintf(page, "%d\n", ntb->epf_ntb_bar[_id]); \
>> + }
>> +
>> +#define EPF_NTB_BAR_W(_name, _id) \
>> + static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
>> + const char *page, size_t len) \
>> + { \
>> + struct config_group *group = to_config_group(item); \
>> + struct epf_ntb *ntb = to_epf_ntb(group); \
>> + int val; \
>> + int ret; \
>> + \
>> + ret = kstrtoint(page, 0, &val); \
>> + if (ret) \
>> + return ret; \
>> + \
>> + if (val < NO_BAR || val > BAR_5) \
>> + return -EINVAL; \
>> + \
>> + ntb->epf_ntb_bar[_id] = val; \
>> + \
>> + return len; \
>> + }
>> +
>> static ssize_t epf_ntb_num_mws_store(struct config_item *item,
>> const char *page, size_t len)
>> {
>> @@ -899,6 +986,18 @@ EPF_NTB_MW_R(mw3)
>> EPF_NTB_MW_W(mw3)
>> EPF_NTB_MW_R(mw4)
>> EPF_NTB_MW_W(mw4)
>> +EPF_NTB_BAR_R(ctrl_bar, BAR_CONFIG)
>> +EPF_NTB_BAR_W(ctrl_bar, BAR_CONFIG)
>> +EPF_NTB_BAR_R(db_bar, BAR_DB)
>> +EPF_NTB_BAR_W(db_bar, BAR_DB)
>> +EPF_NTB_BAR_R(mw1_bar, BAR_MW1)
>> +EPF_NTB_BAR_W(mw1_bar, BAR_MW1)
>> +EPF_NTB_BAR_R(mw2_bar, BAR_MW1)
>> +EPF_NTB_BAR_W(mw2_bar, BAR_MW1)
>> +EPF_NTB_BAR_R(mw3_bar, BAR_MW3)
>> +EPF_NTB_BAR_W(mw3_bar, BAR_MW3)
>> +EPF_NTB_BAR_R(mw4_bar, BAR_MW4)
>> +EPF_NTB_BAR_W(mw4_bar, BAR_MW4)
>>
>> CONFIGFS_ATTR(epf_ntb_, spad_count);
>> CONFIGFS_ATTR(epf_ntb_, db_count);
>> @@ -910,6 +1009,12 @@ CONFIGFS_ATTR(epf_ntb_, mw4);
>> CONFIGFS_ATTR(epf_ntb_, vbus_number);
>> CONFIGFS_ATTR(epf_ntb_, vntb_pid);
>> CONFIGFS_ATTR(epf_ntb_, vntb_vid);
>> +CONFIGFS_ATTR(epf_ntb_, ctrl_bar);
>> +CONFIGFS_ATTR(epf_ntb_, db_bar);
>> +CONFIGFS_ATTR(epf_ntb_, mw1_bar);
>> +CONFIGFS_ATTR(epf_ntb_, mw2_bar);
>> +CONFIGFS_ATTR(epf_ntb_, mw3_bar);
>> +CONFIGFS_ATTR(epf_ntb_, mw4_bar);
>>
>> static struct configfs_attribute *epf_ntb_attrs[] = {
>> &epf_ntb_attr_spad_count,
>> @@ -922,6 +1027,12 @@ static struct configfs_attribute *epf_ntb_attrs[] = {
>> &epf_ntb_attr_vbus_number,
>> &epf_ntb_attr_vntb_pid,
>> &epf_ntb_attr_vntb_vid,
>> + &epf_ntb_attr_ctrl_bar,
>> + &epf_ntb_attr_db_bar,
>> + &epf_ntb_attr_mw1_bar,
>> + &epf_ntb_attr_mw2_bar,
>> + &epf_ntb_attr_mw3_bar,
>> + &epf_ntb_attr_mw4_bar,
>> NULL,
>> };
>>
>> @@ -1379,6 +1490,7 @@ static int epf_ntb_probe(struct pci_epf *epf,
>> {
>> struct epf_ntb *ntb;
>> struct device *dev;
>> + int i;
>>
>> dev = &epf->dev;
>>
>> @@ -1389,6 +1501,11 @@ static int epf_ntb_probe(struct pci_epf *epf,
>> epf->header = &epf_ntb_header;
>> ntb->epf = epf;
>> ntb->vbus_number = 0xff;
>> +
>> + /* Initially, no bar is assigned */
>> + for (i = 0; i < VNTB_BAR_NUM; i++)
>> + ntb->epf_ntb_bar[i] = NO_BAR;
>> +
>> epf_set_drvdata(epf, ntb);
>>
>> dev_info(dev, "pci-ep epf driver loaded\n");
>>
>> --
>> 2.47.2
>>
--
Jerome
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-07-01 7:37 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-03 17:03 [PATCH v2 0/3] PCI: endpoint: pci-epf-vntb: allow arbitrary BAR mapping Jerome Brunet
2025-06-03 17:03 ` [PATCH v2 1/3] PCI: endpoint: pci-epf-vntb: Return an error code on bar init Jerome Brunet
2025-06-03 17:03 ` [PATCH v2 2/3] PCI: endpoint: pci-epf-vntb: Align mw naming with config names Jerome Brunet
2025-06-03 19:43 ` Frank Li
2025-06-03 17:03 ` [PATCH v2 3/3] PCI: endpoint: pci-epf-vntb: Allow BAR assignment via configfs Jerome Brunet
2025-06-03 19:46 ` Frank Li
2025-06-30 20:38 ` Bjorn Helgaas
2025-07-01 7:37 ` Jerome Brunet
2025-06-23 12:06 ` [PATCH v2 0/3] PCI: endpoint: pci-epf-vntb: allow arbitrary BAR mapping Manivannan Sadhasivam
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).