aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSteven Luo <steven@steven676.net>2013-12-07 11:11:16 +0100
committerWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2015-12-06 16:58:40 +0100
commit17021fd920fb5bc97a8c81a20b208c5b38f1b0e8 (patch)
treec213295cc0af6e9755e42e670937fef540a1df24 /drivers
parent6acceefa2c1d377fbdeae6c37a376950a395ceb9 (diff)
downloadkernel_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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/tidspbridge/rmgr/drv_interface.c28
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