Skip to content

Commit 71296ea

Browse files
committed
PCI/TPH: Replace the broken MSI-X control word update
The driver walks the MSI descriptors to test whether a descriptor exists for a given index. That's just abuse of the MSI internals. The same test can be done with a single function call by looking up whether there is a Linux interrupt number assigned at the index. What's worse is that the function is completely unserialized against modifications of the MSI-X control by operations issued from the interrupt core. It also brings the PCI/MSI-X internal cached control word out of sync. Remove the trainwreck and invoke the function provided by the PCI/MSI core to update it. Signed-off-by: Thomas Gleixner <[email protected]> Acked-by: Bjorn Helgaas <[email protected]> Link: https://lore.kernel.org/all/[email protected]
1 parent d5124a9 commit 71296ea

File tree

1 file changed

+1
-43
lines changed

1 file changed

+1
-43
lines changed

drivers/pci/tph.c

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -204,48 +204,6 @@ static u8 get_rp_completer_type(struct pci_dev *pdev)
204204
return FIELD_GET(PCI_EXP_DEVCAP2_TPH_COMP_MASK, reg);
205205
}
206206

207-
/* Write ST to MSI-X vector control reg - Return 0 if OK, otherwise -errno */
208-
static int write_tag_to_msix(struct pci_dev *pdev, int msix_idx, u16 tag)
209-
{
210-
#ifdef CONFIG_PCI_MSI
211-
struct msi_desc *msi_desc = NULL;
212-
void __iomem *vec_ctrl;
213-
u32 val;
214-
int err = 0;
215-
216-
msi_lock_descs(&pdev->dev);
217-
218-
/* Find the msi_desc entry with matching msix_idx */
219-
msi_for_each_desc(msi_desc, &pdev->dev, MSI_DESC_ASSOCIATED) {
220-
if (msi_desc->msi_index == msix_idx)
221-
break;
222-
}
223-
224-
if (!msi_desc) {
225-
err = -ENXIO;
226-
goto err_out;
227-
}
228-
229-
/* Get the vector control register (offset 0xc) pointed by msix_idx */
230-
vec_ctrl = pdev->msix_base + msix_idx * PCI_MSIX_ENTRY_SIZE;
231-
vec_ctrl += PCI_MSIX_ENTRY_VECTOR_CTRL;
232-
233-
val = readl(vec_ctrl);
234-
val &= ~PCI_MSIX_ENTRY_CTRL_ST;
235-
val |= FIELD_PREP(PCI_MSIX_ENTRY_CTRL_ST, tag);
236-
writel(val, vec_ctrl);
237-
238-
/* Read back to flush the update */
239-
val = readl(vec_ctrl);
240-
241-
err_out:
242-
msi_unlock_descs(&pdev->dev);
243-
return err;
244-
#else
245-
return -ENODEV;
246-
#endif
247-
}
248-
249207
/* Write tag to ST table - Return 0 if OK, otherwise -errno */
250208
static int write_tag_to_st_table(struct pci_dev *pdev, int index, u16 tag)
251209
{
@@ -346,7 +304,7 @@ int pcie_tph_set_st_entry(struct pci_dev *pdev, unsigned int index, u16 tag)
346304

347305
switch (loc) {
348306
case PCI_TPH_LOC_MSIX:
349-
err = write_tag_to_msix(pdev, index, tag);
307+
err = pci_msix_write_tph_tag(pdev, index, tag);
350308
break;
351309
case PCI_TPH_LOC_CAP:
352310
err = write_tag_to_st_table(pdev, index, tag);

0 commit comments

Comments
 (0)