summaryrefslogtreecommitdiffstats
path: root/arch/avr32/mm
diff options
context:
space:
mode:
authorHaavard Skinnemoen <hskinnemoen@atmel.com>2007-12-03 18:04:11 +0100
committerHaavard Skinnemoen <hskinnemoen@atmel.com>2007-12-07 14:54:47 +0100
commit68ca3e537f12044af05a653fa9d28b4fe80117e8 (patch)
treea8a2e4f9e2e18e031739a8af1e8e3d08af1770ac /arch/avr32/mm
parent[AVR32] Follow the rules when dealing with the OCD system (diff)
downloadlinux-68ca3e537f12044af05a653fa9d28b4fe80117e8.tar.xz
linux-68ca3e537f12044af05a653fa9d28b4fe80117e8.zip
[AVR32] Fix copy_to_user_page() breakage
The current implementation of copy_to_user_page() gives "vaddr" to the cache instruction when trying to sync the icache with the dcache. If vaddr does not exist in the TLB, the CPU will silently abort the operation, which may result in the caches staying out of sync. To fix this, pass the "dst" parameter to flush_icache_range() instead -- we know this is valid because we just wrote to it. Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Diffstat (limited to 'arch/avr32/mm')
-rw-r--r--arch/avr32/mm/cache.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/arch/avr32/mm/cache.c b/arch/avr32/mm/cache.c
index c1233c615e67..15a4e5e142c1 100644
--- a/arch/avr32/mm/cache.c
+++ b/arch/avr32/mm/cache.c
@@ -122,16 +122,6 @@ void flush_icache_page(struct vm_area_struct *vma, struct page *page)
}
}
-/*
- * This one is used by copy_to_user_page()
- */
-void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
- unsigned long addr, int len)
-{
- if (vma->vm_flags & VM_EXEC)
- flush_icache_range(addr, addr + len);
-}
-
asmlinkage int sys_cacheflush(int operation, void __user *addr, size_t len)
{
int ret;
@@ -159,3 +149,13 @@ asmlinkage int sys_cacheflush(int operation, void __user *addr, size_t len)
out:
return ret;
}
+
+void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
+ unsigned long vaddr, void *dst, const void *src,
+ unsigned long len)
+{
+ memcpy(dst, src, len);
+ if (vma->vm_flags & VM_EXEC)
+ flush_icache_range((unsigned long)dst,
+ (unsigned long)dst + len);
+}