staging: gasket: page_table: handle failed dma_map_page
authorNick Ewalt <nicholasewalt@google.com>
Mon, 17 Sep 2018 12:39:05 +0000 (05:39 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 18 Sep 2018 11:22:01 +0000 (13:22 +0200)
Handle dma_map_page failing in gasket_alloc_extended_subtable: free
memory, don't add invalid page table entry.

Signed-off-by: Nick Ewalt <nicholasewalt@google.com>
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/gasket/gasket_page_table.c

index 8364b49f147c2c45c8d26934a6af131ebef40a6d..964146f0df526e8321cb1991d11a76e5f16aca4c 100644 (file)
@@ -902,6 +902,17 @@ static int gasket_alloc_extended_subtable(struct gasket_page_table *pg_tbl,
        /* Map the page into DMA space. */
        pte->dma_addr = dma_map_page(pg_tbl->device, pte->page, 0, PAGE_SIZE,
                                     DMA_TO_DEVICE);
+       if (dma_mapping_error(pg_tbl->device, pte->dma_addr)) {
+               dev_dbg(pg_tbl->device,
+                       "%s: fail to map page [pfn %lx phys %llx]\n",
+                       __func__, page_to_pfn(pte->page),
+                       page_to_phys(pte->page));
+
+               free_page(page_addr);
+               vfree(pte->sublevel);
+               memset(pte, 0, sizeof(struct gasket_page_table_entry));
+               return -ENOMEM;
+       }
 
        /* make the addresses available to the device */
        dma_addr = (pte->dma_addr + pte->offset) | GASKET_VALID_SLOT_FLAG;