From 65c2941e0cdd849f1e51b1f320d60490b9772282 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Mon, 13 Sep 2010 16:19:41 +0100 Subject: [PATCH] --- yaml --- r: 212391 b: refs/heads/master c: c4e259c859538e94007d1f04a488540375189551 h: refs/heads/master i: 212389: 7a73cba80b176e6b7c646a1b6f88313f0967af3f 212387: c0a0c6ae19b335f3638c8a096ec5df69fc419fc3 212383: 1295e13a149db595eae91594969dcc97f4d196a2 v: v3 --- [refs] | 2 +- trunk/arch/arm/mm/flush.c | 23 ++++++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 6284a75b6b80..ca684de54a31 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8925ec4c530094b878e7e28a1fd78e7122afd973 +refs/heads/master: c4e259c859538e94007d1f04a488540375189551 diff --git a/trunk/arch/arm/mm/flush.c b/trunk/arch/arm/mm/flush.c index 2332b774c6b9..391ffae75098 100644 --- a/trunk/arch/arm/mm/flush.c +++ b/trunk/arch/arm/mm/flush.c @@ -40,6 +40,18 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) : "cc"); } +static void flush_icache_alias(unsigned long pfn, unsigned long vaddr, unsigned long len) +{ + unsigned long colour = CACHE_COLOUR(vaddr); + unsigned long offset = vaddr & (PAGE_SIZE - 1); + unsigned long to; + + set_pte_ext(TOP_PTE(ALIAS_FLUSH_START) + colour, pfn_pte(pfn, PAGE_KERNEL), 0); + to = ALIAS_FLUSH_START + (colour << PAGE_SHIFT) + offset; + flush_tlb_kernel_page(to); + flush_icache_range(to, to + len); +} + void flush_cache_mm(struct mm_struct *mm) { if (cache_is_vivt()) { @@ -90,8 +102,10 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsig if (vma->vm_flags & VM_EXEC && icache_is_vivt_asid_tagged()) __flush_icache_all(); } + #else -#define flush_pfn_alias(pfn,vaddr) do { } while (0) +#define flush_pfn_alias(pfn,vaddr) do { } while (0) +#define flush_icache_alias(pfn,vaddr,len) do { } while (0) #endif static void flush_ptrace_access_other(void *args) @@ -117,10 +131,13 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, return; } - /* VIPT non-aliasing cache */ + /* VIPT non-aliasing D-cache */ if (vma->vm_flags & VM_EXEC) { unsigned long addr = (unsigned long)kaddr; - __cpuc_coherent_kern_range(addr, addr + len); + if (icache_is_vipt_aliasing()) + flush_icache_alias(page_to_pfn(page), uaddr, len); + else + __cpuc_coherent_kern_range(addr, addr + len); if (cache_ops_need_broadcast()) smp_call_function(flush_ptrace_access_other, NULL, 1);