Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6aa70a0 authored by Jan Beulich's avatar Jan Beulich Committed by Konrad Rzeszutek Wilk
Browse files

xen-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: default avatarJan Beulich <jbeulich@suse.com>
Signed-off-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
parent aa387d63
Loading
Loading
Loading
Loading
+23 −23
Original line number Original line Diff line number Diff line
@@ -681,14 +681,14 @@ static pci_ers_result_t xen_pcibk_slot_reset(struct pci_dev *dev)
		dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
		dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
			" by HVM, kill it\n");
			" by HVM, kill it\n");
		kill_domain_by_device(psdev);
		kill_domain_by_device(psdev);
		goto release;
		goto end;
	}
	}


	if (!test_bit(_XEN_PCIB_AERHANDLER,
	if (!test_bit(_XEN_PCIB_AERHANDLER,
		(unsigned long *)&psdev->pdev->sh_info->flags)) {
		(unsigned long *)&psdev->pdev->sh_info->flags)) {
		dev_err(&dev->dev,
		dev_err(&dev->dev,
			"guest with no AER driver should have been killed\n");
			"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);
	result = common_process(psdev, 1, XEN_PCI_OP_aer_slotreset, result);


@@ -698,9 +698,9 @@ static pci_ers_result_t xen_pcibk_slot_reset(struct pci_dev *dev)
			"No AER slot_reset service or disconnected!\n");
			"No AER slot_reset service or disconnected!\n");
		kill_domain_by_device(psdev);
		kill_domain_by_device(psdev);
	}
	}
release:
	pcistub_device_put(psdev);
end:
end:
	if (psdev)
		pcistub_device_put(psdev);
	up_write(&pcistub_sem);
	up_write(&pcistub_sem);
	return result;
	return result;


@@ -739,14 +739,14 @@ static pci_ers_result_t xen_pcibk_mmio_enabled(struct pci_dev *dev)
		dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
		dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
			" by HVM, kill it\n");
			" by HVM, kill it\n");
		kill_domain_by_device(psdev);
		kill_domain_by_device(psdev);
		goto release;
		goto end;
	}
	}


	if (!test_bit(_XEN_PCIB_AERHANDLER,
	if (!test_bit(_XEN_PCIB_AERHANDLER,
		(unsigned long *)&psdev->pdev->sh_info->flags)) {
		(unsigned long *)&psdev->pdev->sh_info->flags)) {
		dev_err(&dev->dev,
		dev_err(&dev->dev,
			"guest with no AER driver should have been killed\n");
			"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);
	result = common_process(psdev, 1, XEN_PCI_OP_aer_mmio, result);


@@ -756,9 +756,9 @@ static pci_ers_result_t xen_pcibk_mmio_enabled(struct pci_dev *dev)
			"No AER mmio_enabled service or disconnected!\n");
			"No AER mmio_enabled service or disconnected!\n");
		kill_domain_by_device(psdev);
		kill_domain_by_device(psdev);
	}
	}
release:
	pcistub_device_put(psdev);
end:
end:
	if (psdev)
		pcistub_device_put(psdev);
	up_write(&pcistub_sem);
	up_write(&pcistub_sem);
	return result;
	return result;
}
}
@@ -797,7 +797,7 @@ static pci_ers_result_t xen_pcibk_error_detected(struct pci_dev *dev,
		dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
		dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
			" by HVM, kill it\n");
			" by HVM, kill it\n");
		kill_domain_by_device(psdev);
		kill_domain_by_device(psdev);
		goto release;
		goto end;
	}
	}


	/*Guest owns the device yet no aer handler regiested, kill guest*/
	/*Guest owns the device yet no aer handler regiested, kill guest*/
@@ -805,7 +805,7 @@ static pci_ers_result_t xen_pcibk_error_detected(struct pci_dev *dev,
		(unsigned long *)&psdev->pdev->sh_info->flags)) {
		(unsigned long *)&psdev->pdev->sh_info->flags)) {
		dev_dbg(&dev->dev, "guest may have no aer driver, kill it\n");
		dev_dbg(&dev->dev, "guest may have no aer driver, kill it\n");
		kill_domain_by_device(psdev);
		kill_domain_by_device(psdev);
		goto release;
		goto end;
	}
	}
	result = common_process(psdev, error, XEN_PCI_OP_aer_detected, result);
	result = common_process(psdev, error, XEN_PCI_OP_aer_detected, result);


@@ -815,9 +815,9 @@ static pci_ers_result_t xen_pcibk_error_detected(struct pci_dev *dev,
			"No AER error_detected service or disconnected!\n");
			"No AER error_detected service or disconnected!\n");
		kill_domain_by_device(psdev);
		kill_domain_by_device(psdev);
	}
	}
release:
	pcistub_device_put(psdev);
end:
end:
	if (psdev)
		pcistub_device_put(psdev);
	up_write(&pcistub_sem);
	up_write(&pcistub_sem);
	return result;
	return result;
}
}
@@ -851,7 +851,7 @@ static void xen_pcibk_error_resume(struct pci_dev *dev)
		dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
		dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
			" by HVM, kill it\n");
			" by HVM, kill it\n");
		kill_domain_by_device(psdev);
		kill_domain_by_device(psdev);
		goto release;
		goto end;
	}
	}


	if (!test_bit(_XEN_PCIB_AERHANDLER,
	if (!test_bit(_XEN_PCIB_AERHANDLER,
@@ -859,13 +859,13 @@ static void xen_pcibk_error_resume(struct pci_dev *dev)
		dev_err(&dev->dev,
		dev_err(&dev->dev,
			"guest with no AER driver should have been killed\n");
			"guest with no AER driver should have been killed\n");
		kill_domain_by_device(psdev);
		kill_domain_by_device(psdev);
		goto release;
		goto end;
	}
	}
	common_process(psdev, 1, XEN_PCI_OP_aer_resume,
	common_process(psdev, 1, XEN_PCI_OP_aer_resume,
		       PCI_ERS_RESULT_RECOVERED);
		       PCI_ERS_RESULT_RECOVERED);
release:
	pcistub_device_put(psdev);
end:
end:
	if (psdev)
		pcistub_device_put(psdev);
	up_write(&pcistub_sem);
	up_write(&pcistub_sem);
	return;
	return;
}
}
@@ -1024,7 +1024,7 @@ static int pcistub_reg_add(int domain, int bus, int slot, int func, int reg,
	struct config_field *field;
	struct config_field *field;


	psdev = pcistub_device_find(domain, bus, slot, func);
	psdev = pcistub_device_find(domain, bus, slot, func);
	if (!psdev || !psdev->dev) {
	if (!psdev) {
		err = -ENODEV;
		err = -ENODEV;
		goto out;
		goto out;
	}
	}
@@ -1048,6 +1048,8 @@ static int pcistub_reg_add(int domain, int bus, int slot, int func, int reg,
	if (err)
	if (err)
		kfree(field);
		kfree(field);
out:
out:
	if (psdev)
		pcistub_device_put(psdev);
	return err;
	return err;
}
}


@@ -1152,10 +1154,9 @@ static ssize_t pcistub_irq_handler_switch(struct device_driver *drv,


	err = str_to_slot(buf, &domain, &bus, &slot, &func);
	err = str_to_slot(buf, &domain, &bus, &slot, &func);
	if (err)
	if (err)
		goto out;
		return err;


	psdev = pcistub_device_find(domain, bus, slot, func);
	psdev = pcistub_device_find(domain, bus, slot, func);

	if (!psdev)
	if (!psdev)
		goto out;
		goto out;


@@ -1171,6 +1172,8 @@ static ssize_t pcistub_irq_handler_switch(struct device_driver *drv,
	if (dev_data->isr_on)
	if (dev_data->isr_on)
		dev_data->ack_intr = 1;
		dev_data->ack_intr = 1;
out:
out:
	if (psdev)
		pcistub_device_put(psdev);
	if (!err)
	if (!err)
		err = count;
		err = count;
	return err;
	return err;
@@ -1262,10 +1265,7 @@ static ssize_t permissive_add(struct device_driver *drv, const char *buf,
		err = -ENODEV;
		err = -ENODEV;
		goto out;
		goto out;
	}
	}
	if (!psdev->dev) {

		err = -ENODEV;
		goto release;
	}
	dev_data = pci_get_drvdata(psdev->dev);
	dev_data = pci_get_drvdata(psdev->dev);
	/* the driver data for a device should never be null at this point */
	/* the driver data for a device should never be null at this point */
	if (!dev_data) {
	if (!dev_data) {