aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm/c-r4k.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2011-06-17 11:20:28 -0400
committerRalf Baechle <ralf@linux-mips.org>2011-10-20 10:00:18 -0400
commitd9cdc901af0f92da7f90c750d8c187f5500be067 (patch)
tree1b5e11202d86081253ab1422e302b45902a346a3 /arch/mips/mm/c-r4k.c
parent2e5db86dd4166fd88a042bbb229dfc7081df3e92 (diff)
MIPS: cache: Provide cache flush operations for XFS
Until now flush_kernel_vmap_range() and invalidate_kernel_vmap_range() did not exist on MIPS resulting in heavy cache corruption on XFS filesystems. Left for the post-3.0 time: optimization and make this work with highmem, too. Since the combination of highmem + cache aliases atm doesn't work this isn't a regression. Signed-off-by: Ralf Baechle <ralf@linux-mips.org> Patchwork: https://patchwork.linux-mips.org/patch/2505/
Diffstat (limited to 'arch/mips/mm/c-r4k.c')
-rw-r--r--arch/mips/mm/c-r4k.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index b9aabb998a32..a79fe9aa7721 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -722,6 +722,39 @@ static void r4k_flush_icache_all(void)
722 r4k_blast_icache(); 722 r4k_blast_icache();
723} 723}
724 724
725struct flush_kernel_vmap_range_args {
726 unsigned long vaddr;
727 int size;
728};
729
730static inline void local_r4k_flush_kernel_vmap_range(void *args)
731{
732 struct flush_kernel_vmap_range_args *vmra = args;
733 unsigned long vaddr = vmra->vaddr;
734 int size = vmra->size;
735
736 /*
737 * Aliases only affect the primary caches so don't bother with
738 * S-caches or T-caches.
739 */
740 if (cpu_has_safe_index_cacheops && size >= dcache_size)
741 r4k_blast_dcache();
742 else {
743 R4600_HIT_CACHEOP_WAR_IMPL;
744 blast_dcache_range(vaddr, vaddr + size);
745 }
746}
747
748static void r4k_flush_kernel_vmap_range(unsigned long vaddr, int size)
749{
750 struct flush_kernel_vmap_range_args args;
751
752 args.vaddr = (unsigned long) vaddr;
753 args.size = size;
754
755 r4k_on_each_cpu(local_r4k_flush_kernel_vmap_range, &args);
756}
757
725static inline void rm7k_erratum31(void) 758static inline void rm7k_erratum31(void)
726{ 759{
727 const unsigned long ic_lsize = 32; 760 const unsigned long ic_lsize = 32;
@@ -1403,6 +1436,8 @@ void __cpuinit r4k_cache_init(void)
1403 flush_cache_page = r4k_flush_cache_page; 1436 flush_cache_page = r4k_flush_cache_page;
1404 flush_cache_range = r4k_flush_cache_range; 1437 flush_cache_range = r4k_flush_cache_range;
1405 1438
1439 __flush_kernel_vmap_range = r4k_flush_kernel_vmap_range;
1440
1406 flush_cache_sigtramp = r4k_flush_cache_sigtramp; 1441 flush_cache_sigtramp = r4k_flush_cache_sigtramp;
1407 flush_icache_all = r4k_flush_icache_all; 1442 flush_icache_all = r4k_flush_icache_all;
1408 local_flush_data_cache_page = local_r4k_flush_data_cache_page; 1443 local_flush_data_cache_page = local_r4k_flush_data_cache_page;