diff options
Diffstat (limited to 'arch/arm/mm/flush.c')
-rw-r--r-- | arch/arm/mm/flush.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index e0758968e9f8..7fe64b25dc5a 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -94,12 +94,10 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsig #define flush_pfn_alias(pfn,vaddr) do { } while (0) #endif -#ifdef CONFIG_SMP static void flush_ptrace_access_other(void *args) { __flush_icache_all(); } -#endif static void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, @@ -123,11 +121,9 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, if (vma->vm_flags & VM_EXEC) { unsigned long addr = (unsigned long)kaddr; __cpuc_coherent_kern_range(addr, addr + len); -#ifdef CONFIG_SMP if (cache_ops_need_broadcast()) smp_call_function(flush_ptrace_access_other, NULL, 1); -#endif } } @@ -216,6 +212,21 @@ static void __flush_dcache_aliases(struct address_space *mapping, struct page *p flush_dcache_mmap_unlock(mapping); } +#ifdef CONFIG_SMP +void __sync_icache_dcache(pte_t pteval) +{ + unsigned long pfn = pte_pfn(pteval); + + if (pfn_valid(pfn) && pte_present_exec_user(pteval)) { + struct page *page = pfn_to_page(pfn); + + if (!test_and_set_bit(PG_dcache_clean, &page->flags)) + __flush_dcache_page(NULL, page); + __flush_icache_all(); + } +} +#endif + /* * Ensure cache coherency between kernel mapping and userspace mapping * of this page. @@ -248,14 +259,15 @@ void flush_dcache_page(struct page *page) mapping = page_mapping(page); if (!cache_ops_need_broadcast() && - !PageHighMem(page) && mapping && !mapping_mapped(mapping)) - set_bit(PG_dcache_dirty, &page->flags); + mapping && !mapping_mapped(mapping)) + clear_bit(PG_dcache_clean, &page->flags); else { __flush_dcache_page(mapping, page); if (mapping && cache_is_vivt()) __flush_dcache_aliases(mapping, page); else if (mapping) __flush_icache_all(); + set_bit(PG_dcache_clean, &page->flags); } } EXPORT_SYMBOL(flush_dcache_page); |