diff options
author | Steven Luo <steven@steven676.net> | 2013-12-07 11:11:16 +0100 |
---|---|---|
committer | Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de> | 2015-12-06 16:58:40 +0100 |
commit | 17021fd920fb5bc97a8c81a20b208c5b38f1b0e8 (patch) | |
tree | c213295cc0af6e9755e42e670937fef540a1df24 | |
parent | 6acceefa2c1d377fbdeae6c37a376950a395ceb9 (diff) | |
download | kernel_samsung_smdk4412-17021fd920fb5bc97a8c81a20b208c5b38f1b0e8.zip kernel_samsung_smdk4412-17021fd920fb5bc97a8c81a20b208c5b38f1b0e8.tar.gz kernel_samsung_smdk4412-17021fd920fb5bc97a8c81a20b208c5b38f1b0e8.tar.bz2 |
tidspbridge: fix last patch to map same region of physical memory as before
Commit 559c71fe5dc3 ("Staging: TIDSPBRIDGE: Use vm_iomap_memory for
mmap-ing instead of remap_pfn_range") had the effect of inadvertently
shifting the start of the physical memory area mapped by
pdata->phys_mempool_base. Correct this by subtracting that shift before
calling vm_iomap_memory() and adding it back afterwards.
Reported-by: Dheeraj CVR <cvr.dheeraj@gmail.com>
Signed-off-by: Steven Luo <steven@steven676.net>
Tested-by: Moritz Bandemer <replicant@posteo.mx>
-rw-r--r-- | drivers/staging/tidspbridge/rmgr/drv_interface.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index 17afc2b..80c2ee5 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -617,6 +617,8 @@ err: static int bridge_mmap(struct file *filp, struct vm_area_struct *vma) { u32 offset = vma->vm_pgoff << PAGE_SHIFT; + unsigned long base_pgoff; + int status; struct omap_dsp_platform_data *pdata = omap_dspbridge_dev->dev.platform_data; @@ -630,9 +632,29 @@ static int bridge_mmap(struct file *filp, struct vm_area_struct *vma) "%lx flags %lx\n", __func__, filp, offset, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma->vm_flags); - return vm_iomap_memory(vma, - pdata->phys_mempool_base, - pdata->phys_mempool_size); + /* + * vm_iomap_memory() expects vma->vm_pgoff to be expressed as an offset + * from the start of the physical memory pool, but we're called with + * a pfn (physical page number) stored there instead. + * + * To avoid duplicating lots of tricky overflow checking logic, + * temporarily convert vma->vm_pgoff to the offset vm_iomap_memory() + * expects, but restore the original value once the mapping has been + * created. + */ + base_pgoff = pdata->phys_mempool_base >> PAGE_SHIFT; + if (vma->vm_pgoff < base_pgoff) + return -EINVAL; + vma->vm_pgoff -= base_pgoff; + + status = vm_iomap_memory(vma, + pdata->phys_mempool_base, + pdata->phys_mempool_size); + + /* Restore the original value of vma->vm_pgoff */ + vma->vm_pgoff += base_pgoff; + + return status; } /* To remove all process resources before removing the process from the |