diff options
Diffstat (limited to 'arch/arm/mm')
-rw-r--r-- | arch/arm/mm/fault-armv.c | 4 | ||||
-rw-r--r-- | arch/arm/mm/flush.c | 30 |
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 | ||
29 | static unsigned long shared_pte_mask = L_PTE_MT_BUFFERABLE; | 29 | static 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 | ||
219 | void __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. |