[WIP PATCH v3 5/7] PCI: endpoint: pci-epf-test: Use hardware-owned MSI-X layout

From: Koichiro Den

Date: Tue Sep 01 2026 - 03:07:59 EST


pci-epf-test always allocates an MSI-X Table and PBA in its test register
BAR. This duplicates fixed regions provided by endpoint controllers that
own the MSI-X layout.

Use the hardware-owned layout when it can hold the configured MSI-X
entries and omit the duplicate regions from the test register BAR. Keep
the existing EPF-owned layout as the fallback.

Signed-off-by: Koichiro Den <den@xxxxxxxxxxxxx>
---
Changes in v3:
- New patch.
---
drivers/pci/endpoint/functions/pci-epf-test.c | 36 +++++++++++++------
1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index 360df7775110..02505f7ca6c8 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -1278,20 +1278,36 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
enum pci_barno bar;
const struct pci_epc_features *epc_features = epf_test->epc_features;
size_t test_reg_size;
+ int ret;

test_reg_bar_size = ALIGN(sizeof(struct pci_epf_test_reg), 128);

if (epc_features->msix_capable) {
- msix_table_size = PCI_MSIX_ENTRY_SIZE * epf->msix_interrupts;
- pba_size = BITS_TO_U64(epf->msix_interrupts) * sizeof(u64);
-
- epf_test->msix_layout.table_bar = test_reg_bar;
- epf_test->msix_layout.table_offset = test_reg_bar_size;
- epf_test->msix_layout.table_size = msix_table_size;
- epf_test->msix_layout.pba_bar = test_reg_bar;
- epf_test->msix_layout.pba_offset = test_reg_bar_size +
- msix_table_size;
- epf_test->msix_layout.pba_size = pba_size;
+ ret = pci_epc_get_hw_msix_layout(epc_features,
+ &epf_test->msix_layout);
+ if (ret && ret != -ENOENT) {
+ dev_err(dev, "Invalid hardware-owned MSI-X layout\n");
+ return ret;
+ }
+
+ if (ret == -ENOENT ||
+ epf_test->msix_layout.table_size <
+ PCI_MSIX_ENTRY_SIZE * epf->msix_interrupts ||
+ epf_test->msix_layout.pba_size <
+ BITS_TO_U64(epf->msix_interrupts) * sizeof(u64)) {
+ msix_table_size =
+ PCI_MSIX_ENTRY_SIZE * epf->msix_interrupts;
+ pba_size = BITS_TO_U64(epf->msix_interrupts) *
+ sizeof(u64);
+
+ epf_test->msix_layout.table_bar = test_reg_bar;
+ epf_test->msix_layout.table_offset = test_reg_bar_size;
+ epf_test->msix_layout.table_size = msix_table_size;
+ epf_test->msix_layout.pba_bar = test_reg_bar;
+ epf_test->msix_layout.pba_offset =
+ test_reg_bar_size + msix_table_size;
+ epf_test->msix_layout.pba_size = pba_size;
+ }
}
test_reg_size = test_reg_bar_size + msix_table_size + pba_size;

--
2.51.0