mirror of https://gitee.com/openkylin/linux.git
Merge branch 'pci/endpoint' into next
* pci/endpoint: misc: pci_endpoint_test: Fix BUG_ON error during pci_disable_msi() misc: pci_endpoint_test: Fix pci_endpoint_test not releasing resources on remove misc: pci_endpoint_test: Fix failure path return values in probe misc: pci_endpoint_test: Avoid triggering a BUG() misc: pci_endpoint_test: Prevent some integer overflows
This commit is contained in:
commit
1a03bac303
|
@ -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;
|
||||
|
@ -226,6 +227,9 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size)
|
|||
u32 src_crc32;
|
||||
u32 dst_crc32;
|
||||
|
||||
if (size > SIZE_MAX - alignment)
|
||||
goto err;
|
||||
|
||||
orig_src_addr = dma_alloc_coherent(dev, size + alignment,
|
||||
&orig_src_phys_addr, GFP_KERNEL);
|
||||
if (!orig_src_addr) {
|
||||
|
@ -311,6 +315,9 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size)
|
|||
size_t alignment = test->alignment;
|
||||
u32 crc32;
|
||||
|
||||
if (size > SIZE_MAX - alignment)
|
||||
goto err;
|
||||
|
||||
orig_addr = dma_alloc_coherent(dev, size + alignment, &orig_phys_addr,
|
||||
GFP_KERNEL);
|
||||
if (!orig_addr) {
|
||||
|
@ -369,6 +376,9 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size)
|
|||
size_t alignment = test->alignment;
|
||||
u32 crc32;
|
||||
|
||||
if (size > SIZE_MAX - alignment)
|
||||
goto err;
|
||||
|
||||
orig_addr = dma_alloc_coherent(dev, size + alignment, &orig_phys_addr,
|
||||
GFP_KERNEL);
|
||||
if (!orig_addr) {
|
||||
|
@ -504,6 +514,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,
|
||||
|
@ -533,6 +544,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
|
|||
|
||||
test->base = test->bar[test_reg_bar];
|
||||
if (!test->base) {
|
||||
err = -ENOMEM;
|
||||
dev_err(dev, "Cannot perform PCI test without BAR%d\n",
|
||||
test_reg_bar);
|
||||
goto err_iounmap;
|
||||
|
@ -542,6 +554,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
|
|||
|
||||
id = ida_simple_get(&pci_endpoint_test_ida, 0, 0, GFP_KERNEL);
|
||||
if (id < 0) {
|
||||
err = id;
|
||||
dev_err(dev, "unable to get id\n");
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
@ -549,17 +562,24 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
|
|||
snprintf(name, sizeof(name), DRV_MODULE_NAME ".%d", id);
|
||||
misc_device = &test->miscdev;
|
||||
misc_device->minor = MISC_DYNAMIC_MINOR;
|
||||
misc_device->name = name;
|
||||
misc_device->name = kstrdup(name, GFP_KERNEL);
|
||||
if (!misc_device->name) {
|
||||
err = -ENOMEM;
|
||||
goto err_ida_remove;
|
||||
}
|
||||
misc_device->fops = &pci_endpoint_test_fops,
|
||||
|
||||
err = misc_register(misc_device);
|
||||
if (err) {
|
||||
dev_err(dev, "failed to register device\n");
|
||||
goto err_ida_remove;
|
||||
goto err_kfree_name;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_kfree_name:
|
||||
kfree(misc_device->name);
|
||||
|
||||
err_ida_remove:
|
||||
ida_simple_remove(&pci_endpoint_test_ida, id);
|
||||
|
||||
|
@ -569,6 +589,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);
|
||||
|
@ -582,19 +605,25 @@ 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;
|
||||
|
||||
if (sscanf(misc_device->name, DRV_MODULE_NAME ".%d", &id) != 1)
|
||||
return;
|
||||
if (id < 0)
|
||||
return;
|
||||
|
||||
misc_deregister(&test->miscdev);
|
||||
kfree(misc_device->name);
|
||||
ida_simple_remove(&pci_endpoint_test_ida, id);
|
||||
for (bar = BAR_0; bar <= BAR_5; bar++) {
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue