Commit de62893bc0725f8b5f0445250577cd7a10b2d8f8

Authored by Atsushi Nemoto
Committed by Ralf Baechle
1 parent a3c4946db4

[MIPS] local_r4k_flush_cache_page fix

If dcache_size != icache_size or dcache_size != scache_size, or
set-associative cache, icache/scache does not flushed properly.  Make
blast_?cache_page_indexed() masks its index value correctly.  Also,
use physical address for physically indexed pcache/scache.

Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

Showing 5 changed files with 15 additions and 6 deletions Side-by-side Diff

arch/mips/mm/c-r4k.c
... ... @@ -375,6 +375,7 @@
375 375 struct flush_cache_page_args {
376 376 struct vm_area_struct *vma;
377 377 unsigned long addr;
  378 + unsigned long pfn;
378 379 };
379 380  
380 381 static inline void local_r4k_flush_cache_page(void *args)
... ... @@ -382,6 +383,7 @@
382 383 struct flush_cache_page_args *fcp_args = args;
383 384 struct vm_area_struct *vma = fcp_args->vma;
384 385 unsigned long addr = fcp_args->addr;
  386 + unsigned long paddr = fcp_args->pfn << PAGE_SHIFT;
385 387 int exec = vma->vm_flags & VM_EXEC;
386 388 struct mm_struct *mm = vma->vm_mm;
387 389 pgd_t *pgdp;
388 390  
... ... @@ -431,11 +433,12 @@
431 433 * Do indexed flush, too much work to get the (possible) TLB refills
432 434 * to work correctly.
433 435 */
434   - addr = INDEX_BASE + (addr & (dcache_size - 1));
435 436 if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
436   - r4k_blast_dcache_page_indexed(addr);
437   - if (exec && !cpu_icache_snoops_remote_store)
438   - r4k_blast_scache_page_indexed(addr);
  437 + r4k_blast_dcache_page_indexed(cpu_has_pindexed_dcache ?
  438 + paddr : addr);
  439 + if (exec && !cpu_icache_snoops_remote_store) {
  440 + r4k_blast_scache_page_indexed(paddr);
  441 + }
439 442 }
440 443 if (exec) {
441 444 if (cpu_has_vtag_icache) {
... ... @@ -455,6 +458,7 @@
455 458  
456 459 args.vma = vma;
457 460 args.addr = addr;
  461 + args.pfn = pfn;
458 462  
459 463 on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1);
460 464 }
... ... @@ -956,6 +960,7 @@
956 960 switch (c->cputype) {
957 961 case CPU_20KC:
958 962 case CPU_25KF:
  963 + c->dcache.flags |= MIPS_CACHE_PINDEX;
959 964 case CPU_R10000:
960 965 case CPU_R12000:
961 966 case CPU_SB1:
arch/mips/mm/c-tx39.c
... ... @@ -210,7 +210,6 @@
210 210 * Do indexed flush, too much work to get the (possible) TLB refills
211 211 * to work correctly.
212 212 */
213   - page = (KSEG0 + (page & (dcache_size - 1)));
214 213 if (cpu_has_dc_aliases || exec)
215 214 tx39_blast_dcache_page_indexed(page);
216 215 if (exec)
include/asm-mips/cpu-features.h
... ... @@ -96,6 +96,9 @@
96 96 #ifndef cpu_has_ic_fills_f_dc
97 97 #define cpu_has_ic_fills_f_dc (cpu_data[0].icache.flags & MIPS_CACHE_IC_F_DC)
98 98 #endif
  99 +#ifndef cpu_has_pindexed_dcache
  100 +#define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX)
  101 +#endif
99 102  
100 103 /*
101 104 * I-Cache snoops remote store. This only matters on SMP. Some multiprocessors
include/asm-mips/cpu-info.h
... ... @@ -39,6 +39,7 @@
39 39 #define MIPS_CACHE_ALIASES 0x00000004 /* Cache could have aliases */
40 40 #define MIPS_CACHE_IC_F_DC 0x00000008 /* Ic can refill from D-cache */
41 41 #define MIPS_IC_SNOOPS_REMOTE 0x00000010 /* Ic snoops remote stores */
  42 +#define MIPS_CACHE_PINDEX 0x00000020 /* Physically indexed cache */
42 43  
43 44 struct cpuinfo_mips {
44 45 unsigned long udelay_val;
include/asm-mips/r4kcache.h
... ... @@ -257,7 +257,8 @@
257 257 \
258 258 static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \
259 259 { \
260   - unsigned long start = page; \
  260 + unsigned long indexmask = current_cpu_data.desc.waysize - 1; \
  261 + unsigned long start = INDEX_BASE + (page & indexmask); \
261 262 unsigned long end = start + PAGE_SIZE; \
262 263 unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit; \
263 264 unsigned long ws_end = current_cpu_data.desc.ways << \