MIPS: fix blast_icache32 on loongson2
authorAaro Koskinen <aaro.koskinen@iki.fi>
Wed, 15 Jan 2014 01:56:38 +0000 (17:56 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 15 Jan 2014 07:19:42 +0000 (14:19 +0700)
Commit 14bd8c082016 ("MIPS: Loongson: Get rid of Loongson 2 #ifdefery
all over arch/mips") failed to add Loongson2 specific blast_icache32
functions.  Fix that.

The patch fixes the following crash seen with 3.13-rc1:

  Reserved instruction in kernel code[#1]:
  [...]
  Call Trace:
    blast_icache32_page+0x8/0xb0
    r4k_flush_cache_page+0x19c/0x200
    do_wp_page.isra.97+0x47c/0xe08
    handle_mm_fault+0x938/0x1118
    __do_page_fault+0x140/0x540
    resume_userspace_check+0x0/0x10
  Code: 00200825  64834000  00200825 <bc900000bc900020  bc900040  bc900060  bc900080  bc9000a0

Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Acked-by: John Crispin <blogic@openwrt.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
arch/mips/include/asm/r4kcache.h
arch/mips/mm/c-r4k.c

index 91d20b08246f27304cdf17c28057428bd73af6de..c84caddb8bdedea260acac25a71c0d5a9c59ef19 100644 (file)
@@ -357,8 +357,8 @@ static inline void invalidate_tcache_page(unsigned long addr)
                  "i" (op));
 
 /* build blast_xxx, blast_xxx_page, blast_xxx_page_indexed */
-#define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize) \
-static inline void blast_##pfx##cache##lsize(void)                     \
+#define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize, extra)   \
+static inline void extra##blast_##pfx##cache##lsize(void)              \
 {                                                                      \
        unsigned long start = INDEX_BASE;                               \
        unsigned long end = start + current_cpu_data.desc.waysize;      \
@@ -376,7 +376,7 @@ static inline void blast_##pfx##cache##lsize(void)                  \
        __##pfx##flush_epilogue                                         \
 }                                                                      \
                                                                        \
-static inline void blast_##pfx##cache##lsize##_page(unsigned long page) \
+static inline void extra##blast_##pfx##cache##lsize##_page(unsigned long page) \
 {                                                                      \
        unsigned long start = page;                                     \
        unsigned long end = page + PAGE_SIZE;                           \
@@ -391,7 +391,7 @@ static inline void blast_##pfx##cache##lsize##_page(unsigned long page) \
        __##pfx##flush_epilogue                                         \
 }                                                                      \
                                                                        \
-static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \
+static inline void extra##blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \
 {                                                                      \
        unsigned long indexmask = current_cpu_data.desc.waysize - 1;    \
        unsigned long start = INDEX_BASE + (page & indexmask);          \
@@ -410,23 +410,24 @@ static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page)
        __##pfx##flush_epilogue                                         \
 }
 
-__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16)
-__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16)
-__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16)
-__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32)
-__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32)
-__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32)
-__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64)
-__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64)
-__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64)
-__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128)
-
-__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16)
-__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32)
-__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16)
-__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32)
-__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64)
-__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128)
+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16, )
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16, )
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16, )
+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32, )
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32, )
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I_Loongson2, 32, loongson2_)
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32, )
+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64, )
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64, )
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64, )
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128, )
+
+__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16, )
+__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32, )
+__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16, )
+__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32, )
+__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64, )
+__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128, )
 
 /* build blast_xxx_range, protected_blast_xxx_range */
 #define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot, extra)       \
index 73f02da61bafa12ecb4077da2f2f429eaba422c7..49e572d879e1348234bc1413f2e9f25e593d9318 100644 (file)
@@ -237,6 +237,8 @@ static void r4k_blast_icache_page_setup(void)
                r4k_blast_icache_page = (void *)cache_noop;
        else if (ic_lsize == 16)
                r4k_blast_icache_page = blast_icache16_page;
+       else if (ic_lsize == 32 && current_cpu_type() == CPU_LOONGSON2)
+               r4k_blast_icache_page = loongson2_blast_icache32_page;
        else if (ic_lsize == 32)
                r4k_blast_icache_page = blast_icache32_page;
        else if (ic_lsize == 64)
@@ -261,6 +263,9 @@ static void r4k_blast_icache_page_indexed_setup(void)
                else if (TX49XX_ICACHE_INDEX_INV_WAR)
                        r4k_blast_icache_page_indexed =
                                tx49_blast_icache32_page_indexed;
+               else if (current_cpu_type() == CPU_LOONGSON2)
+                       r4k_blast_icache_page_indexed =
+                               loongson2_blast_icache32_page_indexed;
                else
                        r4k_blast_icache_page_indexed =
                                blast_icache32_page_indexed;
@@ -284,6 +289,8 @@ static void r4k_blast_icache_setup(void)
                        r4k_blast_icache = blast_r4600_v1_icache32;
                else if (TX49XX_ICACHE_INDEX_INV_WAR)
                        r4k_blast_icache = tx49_blast_icache32;
+               else if (current_cpu_type() == CPU_LOONGSON2)
+                       r4k_blast_icache = loongson2_blast_icache32;
                else
                        r4k_blast_icache = blast_icache32;
        } else if (ic_lsize == 64)