Skip to content

Commit 8102763

Browse files
floatiousbjorn-helgaas
authored andcommitted
PCI: dwc: ep: Correct PBA offset in .set_msix() callback
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 <[email protected]> Signed-off-by: Manivannan Sadhasivam <[email protected]> Signed-off-by: Bjorn Helgaas <[email protected]> Reviewed-by: Wilfred Mallawa <[email protected]> Reviewed-by: Damien Le Moal <[email protected]> Cc: [email protected] Link: https://patch.msgid.link/[email protected]
1 parent e5327a6 commit 8102763

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
@@ -585,6 +585,7 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
585585
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
586586
struct dw_pcie_ep_func *ep_func;
587587
u32 val, reg;
588+
u16 actual_interrupts = interrupts + 1;
588589

589590
ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
590591
if (!ep_func || !ep_func->msix_cap)
@@ -595,15 +596,15 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
595596
reg = ep_func->msix_cap + PCI_MSIX_FLAGS;
596597
val = dw_pcie_ep_readw_dbi(ep, func_no, reg);
597598
val &= ~PCI_MSIX_FLAGS_QSIZE;
598-
val |= interrupts;
599+
val |= interrupts; /* 0's based value */
599600
dw_pcie_writew_dbi(pci, reg, val);
600601

601602
reg = ep_func->msix_cap + PCI_MSIX_TABLE;
602603
val = offset | bir;
603604
dw_pcie_ep_writel_dbi(ep, func_no, reg, val);
604605

605606
reg = ep_func->msix_cap + PCI_MSIX_PBA;
606-
val = (offset + (interrupts * PCI_MSIX_ENTRY_SIZE)) | bir;
607+
val = (offset + (actual_interrupts * PCI_MSIX_ENTRY_SIZE)) | bir;
607608
dw_pcie_ep_writel_dbi(ep, func_no, reg, val);
608609

609610
dw_pcie_dbi_ro_wr_dis(pci);

0 commit comments

Comments
 (0)