aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-08-04 03:02:43 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-08-04 03:02:43 -0400
commitc0fe478dbb14fd32e71d1383dbe302b54ce94134 (patch)
tree65bf8762df2a02d01a7f1326c67c078a98c51c39 /arch/sh
parentb5eb10ae901fa797c19accb684825f0e36ecbe0f (diff)
sh: Provide __flush_anon_page().
This provides a __flush_anon_page() that handles both the aliasing and non-aliasing cases. This fixes up some crashes with heavy get_user_pages() users. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/include/asm/cacheflush.h14
-rw-r--r--arch/sh/mm/pg-mmu.c17
2 files changed, 31 insertions, 0 deletions
diff --git a/arch/sh/include/asm/cacheflush.h b/arch/sh/include/asm/cacheflush.h
index 4c85d55847cc..5dffbd126e46 100644
--- a/arch/sh/include/asm/cacheflush.h
+++ b/arch/sh/include/asm/cacheflush.h
@@ -1,6 +1,8 @@
1#ifndef __ASM_SH_CACHEFLUSH_H 1#ifndef __ASM_SH_CACHEFLUSH_H
2#define __ASM_SH_CACHEFLUSH_H 2#define __ASM_SH_CACHEFLUSH_H
3 3
4#include <linux/mm.h>
5
4#ifdef __KERNEL__ 6#ifdef __KERNEL__
5 7
6#ifdef CONFIG_CACHE_OFF 8#ifdef CONFIG_CACHE_OFF
@@ -43,6 +45,18 @@ extern void __flush_purge_region(void *start, int size);
43extern void __flush_invalidate_region(void *start, int size); 45extern void __flush_invalidate_region(void *start, int size);
44#endif 46#endif
45 47
48#ifdef CONFIG_MMU
49#define ARCH_HAS_FLUSH_ANON_PAGE
50extern void __flush_anon_page(struct page *page, unsigned long);
51
52static inline void flush_anon_page(struct vm_area_struct *vma,
53 struct page *page, unsigned long vmaddr)
54{
55 if (boot_cpu_data.dcache.n_aliases && PageAnon(page))
56 __flush_anon_page(page, vmaddr);
57}
58#endif
59
46#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE 60#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
47static inline void flush_kernel_dcache_page(struct page *page) 61static inline void flush_kernel_dcache_page(struct page *page)
48{ 62{
diff --git a/arch/sh/mm/pg-mmu.c b/arch/sh/mm/pg-mmu.c
index a9ede7bae520..027c4d83fb8e 100644
--- a/arch/sh/mm/pg-mmu.c
+++ b/arch/sh/mm/pg-mmu.c
@@ -157,3 +157,20 @@ void __update_cache(struct vm_area_struct *vma,
157 } 157 }
158 } 158 }
159} 159}
160
161void __flush_anon_page(struct page *page, unsigned long vmaddr)
162{
163 unsigned long addr = (unsigned long) page_address(page);
164
165 if (pages_do_alias(addr, vmaddr)) {
166 if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
167 !test_bit(PG_dcache_dirty, &page->flags)) {
168 void *kaddr;
169
170 kaddr = kmap_coherent(page, vmaddr);
171 __flush_wback_region((void *)kaddr, PAGE_SIZE);
172 kunmap_coherent();
173 } else
174 __flush_wback_region((void *)addr, PAGE_SIZE);
175 }
176}