aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm')
-rw-r--r--arch/arm/mm/fault-armv.c4
-rw-r--r--arch/arm/mm/flush.c30
2 files changed, 32 insertions, 2 deletions
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 58846cbd0e0b..8440d952ba6d 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -28,6 +28,7 @@
28 28
29static unsigned long shared_pte_mask = L_PTE_MT_BUFFERABLE; 29static unsigned long shared_pte_mask = L_PTE_MT_BUFFERABLE;
30 30
31#if __LINUX_ARM_ARCH__ < 6
31/* 32/*
32 * We take the easy way out of this problem - we make the 33 * We take the easy way out of this problem - we make the
33 * PTE uncacheable. However, we leave the write buffer on. 34 * PTE uncacheable. However, we leave the write buffer on.
@@ -168,10 +169,8 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
168 return; 169 return;
169 170
170 mapping = page_mapping(page); 171 mapping = page_mapping(page);
171#ifndef CONFIG_SMP
172 if (!test_and_set_bit(PG_dcache_clean, &page->flags)) 172 if (!test_and_set_bit(PG_dcache_clean, &page->flags))
173 __flush_dcache_page(mapping, page); 173 __flush_dcache_page(mapping, page);
174#endif
175 if (mapping) { 174 if (mapping) {
176 if (cache_is_vivt()) 175 if (cache_is_vivt())
177 make_coherent(mapping, vma, addr, ptep, pfn); 176 make_coherent(mapping, vma, addr, ptep, pfn);
@@ -179,6 +178,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
179 __flush_icache_all(); 178 __flush_icache_all();
180 } 179 }
181} 180}
181#endif /* __LINUX_ARM_ARCH__ < 6 */
182 182
183/* 183/*
184 * Check whether the write buffer has physical address aliasing 184 * Check whether the write buffer has physical address aliasing
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index b4efce9b7985..dd5b0120b92e 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -215,6 +215,36 @@ static void __flush_dcache_aliases(struct address_space *mapping, struct page *p
215 flush_dcache_mmap_unlock(mapping); 215 flush_dcache_mmap_unlock(mapping);
216} 216}
217 217
218#if __LINUX_ARM_ARCH__ >= 6
219void __sync_icache_dcache(pte_t pteval)
220{
221 unsigned long pfn;
222 struct page *page;
223 struct address_space *mapping;
224
225 if (!pte_present_user(pteval))
226 return;
227 if (cache_is_vipt_nonaliasing() && !pte_exec(pteval))
228 /* only flush non-aliasing VIPT caches for exec mappings */
229 return;
230 pfn = pte_pfn(pteval);
231 if (!pfn_valid(pfn))
232 return;
233
234 page = pfn_to_page(pfn);
235 if (cache_is_vipt_aliasing())
236 mapping = page_mapping(page);
237 else
238 mapping = NULL;
239
240 if (!test_and_set_bit(PG_dcache_clean, &page->flags))
241 __flush_dcache_page(mapping, page);
242 /* pte_exec() already checked above for non-aliasing VIPT cache */
243 if (cache_is_vipt_nonaliasing() || pte_exec(pteval))
244 __flush_icache_all();
245}
246#endif
247
218/* 248/*
219 * Ensure cache coherency between kernel mapping and userspace mapping 249 * Ensure cache coherency between kernel mapping and userspace mapping
220 * of this page. 250 * of this page.