From 8ef5089c1baf62db99f0855d49bd2fb9b89be685 Mon Sep 17 00:00:00 2001 From: Leonid Yegoshin Date: Thu, 19 Feb 2015 10:17:44 -0600 Subject: [PATCH] MIPS: Fix I-cache flushing for kmap'd pages. Make the I-cache flush pages while taking into account the address color by using kmap_coherent() when there is I-cache aliasing present. Signed-off-by: Leonid Yegoshin Signed-off-by: Steven J. Hill --- arch/mips/include/asm/cpu-features.h | 3 +++ arch/mips/mm/c-r4k.c | 17 ++++++++++++++--- arch/mips/mm/init.c | 2 -- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index 6c8dd32ad77ec1..8b854a7041a16d 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h @@ -142,6 +142,9 @@ #ifndef cpu_has_vtag_dcache #define cpu_has_vtag_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_VTAG) #endif +#ifndef cpu_has_ic_aliases +#define cpu_has_ic_aliases (cpu_data[0].icache.flags & MIPS_CACHE_ALIASES) +#endif #ifndef cpu_has_dc_aliases #define cpu_has_dc_aliases (cpu_data[0].dcache.flags & MIPS_CACHE_ALIASES) #endif diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index e5baf4b7053cd8..9e823808799a6a 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -552,6 +552,7 @@ static inline void local_r4k_flush_cache_page(void *args) pmd_t *pmdp; pte_t *ptep; void *vaddr; + int noflush = 0; /* * If ownes no valid ASID yet, cannot possibly have gotten @@ -611,6 +612,7 @@ static inline void local_r4k_flush_cache_page(void *args) if (cpu_context(cpu, mm) != 0) drop_mmu_context(mm, cpu); + noflush = 1; } else vaddr ? r4k_blast_icache_page(addr) : r4k_blast_icache_user_page(addr); @@ -622,6 +624,13 @@ static inline void local_r4k_flush_cache_page(void *args) else kunmap_atomic(vaddr); } + + /* If we have I-cache aliasing, then blast it via coherent page. */ + if (exec && cpu_has_ic_aliases && !noflush && !map_coherent) { + vaddr = kmap_coherent(page, addr); + r4k_blast_icache_page((unsigned long)vaddr); + kunmap_coherent(); + } } static void r4k_flush_cache_page(struct vm_area_struct *vma, @@ -1305,10 +1314,12 @@ static void probe_pcache(void) c->icache.ways = 1; } - printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n", - icache_size >> 10, + printk("Primary instruction cache %ldkB, %s, %s, %slinesize %d bytes.\n", + icache_size >> 10, way_string[c->icache.ways], c->icache.flags & MIPS_CACHE_VTAG ? "VIVT" : "VIPT", - way_string[c->icache.ways], c->icache.linesz); + (c->icache.flags & MIPS_CACHE_ALIASES) ? + "I-cache aliases, " : "", + c->icache.linesz); printk("Primary data cache %ldkB, %s, %s, %s, linesize %d bytes\n", dcache_size >> 10, way_string[c->dcache.ways], diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index dd74b1ad762fbf..5efe70f9d29fc1 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -88,8 +88,6 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot) pte_t pte; int tlbidx; - BUG_ON(Page_dcache_dirty(page)); - pagefault_disable(); idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1); idx += in_interrupt() ? FIX_N_COLOURS : 0;