Skip to content

Commit ae67236

Browse files
floatioussmb49
authored andcommitted
PCI: dwc: ep: Correct PBA offset in .set_msix() callback
BugLink: https://bugs.launchpad.net/bugs/2120812 commit 810276362bad172d063d1f6be1cc2cb425b90103 upstream. While dw_pcie_ep_set_msix() writes the Table Size field correctly (N-1), the calculation of the PBA offset is wrong because it calculates space for (N-1) entries instead of N. This results in the following QEMU error when using PCI passthrough on a device which relies on the PCI endpoint subsystem: failed to add PCI capability 0x11[0x50]@0xb0: table & pba overlap, or they don't fit in BARs, or don't align Fix the calculation of PBA offset in the MSI-X capability. [bhelgaas: more specific subject and commit log] Fixes: 83153d9 ("PCI: endpoint: Fix ->set_msix() to take BIR and offset as arguments") Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20250514074313.283156-9-cassel@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Noah Wager <noah.wager@canonical.com> Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
1 parent e491c81 commit ae67236

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

drivers/pci/controller/dwc/pcie-designware-ep.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
415415
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
416416
struct dw_pcie_ep_func *ep_func;
417417
u32 val, reg;
418+
u16 actual_interrupts = interrupts + 1;
418419

419420
ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
420421
if (!ep_func || !ep_func->msix_cap)
@@ -425,15 +426,15 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
425426
reg = ep_func->msix_cap + PCI_MSIX_FLAGS;
426427
val = dw_pcie_ep_readw_dbi(ep, func_no, reg);
427428
val &= ~PCI_MSIX_FLAGS_QSIZE;
428-
val |= interrupts;
429+
val |= interrupts; /* 0's based value */
429430
dw_pcie_writew_dbi(pci, reg, val);
430431

431432
reg = ep_func->msix_cap + PCI_MSIX_TABLE;
432433
val = offset | bir;
433434
dw_pcie_ep_writel_dbi(ep, func_no, reg, val);
434435

435436
reg = ep_func->msix_cap + PCI_MSIX_PBA;
436-
val = (offset + (interrupts * PCI_MSIX_ENTRY_SIZE)) | bir;
437+
val = (offset + (actual_interrupts * PCI_MSIX_ENTRY_SIZE)) | bir;
437438
dw_pcie_ep_writel_dbi(ep, func_no, reg, val);
438439

439440
dw_pcie_dbi_ro_wr_dis(pci);

0 commit comments

Comments
 (0)