Skip to content

Commit

Permalink
misc: pci_endpoint_test: Fix BUG_ON error during pci_disable_msi()
Browse files Browse the repository at this point in the history
commit b7636e8 upstream

pci_disable_msi() throws a Kernel BUG if the driver has successfully
requested an IRQ and not released it. Fix it here by freeing IRQs before
invoking pci_disable_msi().

Signed-off-by: Kishon Vijay Abraham I <[email protected]>
Signed-off-by: Bjorn Helgaas <[email protected]>
Signed-off-by: Mathieu Poirier <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
kishon authored and gregkh committed Nov 12, 2019
1 parent 354d644 commit 3f2beab
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions drivers/misc/pci_endpoint_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ struct pci_endpoint_test {
void __iomem *bar[6];
struct completion irq_raised;
int last_irq;
int num_irqs;
/* mutex to protect the ioctls */
struct mutex mutex;
struct miscdevice miscdev;
Expand Down Expand Up @@ -514,6 +515,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
irq = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI);
if (irq < 0)
dev_err(dev, "failed to get MSI interrupts\n");
test->num_irqs = irq;
}

err = devm_request_irq(dev, pdev->irq, pci_endpoint_test_irqhandler,
Expand Down Expand Up @@ -581,6 +583,9 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
pci_iounmap(pdev, test->bar[bar]);
}

for (i = 0; i < irq; i++)
devm_free_irq(dev, pdev->irq + i, test);

err_disable_msi:
pci_disable_msi(pdev);
pci_release_regions(pdev);
Expand All @@ -594,6 +599,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
static void pci_endpoint_test_remove(struct pci_dev *pdev)
{
int id;
int i;
enum pci_barno bar;
struct pci_endpoint_test *test = pci_get_drvdata(pdev);
struct miscdevice *misc_device = &test->miscdev;
Expand All @@ -609,6 +615,8 @@ static void pci_endpoint_test_remove(struct pci_dev *pdev)
if (test->bar[bar])
pci_iounmap(pdev, test->bar[bar]);
}
for (i = 0; i < test->num_irqs; i++)
devm_free_irq(&pdev->dev, pdev->irq + i, test);
pci_disable_msi(pdev);
pci_release_regions(pdev);
pci_disable_device(pdev);
Expand Down

0 comments on commit 3f2beab

Please sign in to comment.