aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/mm/flush.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/mm/flush.c')
-rw-r--r--arch/arm64/mm/flush.c37
1 files changed, 8 insertions, 29 deletions
diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c
index 88611c3a421a..e4193e3adc7f 100644
--- a/arch/arm64/mm/flush.c
+++ b/arch/arm64/mm/flush.c
@@ -70,23 +70,16 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
70#endif 70#endif
71} 71}
72 72
73void __flush_dcache_page(struct page *page)
74{
75 __flush_dcache_area(page_address(page), PAGE_SIZE);
76}
77
78void __sync_icache_dcache(pte_t pte, unsigned long addr) 73void __sync_icache_dcache(pte_t pte, unsigned long addr)
79{ 74{
80 unsigned long pfn; 75 struct page *page = pte_page(pte);
81 struct page *page;
82 76
83 pfn = pte_pfn(pte); 77 /* no flushing needed for anonymous pages */
84 if (!pfn_valid(pfn)) 78 if (!page_mapping(page))
85 return; 79 return;
86 80
87 page = pfn_to_page(pfn);
88 if (!test_and_set_bit(PG_dcache_clean, &page->flags)) { 81 if (!test_and_set_bit(PG_dcache_clean, &page->flags)) {
89 __flush_dcache_page(page); 82 __flush_dcache_area(page_address(page), PAGE_SIZE);
90 __flush_icache_all(); 83 __flush_icache_all();
91 } else if (icache_is_aivivt()) { 84 } else if (icache_is_aivivt()) {
92 __flush_icache_all(); 85 __flush_icache_all();
@@ -94,28 +87,14 @@ void __sync_icache_dcache(pte_t pte, unsigned long addr)
94} 87}
95 88
96/* 89/*
97 * Ensure cache coherency between kernel mapping and userspace mapping of this 90 * This function is called when a page has been modified by the kernel. Mark
98 * page. 91 * it as dirty for later flushing when mapped in user space (if executable,
92 * see __sync_icache_dcache).
99 */ 93 */
100void flush_dcache_page(struct page *page) 94void flush_dcache_page(struct page *page)
101{ 95{
102 struct address_space *mapping; 96 if (test_bit(PG_dcache_clean, &page->flags))
103
104 /*
105 * The zero page is never written to, so never has any dirty cache
106 * lines, and therefore never needs to be flushed.
107 */
108 if (page == ZERO_PAGE(0))
109 return;
110
111 mapping = page_mapping(page);
112 if (mapping && mapping_mapped(mapping)) {
113 __flush_dcache_page(page);
114 __flush_icache_all();
115 set_bit(PG_dcache_clean, &page->flags);
116 } else {
117 clear_bit(PG_dcache_clean, &page->flags); 97 clear_bit(PG_dcache_clean, &page->flags);
118 }
119} 98}
120EXPORT_SYMBOL(flush_dcache_page); 99EXPORT_SYMBOL(flush_dcache_page);
121 100