summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/linux/pci.c
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2018-03-23 08:44:19 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-03-23 20:18:38 -0400
commitb1ac66d41855a9fa6bc6a29ff2259c93cae36532 (patch)
tree1b76f3de06bf7e273e2119f06161ef6f2fc83ce1 /drivers/gpu/nvgpu/common/linux/pci.c
parentcb8d8337a61ead5eb948d78ef24d55d07fa99e7b (diff)
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>
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/pci.c')
-rw-r--r--drivers/gpu/nvgpu/common/linux/pci.c43
1 files changed, 29 insertions, 14 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/pci.c b/drivers/gpu/nvgpu/common/linux/pci.c
index c57674ee..3ea4357f 100644
--- a/drivers/gpu/nvgpu/common/linux/pci.c
+++ b/drivers/gpu/nvgpu/common/linux/pci.c
@@ -549,7 +549,8 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
549 sizeof(struct gk20a_platform)); 549 sizeof(struct gk20a_platform));
550 if (!platform) { 550 if (!platform) {
551 dev_err(&pdev->dev, "couldn't allocate platform data"); 551 dev_err(&pdev->dev, "couldn't allocate platform data");
552 return -ENOMEM; 552 err = -ENOMEM;
553 goto err_free_l;
553 } 554 }
554 555
555 /* copy detected device data to allocated platform space*/ 556 /* copy detected device data to allocated platform space*/
@@ -559,10 +560,8 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
559 pci_set_drvdata(pdev, platform); 560 pci_set_drvdata(pdev, platform);
560 561
561 err = nvgpu_init_enabled_flags(g); 562 err = nvgpu_init_enabled_flags(g);
562 if (err) { 563 if (err)
563 kfree(g); 564 goto err_free_platform;
564 return err;
565 }
566 565
567 platform->g = g; 566 platform->g = g;
568 l->dev = &pdev->dev; 567 l->dev = &pdev->dev;
@@ -575,7 +574,7 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
575 574
576 err = pci_enable_device(pdev); 575 err = pci_enable_device(pdev);
577 if (err) 576 if (err)
578 return err; 577 goto err_free_platform;
579 pci_set_master(pdev); 578 pci_set_master(pdev);
580 579
581 g->pci_vendor_id = pdev->vendor; 580 g->pci_vendor_id = pdev->vendor;
@@ -597,8 +596,10 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
597 596
598 g->irq_stall = pdev->irq; 597 g->irq_stall = pdev->irq;
599 g->irq_nonstall = pdev->irq; 598 g->irq_nonstall = pdev->irq;
600 if (g->irq_stall < 0) 599 if (g->irq_stall < 0) {
601 return -ENXIO; 600 err = -ENXIO;
601 goto err_disable_msi;
602 }
602 603
603 err = devm_request_threaded_irq(&pdev->dev, 604 err = devm_request_threaded_irq(&pdev->dev,
604 g->irq_stall, 605 g->irq_stall,
@@ -611,17 +612,18 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
611 if (err) { 612 if (err) {
612 nvgpu_err(g, 613 nvgpu_err(g,
613 "failed to request irq @ %d", g->irq_stall); 614 "failed to request irq @ %d", g->irq_stall);
614 return err; 615 goto err_disable_msi;
615 } 616 }
616 disable_irq(g->irq_stall); 617 disable_irq(g->irq_stall);
617 618
618 err = nvgpu_pci_init_support(pdev); 619 err = nvgpu_pci_init_support(pdev);
619 if (err) 620 if (err)
620 return err; 621 goto err_free_irq;
621 622
622 if (strchr(dev_name(&pdev->dev), '%')) { 623 if (strchr(dev_name(&pdev->dev), '%')) {
623 nvgpu_err(g, "illegal character in device name"); 624 nvgpu_err(g, "illegal character in device name");
624 return -EINVAL; 625 err = -EINVAL;
626 goto err_free_irq;
625 } 627 }
626 628
627 snprintf(nodefmt, sizeof(nodefmt), 629 snprintf(nodefmt, sizeof(nodefmt),
@@ -629,12 +631,12 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
629 631
630 err = nvgpu_probe(g, "gpu_pci", nodefmt, &nvgpu_pci_class); 632 err = nvgpu_probe(g, "gpu_pci", nodefmt, &nvgpu_pci_class);
631 if (err) 633 if (err)
632 return err; 634 goto err_free_irq;
633 635
634 err = nvgpu_pci_pm_init(&pdev->dev); 636 err = nvgpu_pci_pm_init(&pdev->dev);
635 if (err) { 637 if (err) {
636 nvgpu_err(g, "pm init failed"); 638 nvgpu_err(g, "pm init failed");
637 return err; 639 goto err_free_irq;
638 } 640 }
639 641
640 err = nvgpu_nvlink_probe(g); 642 err = nvgpu_nvlink_probe(g);
@@ -645,13 +647,26 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
645 if (err) { 647 if (err) {
646 if (err != -ENODEV) { 648 if (err != -ENODEV) {
647 nvgpu_err(g, "fatal error probing nvlink, bailing out"); 649 nvgpu_err(g, "fatal error probing nvlink, bailing out");
648 return err; 650 goto err_free_irq;
649 } 651 }
650 } 652 }
651 653
652 g->mm.has_physical_mode = false; 654 g->mm.has_physical_mode = false;
653 655
654 return 0; 656 return 0;
657
658err_free_irq:
659 nvgpu_free_irq(g);
660err_disable_msi:
661#if defined(CONFIG_PCI_MSI)
662 if (g->msi_enabled)
663 pci_disable_msi(pdev);
664#endif
665err_free_platform:
666 nvgpu_kfree(g, platform);
667err_free_l:
668 kfree(l);
669 return err;
655} 670}
656 671
657static void nvgpu_pci_remove(struct pci_dev *pdev) 672static void nvgpu_pci_remove(struct pci_dev *pdev)