From aa0f79964a0e0caefc43a5002059eda6f1e642d2 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 25 Aug 2006 17:55:31 +0900 Subject: [PATCH] --- yaml --- r: 36015 b: refs/heads/master c: f6502791d780b22fc147150137704a07a05ba361 h: refs/heads/master i: 36013: fd2520a98bce822e6455bcaac3aa3966b5b9dbab 36011: 57a6599e37699c1a1dbfc3eafcc733ab78615e04 36007: 8ca215bcf0e4cc860415b88c90e483327f57e76e 35999: 31dd17c7551c17c9f2e1a332bd578137c9c66e56 v: v3 --- [refs] | 2 +- trunk/arch/mips/mm/c-r4k.c | 4 +-- trunk/arch/mips/mm/c-sb1.c | 56 +++++++++++++++++++++----------------- 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/[refs] b/[refs] index 4aaa8f91d6c1..3fcde85b316e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: a94d702049569401c65b579d0751ce282f962b41 +refs/heads/master: f6502791d780b22fc147150137704a07a05ba361 diff --git a/trunk/arch/mips/mm/c-r4k.c b/trunk/arch/mips/mm/c-r4k.c index 4e1498246343..2d729f6f6348 100644 --- a/trunk/arch/mips/mm/c-r4k.c +++ b/trunk/arch/mips/mm/c-r4k.c @@ -475,7 +475,7 @@ static inline void local_r4k_flush_cache_page(void *args) } } if (exec) { - if (cpu_has_vtag_icache) { + if (cpu_has_vtag_icache && mm == current->active_mm) { int cpu = smp_processor_id(); if (cpu_context(cpu, mm) != 0) @@ -599,7 +599,7 @@ static inline void local_r4k_flush_icache_page(void *args) * We're not sure of the virtual address(es) involved here, so * we have to flush the entire I-cache. */ - if (cpu_has_vtag_icache) { + if (cpu_has_vtag_icache && vma->vm_mm == current->active_mm) { int cpu = smp_processor_id(); if (cpu_context(cpu, vma->vm_mm) != 0) diff --git a/trunk/arch/mips/mm/c-sb1.c b/trunk/arch/mips/mm/c-sb1.c index 4bd9ad8a5e07..16bad7c0a63f 100644 --- a/trunk/arch/mips/mm/c-sb1.c +++ b/trunk/arch/mips/mm/c-sb1.c @@ -154,6 +154,26 @@ static inline void __sb1_flush_icache_all(void) } } +/* + * Invalidate a range of the icache. The addresses are virtual, and + * the cache is virtually indexed and tagged. However, we don't + * necessarily have the right ASID context, so use index ops instead + * of hit ops. + */ +static inline void __sb1_flush_icache_range(unsigned long start, + unsigned long end) +{ + start &= ~(icache_line_size - 1); + end = (end + icache_line_size - 1) & ~(icache_line_size - 1); + + while (start != end) { + cache_set_op(Index_Invalidate_I, start & icache_index_mask); + start += icache_line_size; + } + mispredict(); + sync(); +} + /* * Flush the icache for a given physical page. Need to writeback the * dcache first, then invalidate the icache. If the page isn't @@ -173,8 +193,11 @@ static void local_sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long /* * Bumping the ASID is probably cheaper than the flush ... */ - if (cpu_context(cpu, vma->vm_mm) != 0) - drop_mmu_context(vma->vm_mm, cpu); + if (vma->vm_mm == current->active_mm) { + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); + } else + __sb1_flush_icache_range(addr, addr + PAGE_SIZE); } #ifdef CONFIG_SMP @@ -210,26 +233,6 @@ void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsign __attribute__((alias("local_sb1_flush_cache_page"))); #endif -/* - * Invalidate a range of the icache. The addresses are virtual, and - * the cache is virtually indexed and tagged. However, we don't - * necessarily have the right ASID context, so use index ops instead - * of hit ops. - */ -static inline void __sb1_flush_icache_range(unsigned long start, - unsigned long end) -{ - start &= ~(icache_line_size - 1); - end = (end + icache_line_size - 1) & ~(icache_line_size - 1); - - while (start != end) { - cache_set_op(Index_Invalidate_I, start & icache_index_mask); - start += icache_line_size; - } - mispredict(); - sync(); -} - /* * Invalidate all caches on this CPU @@ -326,9 +329,12 @@ static void local_sb1_flush_icache_page(struct vm_area_struct *vma, * If there's a context, bump the ASID (cheaper than a flush, * since we don't know VAs!) */ - if (cpu_context(cpu, vma->vm_mm) != 0) { - drop_mmu_context(vma->vm_mm, cpu); - } + if (vma->vm_mm == current->active_mm) { + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); + } else + __sb1_flush_icache_range(start, start + PAGE_SIZE); + } #ifdef CONFIG_SMP