aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mm/flush.c39
-rw-r--r--include/asm-arm/cacheflush.h10
2 files changed, 49 insertions, 0 deletions
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 628348c9f6c5..9df507d36e0b 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -202,3 +202,42 @@ void flush_dcache_page(struct page *page)
202 } 202 }
203} 203}
204EXPORT_SYMBOL(flush_dcache_page); 204EXPORT_SYMBOL(flush_dcache_page);
205
206/*
207 * Flush an anonymous page so that users of get_user_pages()
208 * can safely access the data. The expected sequence is:
209 *
210 * get_user_pages()
211 * -> flush_anon_page
212 * memcpy() to/from page
213 * if written to page, flush_dcache_page()
214 */
215void __flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr)
216{
217 unsigned long pfn;
218
219 /* VIPT non-aliasing caches need do nothing */
220 if (cache_is_vipt_nonaliasing())
221 return;
222
223 /*
224 * Write back and invalidate userspace mapping.
225 */
226 pfn = page_to_pfn(page);
227 if (cache_is_vivt()) {
228 flush_cache_page(vma, vmaddr, pfn);
229 } else {
230 /*
231 * For aliasing VIPT, we can flush an alias of the
232 * userspace address only.
233 */
234 flush_pfn_alias(pfn, vmaddr);
235 }
236
237 /*
238 * Invalidate kernel mapping. No data should be contained
239 * in this mapping of the page. FIXME: this is overkill
240 * since we actually ask for a write-back and invalidate.
241 */
242 __cpuc_flush_dcache_page(page_address(page));
243}
diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h
index d51049522cd0..5f531ea03059 100644
--- a/include/asm-arm/cacheflush.h
+++ b/include/asm-arm/cacheflush.h
@@ -357,6 +357,16 @@ extern void flush_dcache_page(struct page *);
357 357
358extern void __flush_dcache_page(struct address_space *mapping, struct page *page); 358extern void __flush_dcache_page(struct address_space *mapping, struct page *page);
359 359
360#define ARCH_HAS_FLUSH_ANON_PAGE
361static inline void flush_anon_page(struct vm_area_struct *vma,
362 struct page *page, unsigned long vmaddr)
363{
364 extern void __flush_anon_page(struct vm_area_struct *vma,
365 struct page *, unsigned long);
366 if (PageAnon(page))
367 __flush_anon_page(vma, page, vmaddr);
368}
369
360#define flush_dcache_mmap_lock(mapping) \ 370#define flush_dcache_mmap_lock(mapping) \
361 write_lock_irq(&(mapping)->tree_lock) 371 write_lock_irq(&(mapping)->tree_lock)
362#define flush_dcache_mmap_unlock(mapping) \ 372#define flush_dcache_mmap_unlock(mapping) \