The function pcim_enable_device() sets the is_managed flag, which causes the device's IRQ vectors to be automatically managed and released by the devres framework. If a driver subsequently calls pci_free_irq_vectors() manually, it can lead to a double-free of the interrupt resources.
Analysis reveals most PCI drivers call pci_free_irq_vectors() while also using pcim_enable_device(), making them susceptible to this double-free issue. In contrast, 35 drivers follow the pattern of relying on devres to handle the cleanup. To address this inconsistency and enforce explicit, driver-managed control of IRQ vectors, this patch removes the pci_is_managed() check from pcim_setup_msi_release() and let devres help cleanup if is_msi_managed is true. This change ensures that interrupt vectors are not automatically freed by the devres machinery when pcim_enable_device() is used, placing the responsibility for their release squarely on the driver logic via pci_free_irq_vectors(). If the driver need devres to help cleanup, newly added pcim_alloc_irq_vectors() and pcim_alloc_irq_vectors_affinity() helpers could be used. Signed-off-by: Shawn Lin <[email protected]> --- drivers/pci/msi/msi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c index 81d24a2..0727a0a 100644 --- a/drivers/pci/msi/msi.c +++ b/drivers/pci/msi/msi.c @@ -70,7 +70,6 @@ static void pcim_msi_release(void *pcidev) { struct pci_dev *dev = pcidev; - dev->is_msi_managed = false; pci_free_irq_vectors(dev); } @@ -92,14 +91,13 @@ static int pcim_setup_msi_release(struct pci_dev *dev) { int ret; - if (!pci_is_managed(dev) || dev->is_msi_managed) + if (!dev->is_msi_managed) return 0; ret = devm_add_action(&dev->dev, pcim_msi_release, dev); if (ret) return ret; - dev->is_msi_managed = true; return 0; } -- 2.7.4
