Skip to content

Commit c8bcb01

Browse files
floatiousbjorn-helgaas
authored andcommitted
PCI: cadence-ep: Correct PBA offset in .set_msix() callback
While cdns_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: 3ef5d16 ("PCI: cadence: Add MSI-X support to Endpoint driver") 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 8102763 commit c8bcb01

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

drivers/pci/controller/cadence/pcie-cadence-ep.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,13 +292,14 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
292292
struct cdns_pcie *pcie = &ep->pcie;
293293
u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
294294
u32 val, reg;
295+
u16 actual_interrupts = interrupts + 1;
295296

296297
fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
297298

298299
reg = cap + PCI_MSIX_FLAGS;
299300
val = cdns_pcie_ep_fn_readw(pcie, fn, reg);
300301
val &= ~PCI_MSIX_FLAGS_QSIZE;
301-
val |= interrupts;
302+
val |= interrupts; /* 0's based value */
302303
cdns_pcie_ep_fn_writew(pcie, fn, reg, val);
303304

304305
/* Set MSI-X BAR and offset */
@@ -308,7 +309,7 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
308309

309310
/* Set PBA BAR and offset. BAR must match MSI-X BAR */
310311
reg = cap + PCI_MSIX_PBA;
311-
val = (offset + (interrupts * PCI_MSIX_ENTRY_SIZE)) | bir;
312+
val = (offset + (actual_interrupts * PCI_MSIX_ENTRY_SIZE)) | bir;
312313
cdns_pcie_ep_fn_writel(pcie, fn, reg, val);
313314

314315
return 0;

0 commit comments

Comments
 (0)