From 1976a369cfd78e2f04372c033fa712f28eb5e6f4 Mon Sep 17 00:00:00 2001 From: "George G. Davis" Date: Sat, 2 Sep 2006 18:43:20 +0100 Subject: [PATCH] --- yaml --- r: 33790 b: refs/heads/master c: a188ad2bc7dbfa16ccdcaa8d43ade185b969baff h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/arm/mm/flush.c | 26 ++++++++++++++++++++++++++ trunk/include/asm-arm/cacheflush.h | 18 +++++++++++++++--- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index bdbdba082ee7..35cc73720f5c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 57bcdafcb1e0782e7ae13471d9223c69e3a6cba2 +refs/heads/master: a188ad2bc7dbfa16ccdcaa8d43ade185b969baff diff --git a/trunk/arch/arm/mm/flush.c b/trunk/arch/arm/mm/flush.c index b103e56806bd..d438ce41cdd5 100644 --- a/trunk/arch/arm/mm/flush.c +++ b/trunk/arch/arm/mm/flush.c @@ -87,6 +87,32 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsig if (cache_is_vipt_aliasing()) flush_pfn_alias(pfn, user_addr); } + +void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, + unsigned long uaddr, void *kaddr, + unsigned long len, int write) +{ + if (cache_is_vivt()) { + if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) { + unsigned long addr = (unsigned long)kaddr; + __cpuc_coherent_kern_range(addr, addr + len); + } + return; + } + + if (cache_is_vipt_aliasing()) { + flush_pfn_alias(page_to_pfn(page), uaddr); + return; + } + + /* VIPT non-aliasing cache */ + if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask) && + vma->vm_flags | VM_EXEC) { + unsigned long addr = (unsigned long)kaddr; + /* only flushing the kernel mapping on non-aliasing VIPT */ + __cpuc_coherent_kern_range(addr, addr + len); + } +} #else #define flush_pfn_alias(pfn,vaddr) do { } while (0) #endif diff --git a/trunk/include/asm-arm/cacheflush.h b/trunk/include/asm-arm/cacheflush.h index fe0c744e0266..e4a2569c636c 100644 --- a/trunk/include/asm-arm/cacheflush.h +++ b/trunk/include/asm-arm/cacheflush.h @@ -247,14 +247,12 @@ extern void dmac_flush_range(unsigned long, unsigned long); */ #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ do { \ - flush_cache_page(vma, vaddr, page_to_pfn(page));\ memcpy(dst, src, len); \ - flush_dcache_page(page); \ + flush_ptrace_access(vma, page, vaddr, dst, len, 1);\ } while (0) #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ do { \ - flush_cache_page(vma, vaddr, page_to_pfn(page));\ memcpy(dst, src, len); \ } while (0) @@ -285,10 +283,24 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned l __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags); } } + +static inline void +flush_ptrace_access(struct vm_area_struct *vma, struct page *page, + unsigned long uaddr, void *kaddr, + unsigned long len, int write) +{ + if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) { + unsigned long addr = (unsigned long)kaddr; + __cpuc_coherent_kern_range(addr, addr + len); + } +} #else extern void flush_cache_mm(struct mm_struct *mm); extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn); +extern void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, + unsigned long uaddr, void *kaddr, + unsigned long len, int write); #endif /*