Skip to contentSkip to conversation

DSPBRIDGE: cache operation against kernel address instead of user's

PATCH Superseded Omar Ramirez Luna 2 participants 4 messages Jan 23, 2010 – Feb 2, 2010

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

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
index 491661f..eb4752d 100644
@@ -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(&current->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(&current->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(&current->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(&current->mm->mmap_sem);
 
 err_out:
 	GT_2trace(PROC_DebugMask, GT_ENTER,
mm/memory.c +1 -0
index 6ab19dd..377be88 100644
@@ -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
#1 lore raw

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
index 491661f..3e05281 100644
@@ -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(&current->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(&current->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(&current->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(&current->mm->mmap_sem);

err_out:
GT_2trace(PROC_DebugMask, GT_ENTER,

mm/memory.c +1 -0
index 6ab19dd..377be88 100644
@@ -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
#2 lore raw
Quoted 6 lines · Omar Ramirez Luna

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

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
author Applied
#3 lore raw

Hi,

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.html

HACK: export "follow_page()" for dspbridge cache operation

This 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