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

Reply via email to