pciback: properly clean up after calling pcistub_device_find() As the function calls pcistub_device_get() before returning non-NULL, its callers need to take care of calling pcistub_device_put() on (mostly, but not exclusively) error paths. Otoh, the function already guarantees that the 'dev' member is non-NULL upon successful return, so callers do not need to check for this a second time. Signed-off-by: Jan Beulich --- a/drivers/xen/pciback/pci_stub.c +++ b/drivers/xen/pciback/pci_stub.c @@ -642,14 +642,14 @@ static pci_ers_result_t pciback_slot_res dev_err(&dev->dev, "pciback device is not connected or owned" " by HVM, kill it\n"); kill_domain_by_device(psdev); - goto release; + goto end; } if ( !test_bit(_XEN_PCIB_AERHANDLER, (unsigned long *)&psdev->pdev->sh_info->flags) ) { dev_err(&dev->dev, "guest with no AER driver should have been killed\n"); - goto release; + goto end; } result = common_process(psdev, 1, XEN_PCI_OP_aer_slotreset, result); @@ -659,9 +659,9 @@ static pci_ers_result_t pciback_slot_res "No AER slot_reset service or disconnected!\n"); kill_domain_by_device(psdev); } -release: - pcistub_device_put(psdev); end: + if (psdev) + pcistub_device_put(psdev); up_write(&pcistub_sem); return result; @@ -702,14 +702,14 @@ static pci_ers_result_t pciback_mmio_ena dev_err(&dev->dev, "pciback device is not connected or owned" " by HVM, kill it\n"); kill_domain_by_device(psdev); - goto release; + goto end; } if ( !test_bit(_XEN_PCIB_AERHANDLER, (unsigned long *)&psdev->pdev->sh_info->flags) ) { dev_err(&dev->dev, "guest with no AER driver should have been killed\n"); - goto release; + goto end; } result = common_process(psdev, 1, XEN_PCI_OP_aer_mmio, result); @@ -719,9 +719,9 @@ static pci_ers_result_t pciback_mmio_ena "No AER mmio_enabled service or disconnected!\n"); kill_domain_by_device(psdev); } -release: - pcistub_device_put(psdev); end: + if (psdev) + pcistub_device_put(psdev); up_write(&pcistub_sem); return result; } @@ -762,7 +762,7 @@ static pci_ers_result_t pciback_error_de dev_err(&dev->dev, "pciback device is not connected or owned" " by HVM, kill it\n"); kill_domain_by_device(psdev); - goto release; + goto end; } /*Guest owns the device yet no aer handler regiested, kill guest*/ @@ -770,7 +770,7 @@ static pci_ers_result_t pciback_error_de (unsigned long *)&psdev->pdev->sh_info->flags) ) { dev_dbg(&dev->dev, "guest may have no aer driver, kill it\n"); kill_domain_by_device(psdev); - goto release; + goto end; } result = common_process(psdev, error, XEN_PCI_OP_aer_detected, result); @@ -780,9 +780,9 @@ static pci_ers_result_t pciback_error_de "No AER error_detected service or disconnected!\n"); kill_domain_by_device(psdev); } -release: - pcistub_device_put(psdev); end: + if (psdev) + pcistub_device_put(psdev); up_write(&pcistub_sem); return result; } @@ -818,7 +818,7 @@ static void pciback_error_resume(struct dev_err(&dev->dev, "pciback device is not connected or owned" " by HVM, kill it\n"); kill_domain_by_device(psdev); - goto release; + goto end; } if ( !test_bit(_XEN_PCIB_AERHANDLER, @@ -826,12 +826,12 @@ static void pciback_error_resume(struct dev_err(&dev->dev, "guest with no AER driver should have been killed\n"); kill_domain_by_device(psdev); - goto release; + goto end; } common_process(psdev, 1, XEN_PCI_OP_aer_resume, PCI_ERS_RESULT_RECOVERED); -release: - pcistub_device_put(psdev); end: + if (psdev) + pcistub_device_put(psdev); up_write(&pcistub_sem); return; } @@ -988,7 +988,7 @@ static int pcistub_reg_add(int domain, i struct config_field *field; psdev = pcistub_device_find(domain, bus, slot, func); - if (!psdev || !psdev->dev) { + if (!psdev) { err = -ENODEV; goto out; } @@ -1012,6 +1012,8 @@ static int pcistub_reg_add(int domain, i if (err) kfree(field); out: + if (psdev) + pcistub_device_put(psdev); return err; } @@ -1163,10 +1165,7 @@ static ssize_t permissive_add(struct dev err = -ENODEV; goto out; } - if (!psdev->dev) { - err = -ENODEV; - goto release; - } + dev_data = pci_get_drvdata(psdev->dev); /* the driver data for a device should never be null at this point */ if (!dev_data) { @@ -1219,14 +1218,18 @@ DRIVER_ATTR(permissive, S_IRUSR | S_IWUS int pciback_get_owner(struct pci_dev *dev) { struct pcistub_device *psdev; + int rc; psdev = pcistub_device_find(pci_domain_nr(dev->bus), dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); - if (!psdev || !psdev->pdev) - return -1; + if (!psdev) + return -ESRCH; + + rc = psdev->pdev ? psdev->pdev->xdev->otherend_id : -EINVAL; - return psdev->pdev->xdev->otherend_id; + pcistub_device_put(psdev); + return rc; } #endif