DSPBRIDGE: cache operation against kernel address instead of user's
Subsystems (2)
PATCH 1/1 DSPBRIDGE: cache operation against kernel address instead of user's
From: Hiroshi DOYU <[email protected]>
Based on the discussion:
http://www.spinics.net/lists/arm-kernel/msg72810.html
HACK: export "follow_page()" for dspbridge cache operation
--- drivers/dsp/bridge/rmgr/proc.c | 68 ++++++++++++++++++++++++++++++--------- mm/memory.c | 1 + 2 files changed, 53 insertions(+), 16 deletions(-)
drivers/dsp/bridge/rmgr/proc.c +52 -16
@@ -574,8 +574,43 @@ DSP_STATUS PROC_EnumNodes(DSP_HPROCESSOR hProcessor, OUT DSP_HNODE *aNodeTab,return status; } +/* Cache operation against kernel address instead of users */ +static int memory_sync_page (struct vm_area_struct *vma,unsigned long start, +ssize_t len,enum DSP_FLUSHTYPE ftype) +{ +struct page *page; +void *kaddr; +unsigned long offset; +ssize_t rest; + +while (len) { + page =follow_page (vma, start,FOLL_GET ); +if (!page) { +pr_err ("%s: no page for %08lx\n" , __func__, start); +return -EINVAL ; + }else if (IS_ERR (page)) { +pr_err ("%s: err page for %08lx(%lu)\n" , __func__, start, +IS_ERR (page)); +return IS_ERR (page); + } + + offset = start & ~PAGE_MASK ; + kaddr =page_address (page) + offset; + rest =min_t (ssize_t,PAGE_SIZE - offset, len); + +MEM_FlushCache (kaddr, rest, ftype); + +put_page (page); + len -= rest; + start += rest; + } + +return 0 ; +} +/* Check if the given area blongs to process virtul memory address space */ -static int memory_check_vma (unsigned long start,u32 len) +static int memory_sync_vma (unsigned long start,u32 len, +enum DSP_FLUSHTYPE ftype) {int err =0 ;unsigned long end;
@@ -585,14 +620,19 @@ static int memory_check_vma(unsigned long start, u32 len)if (end <= start)return -EINVAL ; -down_read (¤t->mm->mmap_sem); -while ((vma =find_vma (current->mm, start)) !=NULL ) { +ssize_t size; -if (vma->vm_start > start) { - err = -EINVAL ; +if (vma->vm_flags & (VM_IO |VM_PFNMAP )) +return -EINVAL ; + +if (vma->vm_start > start) +return -EINVAL ; + + size =min_t (ssize_t, vma->vm_end - start, len); + err =memory_sync_page (vma, start, size, ftype); +if (err)break ; - }if (end <= vma->vm_end)break ;
@@ -603,8 +643,6 @@ static int memory_check_vma(unsigned long start, u32 len)if (!vma) err = -EINVAL ; -up_read (¤t->mm->mmap_sem); -return err; }
@@ -629,17 +667,15 @@ static DSP_STATUS proc_memory_sync(DSP_HPROCESSOR hProcessor, void *pMpuAddr, goto err_out; } -if (memory_check_vma ((u32 )pMpuAddr, ulSize)) { -GT_3trace (PROC_DebugMask,GT_7CLASS , -"%s: InValid address parameters\n" , - __func__, pMpuAddr, ulSize); +down_read (¤t->mm->mmap_sem); + +if (memory_sync_vma ((u32 )pMpuAddr, ulSize, ulFlags)) { +pr_err ("%s: InValid address parameters %p %x\n" , + __func__, pMpuAddr, ulSize); status =DSP_EHANDLE ; - goto err_out; } - (void )SYNC_EnterCS (hProcLock); -MEM_FlushCache (pMpuAddr, ulSize, FlushMemType); - (void )SYNC_LeaveCS (hProcLock); +up_read (¤t->mm->mmap_sem); err_out: GT_2trace(PROC_DebugMask, GT_ENTER,
mm/memory.c +1 -0
@@ -1228,6 +1228,7 @@ no_page_table:return ERR_PTR (-EFAULT );return page; } +EXPORT_SYMBOL_GPL (follow_page); int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, int nr_pages, unsigned int gup_flags,
Signature · 1 line
1.6.2.4
PATCH RESEND 1/1 DSPBRIDGE: cache operation against kernel address instead of user's
From: Hiroshi DOYU <[email protected]>
Based on the discussion:
http://www.spinics.net/lists/arm-kernel/msg72810.html
HACK: export "follow_page()" for dspbridge cache operation
--- drivers/dsp/bridge/rmgr/proc.c | 68 ++++++++++++++++++++++++++++++--------- mm/memory.c | 1 + 2 files changed, 53 insertions(+), 16 deletions(-)
drivers/dsp/bridge/rmgr/proc.c +34 -0
@@ -574,8 +574,43 @@ DSP_STATUS PROC_EnumNodes(DSP_HPROCESSOR hProcessor, OUT DSP_HNODE *aNodeTab,return status; } +/* Cache operation against kernel address instead of users */ +static int memory_sync_page (struct vm_area_struct *vma,unsigned long start, +ssize_t len,enum DSP_FLUSHTYPE ftype) +{ +struct page *page; +void *kaddr; +unsigned long offset; +ssize_t rest; + +while (len) { + page =follow_page (vma, start,FOLL_GET ); +if (!page) { +pr_err ("%s: no page for %08lx\n" , __func__, start); +return -EINVAL ; + }else if (IS_ERR (page)) { +pr_err ("%s: err page for %08lx(%lu)\n" , __func__, start, +IS_ERR (page)); +return IS_ERR (page); + } + + offset = start & ~PAGE_MASK ; + kaddr =page_address (page) + offset; + rest =min_t (ssize_t,PAGE_SIZE - offset, len); + +MEM_FlushCache (kaddr, rest, ftype); + +put_page (page); + len -= rest; + start += rest; + } + +return 0 ; +} +/* Check if the given area blongs to process virtul memory address
space */
-static int memory_check_vma(unsigned long start, u32 len)
+static int memory_sync_vma(unsigned long start, u32 len,
+ enum DSP_FLUSHTYPE ftype)
{
int err = 0;
unsigned long end;
@@ -585,14 +620,19 @@ static int memory_check_vma(unsigned long start, u32 len)
if (end <= start)
return -EINVAL;
- down_read(¤t->mm->mmap_sem);
-
while ((vma = find_vma(current->mm, start)) != NULL) {
+ ssize_t size;
- if (vma->vm_start > start) {
- err = -EINVAL;
+ if (vma->vm_flags & (VM_IO | VM_PFNMAP))
+ return -EINVAL;
+
+ if (vma->vm_start > start)
+ return -EINVAL;
+
+ size = min_t(ssize_t, vma->vm_end - start, len);
+ err = memory_sync_page(vma, start, size, ftype);
+ if (err)
break;
- }
if (end <= vma->vm_end)
break;
@@ -603,8 +643,6 @@ static int memory_check_vma(unsigned long start, u32 len)
if (!vma)
err = -EINVAL;
- up_read(¤t->mm->mmap_sem);
-
return err;
}
@@ -629,17 +667,15 @@ static DSP_STATUS proc_memory_sync(DSP_HPROCESSOR hProcessor, void *pMpuAddr,
goto err_out;
}
- if (memory_check_vma((u32)pMpuAddr, ulSize)) {
- GT_3trace(PROC_DebugMask, GT_7CLASS,
- "%s: InValid address parameters\n",
- __func__, pMpuAddr, ulSize);
+ down_read(¤t->mm->mmap_sem);
+
+ if (memory_sync_vma((u32)pMpuAddr, ulSize, FlushMemType)) {
+ pr_err("%s: InValid address parameters %p %x\n",
+ __func__, pMpuAddr, ulSize);
status = DSP_EHANDLE;
- goto err_out;
}
- (void)SYNC_EnterCS(hProcLock);
- MEM_FlushCache(pMpuAddr, ulSize, FlushMemType);
- (void)SYNC_LeaveCS(hProcLock);
+ up_read(¤t->mm->mmap_sem);
err_out:
GT_2trace(PROC_DebugMask, GT_ENTER,
mm/memory.c +1 -0
@@ -1228,6 +1228,7 @@ no_page_table:return ERR_PTR (-EFAULT );return page; } +EXPORT_SYMBOL_GPL (follow_page); int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, int nr_pages, unsigned int gup_flags,
Signature · 1 line
1.6.2.4
Quoted 6 lines · Omar Ramirez Luna
From: Hiroshi DOYU <[email protected]>
Based on the discussion:
http://www.spinics.net/lists/arm-kernel/msg72810.htmlHACK: export "
follow_page()" for dspbridge cache operation
This is clearly a hack, so what's the plan to fix this in a proper way?
Signature · 5 lines
Felipe Contreras -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Omar Ramirez Luna
AppliedHi,
Quoted 10 lines · Felipe Contreras
Quoted 6 lines · Omar Ramirez Luna
From: Hiroshi DOYU<[email protected]>
Based on the discussion:
http://www.spinics.net/lists/arm-kernel/msg72810.htmlHACK: export "
follow_page()" for dspbridge cache operationThis is clearly a hack, so what's the plan to fix this in a proper way?
Yes it is, we will be investigating how to avoid this.
For now this patch will be pushed until a proper fix is available.
Pushed to dspbridge.
- omar