* [PATCH v2 1/9] PCI: endpoint: pci-epf-test: Fix incorrect loop increment
2024-03-12 10:51 [PATCH v2 0/9] PCI: endpoint: set prefetchable bit for 64-bit BARs Niklas Cassel
@ 2024-03-12 10:51 ` Niklas Cassel
2024-03-12 10:51 ` [PATCH v2 2/9] PCI: endpoint: Allocate a 64-bit BAR if that is the only option Niklas Cassel
` (7 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Niklas Cassel @ 2024-03-12 10:51 UTC (permalink / raw)
To: Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Kishon Vijay Abraham I, Bjorn Helgaas
Cc: Shradha Todi, Damien Le Moal, Niklas Cassel, linux-pci
pci_epf_test_alloc_space() currently skips the BAR succeeding a 64-bit BAR
if the 64-bit flag is set, before calling pci_epf_alloc_space().
However, pci_epf_alloc_space() will set the 64-bit flag if we request an
allocation of 4 GB or larger, even if it wasn't set before the allocation.
Thus, we need to check the flag also after pci_epf_alloc_space().
Signed-off-by: Niklas Cassel <cassel@kernel.org>
---
drivers/pci/endpoint/functions/pci-epf-test.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index cd4ffb39dcdc..01ba088849cc 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -865,6 +865,12 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
dev_err(dev, "Failed to allocate space for BAR%d\n",
bar);
epf_test->reg[bar] = base;
+
+ /*
+ * pci_epf_alloc_space() might have given us a 64-bit BAR,
+ * if we requested a size larger than 4 GB.
+ */
+ add = (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) ? 2 : 1;
}
return 0;
--
2.44.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v2 2/9] PCI: endpoint: Allocate a 64-bit BAR if that is the only option
2024-03-12 10:51 [PATCH v2 0/9] PCI: endpoint: set prefetchable bit for 64-bit BARs Niklas Cassel
2024-03-12 10:51 ` [PATCH v2 1/9] PCI: endpoint: pci-epf-test: Fix incorrect loop increment Niklas Cassel
@ 2024-03-12 10:51 ` Niklas Cassel
2024-03-12 10:51 ` [PATCH v2 3/9] PCI: endpoint: pci-epf-test: Remove superfluous code Niklas Cassel
` (6 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Niklas Cassel @ 2024-03-12 10:51 UTC (permalink / raw)
To: Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Kishon Vijay Abraham I, Bjorn Helgaas
Cc: Shradha Todi, Damien Le Moal, Niklas Cassel, linux-pci
pci_epf_alloc_space() already sets the 64-bit flag if the BAR size is
larger than 4GB, even if the caller did not explicitly request a 64-bit
BAR.
Thus, let pci_epf_alloc_space() also set the 64-bit flag if the hardware
description says that the specific BAR can only be 64-bit.
Signed-off-by: Niklas Cassel <cassel@kernel.org>
---
drivers/pci/endpoint/functions/pci-epf-test.c | 3 ++-
drivers/pci/endpoint/pci-epf-core.c | 7 ++++---
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index 01ba088849cc..8c9802b9b835 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -868,7 +868,8 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
/*
* pci_epf_alloc_space() might have given us a 64-bit BAR,
- * if we requested a size larger than 4 GB.
+ * either because the BAR can only be a 64-bit BAR, or if
+ * we requested a size larger than 4 GB.
*/
add = (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) ? 2 : 1;
}
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index 0a28a0b0911b..e7dbbeb1f0de 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -304,9 +304,10 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
epf_bar[bar].addr = space;
epf_bar[bar].size = size;
epf_bar[bar].barno = bar;
- epf_bar[bar].flags |= upper_32_bits(size) ?
- PCI_BASE_ADDRESS_MEM_TYPE_64 :
- PCI_BASE_ADDRESS_MEM_TYPE_32;
+ if (upper_32_bits(size) || epc_features->bar[bar].only_64bit)
+ epf_bar[bar].flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
+ else
+ epf_bar[bar].flags |= PCI_BASE_ADDRESS_MEM_TYPE_32;
return space;
}
--
2.44.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v2 3/9] PCI: endpoint: pci-epf-test: Remove superfluous code
2024-03-12 10:51 [PATCH v2 0/9] PCI: endpoint: set prefetchable bit for 64-bit BARs Niklas Cassel
2024-03-12 10:51 ` [PATCH v2 1/9] PCI: endpoint: pci-epf-test: Fix incorrect loop increment Niklas Cassel
2024-03-12 10:51 ` [PATCH v2 2/9] PCI: endpoint: Allocate a 64-bit BAR if that is the only option Niklas Cassel
@ 2024-03-12 10:51 ` Niklas Cassel
2024-03-12 10:51 ` [PATCH v2 4/9] PCI: endpoint: pci-epf-test: Simplify pci_epf_test_alloc_space() loop Niklas Cassel
` (5 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Niklas Cassel @ 2024-03-12 10:51 UTC (permalink / raw)
To: Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Kishon Vijay Abraham I, Bjorn Helgaas
Cc: Shradha Todi, Damien Le Moal, Niklas Cassel, linux-pci
The pci-epf-test does no special configuration at all, it simply requests
a 64-bit BAR if the hardware requires it. However, this flag is now
automatically set when allocating a BAR that can only be a 64-bit BAR,
so we can drop pci_epf_configure_bar() completely.
Signed-off-by: Niklas Cassel <cassel@kernel.org>
---
drivers/pci/endpoint/functions/pci-epf-test.c | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index 8c9802b9b835..7dc9704128dc 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -877,19 +877,6 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
return 0;
}
-static void pci_epf_configure_bar(struct pci_epf *epf,
- const struct pci_epc_features *epc_features)
-{
- struct pci_epf_bar *epf_bar;
- int i;
-
- for (i = 0; i < PCI_STD_NUM_BARS; i++) {
- epf_bar = &epf->bar[i];
- if (epc_features->bar[i].only_64bit)
- epf_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
- }
-}
-
static int pci_epf_test_bind(struct pci_epf *epf)
{
int ret;
@@ -914,7 +901,6 @@ static int pci_epf_test_bind(struct pci_epf *epf)
test_reg_bar = pci_epc_get_first_free_bar(epc_features);
if (test_reg_bar < 0)
return -EINVAL;
- pci_epf_configure_bar(epf, epc_features);
epf_test->test_reg_bar = test_reg_bar;
epf_test->epc_features = epc_features;
--
2.44.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v2 4/9] PCI: endpoint: pci-epf-test: Simplify pci_epf_test_alloc_space() loop
2024-03-12 10:51 [PATCH v2 0/9] PCI: endpoint: set prefetchable bit for 64-bit BARs Niklas Cassel
` (2 preceding siblings ...)
2024-03-12 10:51 ` [PATCH v2 3/9] PCI: endpoint: pci-epf-test: Remove superfluous code Niklas Cassel
@ 2024-03-12 10:51 ` Niklas Cassel
2024-03-12 10:51 ` [PATCH v2 5/9] PCI: endpoint: pci-epf-test: Simplify pci_epf_test_set_bar() loop Niklas Cassel
` (4 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Niklas Cassel @ 2024-03-12 10:51 UTC (permalink / raw)
To: Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Kishon Vijay Abraham I, Bjorn Helgaas
Cc: Shradha Todi, Damien Le Moal, Niklas Cassel, linux-pci
Make pci-epf-test use pci_epc_get_next_free_bar() just like pci-epf-ntb.c
and pci-epf-vntb.c.
Using pci_epc_get_next_free_bar() also makes it more obvious that
pci-epf-test does no special configuration at all.
This way, the code is more consistent between EPF drivers, and pci-epf-test
does not need to explicitly check if the BAR is reserved, or if the index
belongs to a BAR succeeding a 64-bit only BAR.
Signed-off-by: Niklas Cassel <cassel@kernel.org>
---
drivers/pci/endpoint/functions/pci-epf-test.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index 7dc9704128dc..20c79610712d 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -823,8 +823,8 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
size_t pba_size = 0;
bool msix_capable;
void *base;
- int bar, add;
enum pci_barno test_reg_bar = epf_test->test_reg_bar;
+ enum pci_barno bar;
const struct pci_epc_features *epc_features;
size_t test_reg_size;
@@ -849,16 +849,14 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
}
epf_test->reg[test_reg_bar] = base;
- for (bar = 0; bar < PCI_STD_NUM_BARS; bar += add) {
- epf_bar = &epf->bar[bar];
- add = (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) ? 2 : 1;
+ for (bar = BAR_0; bar < PCI_STD_NUM_BARS; bar++) {
+ bar = pci_epc_get_next_free_bar(epc_features, bar);
+ if (bar == NO_BAR)
+ break;
if (bar == test_reg_bar)
continue;
- if (epc_features->bar[bar].type == BAR_RESERVED)
- continue;
-
base = pci_epf_alloc_space(epf, bar_size[bar], bar,
epc_features, PRIMARY_INTERFACE);
if (!base)
@@ -871,7 +869,9 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
* either because the BAR can only be a 64-bit BAR, or if
* we requested a size larger than 4 GB.
*/
- add = (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) ? 2 : 1;
+ epf_bar = &epf->bar[bar];
+ if (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
+ bar++;
}
return 0;
--
2.44.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v2 5/9] PCI: endpoint: pci-epf-test: Simplify pci_epf_test_set_bar() loop
2024-03-12 10:51 [PATCH v2 0/9] PCI: endpoint: set prefetchable bit for 64-bit BARs Niklas Cassel
` (3 preceding siblings ...)
2024-03-12 10:51 ` [PATCH v2 4/9] PCI: endpoint: pci-epf-test: Simplify pci_epf_test_alloc_space() loop Niklas Cassel
@ 2024-03-12 10:51 ` Niklas Cassel
2024-03-13 2:11 ` kernel test robot
2024-03-12 10:51 ` [PATCH v2 6/9] PCI: endpoint: pci-epf-test: Clean up pci_epf_test_unbind() Niklas Cassel
` (3 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: Niklas Cassel @ 2024-03-12 10:51 UTC (permalink / raw)
To: Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Kishon Vijay Abraham I, Bjorn Helgaas
Cc: Shradha Todi, Damien Le Moal, Niklas Cassel, linux-pci
Simplify the loop in pci_epf_test_set_bar().
If we allocated memory for the BAR, we need to call set_bar() for that
BAR, if we did not allocated memory for that BAR, we need to skip.
It is as simple as that. This also matches the logic in
pci_epf_test_unbind().
A 64-bit BAR will still only be one allocation, with the BAR succeeding
the 64-bit BAR being null.
While at it, remove the misleading comment.
A EPC .set_bar() callback should never change the epf_bar->flags.
(E.g. to set a 64-bit BAR if we requested a 32-bit BAR.)
A .set_bar() callback should do what we request it to do.
If it can't satisfy the request, it should return an error.
If platform has a specific requirement, e.g. that a certain BAR has to
be a 64-bit BAR, then it should specify that by setting the .only_64bit
flag for that specific BAR in epc_features->bar[], such that
pci_epf_alloc_space() will return a epf_bar with the 64-bit flag set.
(Such that .set_bar() will receive a request to set a 64-bit BAR.)
Signed-off-by: Niklas Cassel <cassel@kernel.org>
---
drivers/pci/endpoint/functions/pci-epf-test.c | 18 ++++--------------
1 file changed, 4 insertions(+), 14 deletions(-)
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index 20c79610712d..05b9bc1e89cd 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -709,9 +709,7 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
static int pci_epf_test_set_bar(struct pci_epf *epf)
{
- int bar, add;
- int ret;
- struct pci_epf_bar *epf_bar;
+ int bar, ret;
struct pci_epc *epc = epf->epc;
struct device *dev = &epf->dev;
struct pci_epf_test *epf_test = epf_get_drvdata(epf);
@@ -720,20 +718,12 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
epc_features = epf_test->epc_features;
- for (bar = 0; bar < PCI_STD_NUM_BARS; bar += add) {
- epf_bar = &epf->bar[bar];
- /*
- * pci_epc_set_bar() sets PCI_BASE_ADDRESS_MEM_TYPE_64
- * if the specific implementation required a 64-bit BAR,
- * even if we only requested a 32-bit BAR.
- */
- add = (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) ? 2 : 1;
-
- if (epc_features->bar[bar].type == BAR_RESERVED)
+ for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
+ if (!epf_test->reg[bar])
continue;
ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no,
- epf_bar);
+ &epf->bar[bar]);
if (ret) {
pci_epf_free_space(epf, epf_test->reg[bar], bar,
PRIMARY_INTERFACE);
--
2.44.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v2 5/9] PCI: endpoint: pci-epf-test: Simplify pci_epf_test_set_bar() loop
2024-03-12 10:51 ` [PATCH v2 5/9] PCI: endpoint: pci-epf-test: Simplify pci_epf_test_set_bar() loop Niklas Cassel
@ 2024-03-13 2:11 ` kernel test robot
0 siblings, 0 replies; 13+ messages in thread
From: kernel test robot @ 2024-03-13 2:11 UTC (permalink / raw)
To: Niklas Cassel, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Kishon Vijay Abraham I, Bjorn Helgaas
Cc: oe-kbuild-all, Shradha Todi, Damien Le Moal, Niklas Cassel,
linux-pci
Hi Niklas,
kernel test robot noticed the following build warnings:
[auto build test WARNING on pci/next]
[also build test WARNING on next-20240312]
[cannot apply to pci/for-linus mani-mhi/mhi-next linus/master v6.8]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Niklas-Cassel/PCI-endpoint-pci-epf-test-Fix-incorrect-loop-increment/20240312-185512
base: https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git next
patch link: https://lore.kernel.org/r/20240312105152.3457899-6-cassel%40kernel.org
patch subject: [PATCH v2 5/9] PCI: endpoint: pci-epf-test: Simplify pci_epf_test_set_bar() loop
config: arc-randconfig-001-20240313 (https://download.01.org/0day-ci/archive/20240313/202403131004.Z9epuI06-lkp@intel.com/config)
compiler: arc-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240313/202403131004.Z9epuI06-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202403131004.Z9epuI06-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/pci/endpoint/functions/pci-epf-test.c: In function 'pci_epf_test_set_bar':
>> drivers/pci/endpoint/functions/pci-epf-test.c:717:40: warning: variable 'epc_features' set but not used [-Wunused-but-set-variable]
717 | const struct pci_epc_features *epc_features;
| ^~~~~~~~~~~~
vim +/epc_features +717 drivers/pci/endpoint/functions/pci-epf-test.c
349e7a85b25fa6 Kishon Vijay Abraham I 2017-03-27 709
349e7a85b25fa6 Kishon Vijay Abraham I 2017-03-27 710 static int pci_epf_test_set_bar(struct pci_epf *epf)
349e7a85b25fa6 Kishon Vijay Abraham I 2017-03-27 711 {
2287a91bfd63cb Niklas Cassel 2024-03-12 712 int bar, ret;
349e7a85b25fa6 Kishon Vijay Abraham I 2017-03-27 713 struct pci_epc *epc = epf->epc;
349e7a85b25fa6 Kishon Vijay Abraham I 2017-03-27 714 struct device *dev = &epf->dev;
349e7a85b25fa6 Kishon Vijay Abraham I 2017-03-27 715 struct pci_epf_test *epf_test = epf_get_drvdata(epf);
3235b994950d84 Kishon Vijay Abraham I 2017-08-18 716 enum pci_barno test_reg_bar = epf_test->test_reg_bar;
2c04c5b8eef797 Kishon Vijay Abraham I 2019-01-14 @717 const struct pci_epc_features *epc_features;
2c04c5b8eef797 Kishon Vijay Abraham I 2019-01-14 718
2c04c5b8eef797 Kishon Vijay Abraham I 2019-01-14 719 epc_features = epf_test->epc_features;
349e7a85b25fa6 Kishon Vijay Abraham I 2017-03-27 720
2287a91bfd63cb Niklas Cassel 2024-03-12 721 for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
2287a91bfd63cb Niklas Cassel 2024-03-12 722 if (!epf_test->reg[bar])
2c04c5b8eef797 Kishon Vijay Abraham I 2019-01-14 723 continue;
2c04c5b8eef797 Kishon Vijay Abraham I 2019-01-14 724
53fd3cbe5e9d79 Kishon Vijay Abraham I 2021-08-19 725 ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no,
2287a91bfd63cb Niklas Cassel 2024-03-12 726 &epf->bar[bar]);
349e7a85b25fa6 Kishon Vijay Abraham I 2017-03-27 727 if (ret) {
63840ff5322373 Kishon Vijay Abraham I 2021-02-02 728 pci_epf_free_space(epf, epf_test->reg[bar], bar,
63840ff5322373 Kishon Vijay Abraham I 2021-02-02 729 PRIMARY_INTERFACE);
798c0441bec8c4 Gustavo Pimentel 2018-05-14 730 dev_err(dev, "Failed to set BAR%d\n", bar);
3235b994950d84 Kishon Vijay Abraham I 2017-08-18 731 if (bar == test_reg_bar)
349e7a85b25fa6 Kishon Vijay Abraham I 2017-03-27 732 return ret;
349e7a85b25fa6 Kishon Vijay Abraham I 2017-03-27 733 }
349e7a85b25fa6 Kishon Vijay Abraham I 2017-03-27 734 }
349e7a85b25fa6 Kishon Vijay Abraham I 2017-03-27 735
349e7a85b25fa6 Kishon Vijay Abraham I 2017-03-27 736 return 0;
349e7a85b25fa6 Kishon Vijay Abraham I 2017-03-27 737 }
349e7a85b25fa6 Kishon Vijay Abraham I 2017-03-27 738
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 6/9] PCI: endpoint: pci-epf-test: Clean up pci_epf_test_unbind()
2024-03-12 10:51 [PATCH v2 0/9] PCI: endpoint: set prefetchable bit for 64-bit BARs Niklas Cassel
` (4 preceding siblings ...)
2024-03-12 10:51 ` [PATCH v2 5/9] PCI: endpoint: pci-epf-test: Simplify pci_epf_test_set_bar() loop Niklas Cassel
@ 2024-03-12 10:51 ` Niklas Cassel
2024-03-12 10:51 ` [PATCH v2 7/9] PCI: cadence: Set a 64-bit BAR if requested Niklas Cassel
` (2 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Niklas Cassel @ 2024-03-12 10:51 UTC (permalink / raw)
To: Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Kishon Vijay Abraham I, Bjorn Helgaas
Cc: Shradha Todi, Damien Le Moal, Niklas Cassel, linux-pci
Clean up pci_epf_test_unbind() by using a continue if we did not allocate
memory for the BAR index. This reduces the indentation level by one.
This makes pci_epf_test_unbind() more similar to pci_epf_test_set_bar().
Signed-off-by: Niklas Cassel <cassel@kernel.org>
---
drivers/pci/endpoint/functions/pci-epf-test.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index 05b9bc1e89cd..2c1d10afb1ae 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -690,20 +690,18 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
{
struct pci_epf_test *epf_test = epf_get_drvdata(epf);
struct pci_epc *epc = epf->epc;
- struct pci_epf_bar *epf_bar;
int bar;
cancel_delayed_work(&epf_test->cmd_handler);
pci_epf_test_clean_dma_chan(epf_test);
for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
- epf_bar = &epf->bar[bar];
+ if (!epf_test->reg[bar])
+ continue;
- if (epf_test->reg[bar]) {
- pci_epc_clear_bar(epc, epf->func_no, epf->vfunc_no,
- epf_bar);
- pci_epf_free_space(epf, epf_test->reg[bar], bar,
- PRIMARY_INTERFACE);
- }
+ pci_epc_clear_bar(epc, epf->func_no, epf->vfunc_no,
+ &epf->bar[bar]);
+ pci_epf_free_space(epf, epf_test->reg[bar], bar,
+ PRIMARY_INTERFACE);
}
}
--
2.44.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v2 7/9] PCI: cadence: Set a 64-bit BAR if requested
2024-03-12 10:51 [PATCH v2 0/9] PCI: endpoint: set prefetchable bit for 64-bit BARs Niklas Cassel
` (5 preceding siblings ...)
2024-03-12 10:51 ` [PATCH v2 6/9] PCI: endpoint: pci-epf-test: Clean up pci_epf_test_unbind() Niklas Cassel
@ 2024-03-12 10:51 ` Niklas Cassel
2024-05-16 20:49 ` Bjorn Helgaas
2024-03-12 10:51 ` [PATCH v2 8/9] PCI: rockchip-ep: " Niklas Cassel
2024-03-12 10:51 ` [PATCH v2 9/9] PCI: endpoint: Set prefetch when allocating memory for 64-bit BARs Niklas Cassel
8 siblings, 1 reply; 13+ messages in thread
From: Niklas Cassel @ 2024-03-12 10:51 UTC (permalink / raw)
To: Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas
Cc: Shradha Todi, Damien Le Moal, Niklas Cassel, linux-pci
Ever since commit f25b5fae29d4 ("PCI: endpoint: Setting a BAR size > 4 GB
is invalid if 64-bit flag is not set") it has been impossible to get the
.set_bar() callback with a BAR size > 4 GB, if the BAR was also not
requested to be configured as a 64-bit BAR.
Thus, forcing setting the 64-bit flag for BARs larger than 4 GB in the
lower level driver is dead code and can be removed.
It is however possible that an EPF driver configures a BAR as 64-bit,
even if the requested size is < 4 GB.
Respect the requested BAR configuration, just like how it is already
repected with regards to the prefetchable bit.
Signed-off-by: Niklas Cassel <cassel@kernel.org>
---
drivers/pci/controller/cadence/pcie-cadence-ep.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index 2d0a8d78bffb..de10e5edd1b0 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -99,14 +99,11 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS;
} else {
bool is_prefetch = !!(flags & PCI_BASE_ADDRESS_MEM_PREFETCH);
- bool is_64bits = sz > SZ_2G;
+ bool is_64bits = !!(flags & PCI_BASE_ADDRESS_MEM_TYPE_64);
if (is_64bits && (bar & 1))
return -EINVAL;
- if (is_64bits && !(flags & PCI_BASE_ADDRESS_MEM_TYPE_64))
- epf_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
-
if (is_64bits && is_prefetch)
ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS;
else if (is_prefetch)
--
2.44.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v2 7/9] PCI: cadence: Set a 64-bit BAR if requested
2024-03-12 10:51 ` [PATCH v2 7/9] PCI: cadence: Set a 64-bit BAR if requested Niklas Cassel
@ 2024-05-16 20:49 ` Bjorn Helgaas
2024-05-21 12:01 ` Niklas Cassel
0 siblings, 1 reply; 13+ messages in thread
From: Bjorn Helgaas @ 2024-05-16 20:49 UTC (permalink / raw)
To: Niklas Cassel
Cc: Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas,
Shradha Todi, Damien Le Moal, linux-pci, Shawn Lin
[+cc Shawn for Rockchip question]
On Tue, Mar 12, 2024 at 11:51:47AM +0100, Niklas Cassel wrote:
> Ever since commit f25b5fae29d4 ("PCI: endpoint: Setting a BAR size > 4 GB
> is invalid if 64-bit flag is not set") it has been impossible to get the
> .set_bar() callback with a BAR size > 4 GB, if the BAR was also not
> requested to be configured as a 64-bit BAR.
>
> Thus, forcing setting the 64-bit flag for BARs larger than 4 GB in the
> lower level driver is dead code and can be removed.
>
> It is however possible that an EPF driver configures a BAR as 64-bit,
> even if the requested size is < 4 GB.
>
> Respect the requested BAR configuration, just like how it is already
> repected with regards to the prefetchable bit.
>
> Signed-off-by: Niklas Cassel <cassel@kernel.org>
> ---
> drivers/pci/controller/cadence/pcie-cadence-ep.c | 5 +----
> 1 file changed, 1 insertion(+), 4 deletions(-)
>
> diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
> index 2d0a8d78bffb..de10e5edd1b0 100644
> --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
> +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
> @@ -99,14 +99,11 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
> ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS;
> } else {
> bool is_prefetch = !!(flags & PCI_BASE_ADDRESS_MEM_PREFETCH);
> - bool is_64bits = sz > SZ_2G;
> + bool is_64bits = !!(flags & PCI_BASE_ADDRESS_MEM_TYPE_64);
>
> if (is_64bits && (bar & 1))
> return -EINVAL;
Not relevant to *this* patch, but it looks like this code assumes that
a 64-bit BAR must consist of an even-numbered DWORD followed by an
odd-numbered one, e.g., it could be BAR 0 and BAR 1, but not BAR 1 and
BAR 2.
I don't think the PCIe spec requires that. Does the Cadence hardware
require this?
What about Rockchip, which has similar code in
rockchip_pcie_ep_set_bar()?
FWIW, dw_pcie_ep_set_bar() doesn't enforce this restriction.
> - if (is_64bits && !(flags & PCI_BASE_ADDRESS_MEM_TYPE_64))
> - epf_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
> -
> if (is_64bits && is_prefetch)
> ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS;
> else if (is_prefetch)
> --
> 2.44.0
>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v2 7/9] PCI: cadence: Set a 64-bit BAR if requested
2024-05-16 20:49 ` Bjorn Helgaas
@ 2024-05-21 12:01 ` Niklas Cassel
0 siblings, 0 replies; 13+ messages in thread
From: Niklas Cassel @ 2024-05-21 12:01 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas,
Shradha Todi, Damien Le Moal, linux-pci, Shawn Lin
Hello Bjorn,
On Thu, May 16, 2024 at 03:49:07PM -0500, Bjorn Helgaas wrote:
> [+cc Shawn for Rockchip question]
>
> On Tue, Mar 12, 2024 at 11:51:47AM +0100, Niklas Cassel wrote:
> > Ever since commit f25b5fae29d4 ("PCI: endpoint: Setting a BAR size > 4 GB
> > is invalid if 64-bit flag is not set") it has been impossible to get the
> > .set_bar() callback with a BAR size > 4 GB, if the BAR was also not
> > requested to be configured as a 64-bit BAR.
> >
> > Thus, forcing setting the 64-bit flag for BARs larger than 4 GB in the
> > lower level driver is dead code and can be removed.
> >
> > It is however possible that an EPF driver configures a BAR as 64-bit,
> > even if the requested size is < 4 GB.
> >
> > Respect the requested BAR configuration, just like how it is already
> > repected with regards to the prefetchable bit.
> >
> > Signed-off-by: Niklas Cassel <cassel@kernel.org>
> > ---
> > drivers/pci/controller/cadence/pcie-cadence-ep.c | 5 +----
> > 1 file changed, 1 insertion(+), 4 deletions(-)
> >
> > diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
> > index 2d0a8d78bffb..de10e5edd1b0 100644
> > --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
> > +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
> > @@ -99,14 +99,11 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
> > ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS;
> > } else {
> > bool is_prefetch = !!(flags & PCI_BASE_ADDRESS_MEM_PREFETCH);
> > - bool is_64bits = sz > SZ_2G;
> > + bool is_64bits = !!(flags & PCI_BASE_ADDRESS_MEM_TYPE_64);
> >
> > if (is_64bits && (bar & 1))
> > return -EINVAL;
>
> Not relevant to *this* patch, but it looks like this code assumes that
> a 64-bit BAR must consist of an even-numbered DWORD followed by an
> odd-numbered one, e.g., it could be BAR 0 and BAR 1, but not BAR 1 and
> BAR 2.
>
> I don't think the PCIe spec requires that. Does the Cadence hardware
> require this?
The PCIe spec does not seems to require this:
"A Type 0 Configuration Space Header has six DWORD locations allocated for
Base Address registers starting at offset 10h in Configuration Space. [...]
A Function may use any of the locations to implement Base Address registers.
An implemented 64-bit Base Address register consumes two consecutive DWORD
locations."
> What about Rockchip, which has similar code in
> rockchip_pcie_ep_set_bar()?
>
> FWIW, dw_pcie_ep_set_bar() doesn't enforce this restriction.
The Synopsys PCIe controller does have this limitation:
From the DWC databook:
3.5.7.1.1 Overview
Base Address Registers (Offset: 0x100x24)
The controller provides three pairs of 32-bit BARs for each implemented
function. Each pair (BARs 0 and 1, BARs 2 and 3, BARs 4 and 5) can be
configured as follows:
-One 64-bit BAR: For example, BARs 0 and 1 are combined to form a single
64-bit BAR.
-Two 32-bit BARs: For example, BARs 0 and 1 are two independent 32-bit BARs.
-One 32-bit BAR: For example, BAR0 is a 32-bit BAR and BAR1 is either
disabled or removed from the controller altogether to reduce gate count.
So dw_pcie_ep_set_bar() should probably be fixed to enforce this requirement.
(PCI patches for DWC appear to have a tendency to be redirected to /dev/null,
so personally I'm not planning on sending out a patch to enforce this.)
Kind regards,
Niklas
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 8/9] PCI: rockchip-ep: Set a 64-bit BAR if requested
2024-03-12 10:51 [PATCH v2 0/9] PCI: endpoint: set prefetchable bit for 64-bit BARs Niklas Cassel
` (6 preceding siblings ...)
2024-03-12 10:51 ` [PATCH v2 7/9] PCI: cadence: Set a 64-bit BAR if requested Niklas Cassel
@ 2024-03-12 10:51 ` Niklas Cassel
2024-03-12 10:51 ` [PATCH v2 9/9] PCI: endpoint: Set prefetch when allocating memory for 64-bit BARs Niklas Cassel
8 siblings, 0 replies; 13+ messages in thread
From: Niklas Cassel @ 2024-03-12 10:51 UTC (permalink / raw)
To: Manivannan Sadhasivam, Shawn Lin, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas,
Heiko Stuebner
Cc: Shradha Todi, Damien Le Moal, Niklas Cassel, linux-pci,
linux-rockchip, linux-arm-kernel
Ever since commit f25b5fae29d4 ("PCI: endpoint: Setting a BAR size > 4 GB
is invalid if 64-bit flag is not set") it has been impossible to get the
.set_bar() callback with a BAR size > 4 GB, if the BAR was also not
requested to be configured as a 64-bit BAR.
It is however possible that an EPF driver configures a BAR as 64-bit,
even if the requested size is < 4 GB.
Respect the requested BAR configuration, just like how it is already
repected with regards to the prefetchable bit.
Signed-off-by: Niklas Cassel <cassel@kernel.org>
---
drivers/pci/controller/pcie-rockchip-ep.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c
index c9046e97a1d2..57472cf48997 100644
--- a/drivers/pci/controller/pcie-rockchip-ep.c
+++ b/drivers/pci/controller/pcie-rockchip-ep.c
@@ -153,7 +153,7 @@ static int rockchip_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
ctrl = ROCKCHIP_PCIE_CORE_BAR_CFG_CTRL_IO_32BITS;
} else {
bool is_prefetch = !!(flags & PCI_BASE_ADDRESS_MEM_PREFETCH);
- bool is_64bits = sz > SZ_2G;
+ bool is_64bits = !!(flags & PCI_BASE_ADDRESS_MEM_TYPE_64);
if (is_64bits && (bar & 1))
return -EINVAL;
--
2.44.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v2 9/9] PCI: endpoint: Set prefetch when allocating memory for 64-bit BARs
2024-03-12 10:51 [PATCH v2 0/9] PCI: endpoint: set prefetchable bit for 64-bit BARs Niklas Cassel
` (7 preceding siblings ...)
2024-03-12 10:51 ` [PATCH v2 8/9] PCI: rockchip-ep: " Niklas Cassel
@ 2024-03-12 10:51 ` Niklas Cassel
8 siblings, 0 replies; 13+ messages in thread
From: Niklas Cassel @ 2024-03-12 10:51 UTC (permalink / raw)
To: Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Kishon Vijay Abraham I, Bjorn Helgaas
Cc: Shradha Todi, Damien Le Moal, Niklas Cassel, linux-pci
From the PCIe 6.0 base spec:
"Generally only 64-bit BARs are good candidates, since only Legacy
Endpoints are permitted to set the Prefetchable bit in 32-bit BARs,
and most scalable platforms map all 32-bit Memory BARs into
non-prefetchable Memory Space regardless of the Prefetchable bit value."
"For a PCI Express Endpoint, 64-bit addressing must be supported for all
BARs that have the Prefetchable bit Set. 32-bit addressing is permitted
for all BARs that do not have the Prefetchable bit Set."
"Any device that has a range that behaves like normal memory should mark
the range as prefetchable. A linear frame buffer in a graphics device is
an example of a range that should be marked prefetchable."
The PCIe spec tells us that we should have the prefetchable bit set for
64-bit BARs backed by "normal memory". The backing memory that we allocate
for a 64-bit BAR using pci_epf_alloc_space() (which calls
dma_alloc_coherent()) is obviously "normal memory".
Thus, set the prefetchable bit when allocating backing memory for a 64-bit
BAR.
Signed-off-by: Niklas Cassel <cassel@kernel.org>
---
drivers/pci/endpoint/pci-epf-core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index e7dbbeb1f0de..20d2bde0747c 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -309,6 +309,9 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
else
epf_bar[bar].flags |= PCI_BASE_ADDRESS_MEM_TYPE_32;
+ if (epf_bar[bar].flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
+ epf_bar[bar].flags |= PCI_BASE_ADDRESS_MEM_PREFETCH;
+
return space;
}
EXPORT_SYMBOL_GPL(pci_epf_alloc_space);
--
2.44.0
^ permalink raw reply related [flat|nested] 13+ messages in thread