mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 09:57:08 +03:00
gpu: nvgpu: fix memory leaks in error path
Error path is not implemented in nvgpu_pci_probe(), and that could lead to memory leaks if any of the step in nvgpu_pci_probe() fails Fix this by implementing error path and freeing all allocated buffers Bug 200291879 Coverify defect id : 2845621 Change-Id: Iee1abb041089e47a517a6698f0a4067c9c4fa289 Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1681028 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
cb8d8337a6
commit
b1ac66d418
@@ -549,7 +549,8 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
|
|||||||
sizeof(struct gk20a_platform));
|
sizeof(struct gk20a_platform));
|
||||||
if (!platform) {
|
if (!platform) {
|
||||||
dev_err(&pdev->dev, "couldn't allocate platform data");
|
dev_err(&pdev->dev, "couldn't allocate platform data");
|
||||||
return -ENOMEM;
|
err = -ENOMEM;
|
||||||
|
goto err_free_l;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy detected device data to allocated platform space*/
|
/* copy detected device data to allocated platform space*/
|
||||||
@@ -559,10 +560,8 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
|
|||||||
pci_set_drvdata(pdev, platform);
|
pci_set_drvdata(pdev, platform);
|
||||||
|
|
||||||
err = nvgpu_init_enabled_flags(g);
|
err = nvgpu_init_enabled_flags(g);
|
||||||
if (err) {
|
if (err)
|
||||||
kfree(g);
|
goto err_free_platform;
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
platform->g = g;
|
platform->g = g;
|
||||||
l->dev = &pdev->dev;
|
l->dev = &pdev->dev;
|
||||||
@@ -575,7 +574,7 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
|
|||||||
|
|
||||||
err = pci_enable_device(pdev);
|
err = pci_enable_device(pdev);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto err_free_platform;
|
||||||
pci_set_master(pdev);
|
pci_set_master(pdev);
|
||||||
|
|
||||||
g->pci_vendor_id = pdev->vendor;
|
g->pci_vendor_id = pdev->vendor;
|
||||||
@@ -597,8 +596,10 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
|
|||||||
|
|
||||||
g->irq_stall = pdev->irq;
|
g->irq_stall = pdev->irq;
|
||||||
g->irq_nonstall = pdev->irq;
|
g->irq_nonstall = pdev->irq;
|
||||||
if (g->irq_stall < 0)
|
if (g->irq_stall < 0) {
|
||||||
return -ENXIO;
|
err = -ENXIO;
|
||||||
|
goto err_disable_msi;
|
||||||
|
}
|
||||||
|
|
||||||
err = devm_request_threaded_irq(&pdev->dev,
|
err = devm_request_threaded_irq(&pdev->dev,
|
||||||
g->irq_stall,
|
g->irq_stall,
|
||||||
@@ -611,17 +612,18 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
|
|||||||
if (err) {
|
if (err) {
|
||||||
nvgpu_err(g,
|
nvgpu_err(g,
|
||||||
"failed to request irq @ %d", g->irq_stall);
|
"failed to request irq @ %d", g->irq_stall);
|
||||||
return err;
|
goto err_disable_msi;
|
||||||
}
|
}
|
||||||
disable_irq(g->irq_stall);
|
disable_irq(g->irq_stall);
|
||||||
|
|
||||||
err = nvgpu_pci_init_support(pdev);
|
err = nvgpu_pci_init_support(pdev);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto err_free_irq;
|
||||||
|
|
||||||
if (strchr(dev_name(&pdev->dev), '%')) {
|
if (strchr(dev_name(&pdev->dev), '%')) {
|
||||||
nvgpu_err(g, "illegal character in device name");
|
nvgpu_err(g, "illegal character in device name");
|
||||||
return -EINVAL;
|
err = -EINVAL;
|
||||||
|
goto err_free_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(nodefmt, sizeof(nodefmt),
|
snprintf(nodefmt, sizeof(nodefmt),
|
||||||
@@ -629,12 +631,12 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
|
|||||||
|
|
||||||
err = nvgpu_probe(g, "gpu_pci", nodefmt, &nvgpu_pci_class);
|
err = nvgpu_probe(g, "gpu_pci", nodefmt, &nvgpu_pci_class);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto err_free_irq;
|
||||||
|
|
||||||
err = nvgpu_pci_pm_init(&pdev->dev);
|
err = nvgpu_pci_pm_init(&pdev->dev);
|
||||||
if (err) {
|
if (err) {
|
||||||
nvgpu_err(g, "pm init failed");
|
nvgpu_err(g, "pm init failed");
|
||||||
return err;
|
goto err_free_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = nvgpu_nvlink_probe(g);
|
err = nvgpu_nvlink_probe(g);
|
||||||
@@ -645,13 +647,26 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
|
|||||||
if (err) {
|
if (err) {
|
||||||
if (err != -ENODEV) {
|
if (err != -ENODEV) {
|
||||||
nvgpu_err(g, "fatal error probing nvlink, bailing out");
|
nvgpu_err(g, "fatal error probing nvlink, bailing out");
|
||||||
return err;
|
goto err_free_irq;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g->mm.has_physical_mode = false;
|
g->mm.has_physical_mode = false;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_free_irq:
|
||||||
|
nvgpu_free_irq(g);
|
||||||
|
err_disable_msi:
|
||||||
|
#if defined(CONFIG_PCI_MSI)
|
||||||
|
if (g->msi_enabled)
|
||||||
|
pci_disable_msi(pdev);
|
||||||
|
#endif
|
||||||
|
err_free_platform:
|
||||||
|
nvgpu_kfree(g, platform);
|
||||||
|
err_free_l:
|
||||||
|
kfree(l);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nvgpu_pci_remove(struct pci_dev *pdev)
|
static void nvgpu_pci_remove(struct pci_dev *pdev)
|
||||||
|
|||||||
Reference in New Issue
Block a user