aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-mips/cacheflush.h
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2006-10-21 23:17:35 +0100
committerRalf Baechle <ralf@linux-mips.org>2006-10-21 23:17:35 +0100
commitf8829caee311207afbc882794bdc5aa0db5caf33 (patch)
treedbadd9fa746a1a4f091bc7e240ca8d787188a913 /include/asm-mips/cacheflush.h
parent[MIPS] Cleanup remaining references to mips_counter_frequency. (diff)
downloadlinux-dev-f8829caee311207afbc882794bdc5aa0db5caf33.tar.xz
linux-dev-f8829caee311207afbc882794bdc5aa0db5caf33.zip
[MIPS] Fix aliasing bug in copy_to_user_page / copy_from_user_page
The current implementation uses a sequence of a cacheflush and a copy. This is racy in case of a multithreaded debuggee and renders GDB virtually unusable. Aside this fixes a performance hog rendering access to /proc/cmdline very slow and resulting in a enough cache stalls for the 34K AP/SP programming model to make the bare metal code on the non-Linux VPE miss RT deadlines. The main part of this patch was originally written by Ralf Baechle; Atushi Nemoto did the the debugging. Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'include/asm-mips/cacheflush.h')
-rw-r--r--include/asm-mips/cacheflush.h19
1 files changed, 4 insertions, 15 deletions
diff --git a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h
index 9ab59e2bb233..e3c9925876a3 100644
--- a/include/asm-mips/cacheflush.h
+++ b/include/asm-mips/cacheflush.h
@@ -55,24 +55,13 @@ extern void (*flush_icache_range)(unsigned long start, unsigned long end);
#define flush_cache_vmap(start, end) flush_cache_all()
#define flush_cache_vunmap(start, end) flush_cache_all()
-static inline void copy_to_user_page(struct vm_area_struct *vma,
+extern void copy_to_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
- unsigned long len)
-{
- if (cpu_has_dc_aliases)
- flush_cache_page(vma, vaddr, page_to_pfn(page));
- memcpy(dst, src, len);
- __flush_icache_page(vma, page);
-}
+ unsigned long len);
-static inline void copy_from_user_page(struct vm_area_struct *vma,
+extern void copy_from_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
- unsigned long len)
-{
- if (cpu_has_dc_aliases)
- flush_cache_page(vma, vaddr, page_to_pfn(page));
- memcpy(dst, src, len);
-}
+ unsigned long len);
extern void (*flush_cache_sigtramp)(unsigned long addr);
extern void (*flush_icache_all)(void);