forked from MIrrors/gasket-driver
staging: gasket: don't require all pages to be writable
Buffers to be mapped as DMA_TO_DEVICE must be writable due to the 'write' argument to get_user_pages_fast being hard coded to 1. This prevents userspace from passing in pointers returned from mmap(fd, PROT_READ), instead mmap(fd, PROT_READ | PROT_WRITE) must be used even if the buffer is supposed to be read only. Instead set writable to non zero iff direction != DMA_TO_DEVICE, ie only buffers with DMA_FROM_DEVICE or DMA_BIDIRECTIONAL are required to be writable. Change-Id: I21c97b2bb855e11ecaa6ae9e81cf8b463b4aedaa Signed-off-by: Jonas Larsson <ljonas@google.com>
This commit is contained in:
committed by
Leonid Lobachev
parent
0d361c0493
commit
fa575cdad7
@@ -508,6 +508,7 @@ static int gasket_perform_mapping(struct gasket_page_table *pg_tbl,
|
|||||||
dma_addr_t dma_addr;
|
dma_addr_t dma_addr;
|
||||||
ulong page_addr;
|
ulong page_addr;
|
||||||
int i;
|
int i;
|
||||||
|
enum dma_data_direction direction;
|
||||||
|
|
||||||
/* Must have a virtual host address or a sg iterator, but not both. */
|
/* Must have a virtual host address or a sg iterator, but not both. */
|
||||||
if(!((uintptr_t)host_addr ^ (uintptr_t)sg_iter)) {
|
if(!((uintptr_t)host_addr ^ (uintptr_t)sg_iter)) {
|
||||||
@@ -515,7 +516,8 @@ static int gasket_perform_mapping(struct gasket_page_table *pg_tbl,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GET(FLAGS_DMA_DIRECTION, flags) == DMA_NONE) {
|
direction = GET(FLAGS_DMA_DIRECTION, flags);
|
||||||
|
if (direction == DMA_NONE) {
|
||||||
dev_err(pg_tbl->device, "invalid DMA direction flags=0x%lx\n",
|
dev_err(pg_tbl->device, "invalid DMA direction flags=0x%lx\n",
|
||||||
(unsigned long)flags);
|
(unsigned long)flags);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -542,7 +544,8 @@ static int gasket_perform_mapping(struct gasket_page_table *pg_tbl,
|
|||||||
ptes[i].dma_addr = pg_tbl->coherent_pages[0].paddr +
|
ptes[i].dma_addr = pg_tbl->coherent_pages[0].paddr +
|
||||||
off + i * PAGE_SIZE;
|
off + i * PAGE_SIZE;
|
||||||
} else {
|
} else {
|
||||||
ret = get_user_pages_fast(page_addr - offset, 1, 1,
|
ret = get_user_pages_fast(page_addr - offset, 1,
|
||||||
|
direction != DMA_TO_DEVICE,
|
||||||
&page);
|
&page);
|
||||||
|
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user