Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[pandora-kernel.git] / arch / arm / mm / flush.c
index 330695b..d438ce4 100644 (file)
 static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
 {
        unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
+       const int zero = 0;
 
        set_pte(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL));
        flush_tlb_kernel_page(to);
 
        asm(    "mcrr   p15, 0, %1, %0, c14\n"
-       "       mcrr    p15, 0, %1, %0, c5\n"
+       "       mcr     p15, 0, %2, c7, c10, 4\n"
+       "       mcr     p15, 0, %2, c7, c5, 0\n"
            :
-           : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES)
+           : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero)
            : "cc");
 }
 
@@ -85,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