forked from MIrrors/gasket-driver
staging: gasket: cleanup if dma_map_page fails in gasket_perform_mapping
Previously pages would have never been unmapped in this case. Change-Id: I71b6447267933865ab23a3ba3830e7ce3d3e0e57 Signed-off-by: Nick Ewalt <nicholasewalt@google.com> Signed-off-by: Todd Poynor <toddpoynor@google.com>
This commit is contained in:
@@ -450,6 +450,19 @@ static int is_coherent(struct gasket_page_table *pg_tbl, ulong host_addr)
|
||||
return min <= host_addr && host_addr < max;
|
||||
}
|
||||
|
||||
/* Safely return a page to the OS. */
|
||||
static bool gasket_release_page(struct page *page)
|
||||
{
|
||||
if (!page)
|
||||
return false;
|
||||
|
||||
if (!PageReserved(page))
|
||||
SetPageDirty(page);
|
||||
put_page(page);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get and map last level page table buffers.
|
||||
*
|
||||
@@ -523,6 +536,12 @@ static int gasket_perform_mapping(struct gasket_page_table *pg_tbl,
|
||||
(unsigned long long)ptes[i].dma_addr,
|
||||
(void *)page_to_pfn(page),
|
||||
(void *)page_to_phys(page));
|
||||
|
||||
/* clean up */
|
||||
if (gasket_release_page(ptes[i].page))
|
||||
--pg_tbl->num_active_pages;
|
||||
|
||||
memset(&ptes[i], 0, sizeof(struct gasket_page_table_entry));
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
@@ -596,19 +615,6 @@ static int gasket_alloc_simple_entries(struct gasket_page_table *pg_tbl,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Safely return a page to the OS. */
|
||||
static bool gasket_release_page(struct page *page)
|
||||
{
|
||||
if (!page)
|
||||
return false;
|
||||
|
||||
if (!PageReserved(page))
|
||||
SetPageDirty(page);
|
||||
put_page(page);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unmap and release mapped pages.
|
||||
* The page table mutex must be held by the caller.
|
||||
|
||||
Reference in New Issue
Block a user