From: Sebastian Ott <[email protected]>

commit dba599091c191d209b1499511a524ad9657c0e5a upstream.

After a failure during registration of the dma_table (because of the
function being in error state) we free its memory but don't reset the
associated pointer to zero.

When we then receive a notification from firmware (about the function
being in error state) we'll try to walk and free the dma_table again.

Fix this by resetting the dma_table pointer. In addition to that make
sure that we free the iommu_bitmap when appropriate.

Signed-off-by: Sebastian Ott <[email protected]>
Reviewed-by: Gerald Schaefer <[email protected]>
Signed-off-by: Martin Schwidefsky <[email protected]>
Cc: Sumit Semwal <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
Signed-off-by: Willy Tarreau <[email protected]>
---
 arch/s390/pci/pci_dma.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c
index f8e69d5..aae199b 100644
--- a/arch/s390/pci/pci_dma.c
+++ b/arch/s390/pci/pci_dma.c
@@ -416,7 +416,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
        zdev->dma_table = dma_alloc_cpu_table();
        if (!zdev->dma_table) {
                rc = -ENOMEM;
-               goto out_clean;
+               goto out;
        }
 
        zdev->iommu_size = (unsigned long) high_memory - PAGE_OFFSET;
@@ -429,7 +429,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
                                                       bitmap_order);
        if (!zdev->iommu_bitmap) {
                rc = -ENOMEM;
-               goto out_reg;
+               goto free_dma_table;
        }
 
        rc = zpci_register_ioat(zdev,
@@ -438,12 +438,16 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
                                zdev->start_dma + zdev->iommu_size - 1,
                                (u64) zdev->dma_table);
        if (rc)
-               goto out_reg;
-       return 0;
+               goto free_bitmap;
 
-out_reg:
+       return 0;
+free_bitmap:
+       vfree(zdev->iommu_bitmap);
+       zdev->iommu_bitmap = NULL;
+free_dma_table:
        dma_free_cpu_table(zdev->dma_table);
-out_clean:
+       zdev->dma_table = NULL;
+out:
        return rc;
 }
 
-- 
2.8.0.rc2.1.gbe9624a

Reply via email to