aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/flush.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/flush.c')
-rw-r--r--arch/arm/mm/flush.c39
1 files changed, 39 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}