Linux MIPS Architecture development
 help / color / mirror / Atom feed
* [PATCH] local_r4k_flush_cache_page fix
@ 2006-01-31 15:03 Atsushi Nemoto
  2006-02-01  6:31 ` Atsushi Nemoto
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Atsushi Nemoto @ 2006-01-31 15:03 UTC (permalink / raw)
  To: linux-mips; +Cc: ralf

If dcache_size != icache_size or dcache_size != scache_size,
icache/scache does not flushed properly.  Use correct cache size to
calculate index value for scache/icache.

Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>

diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index e51c38c..d70d700 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -376,6 +376,7 @@ static inline void local_r4k_flush_cache
 	struct flush_cache_page_args *fcp_args = args;
 	struct vm_area_struct *vma = fcp_args->vma;
 	unsigned long addr = fcp_args->addr;
+	unsigned long index;
 	int exec = vma->vm_flags & VM_EXEC;
 	struct mm_struct *mm = vma->vm_mm;
 	pgd_t *pgdp;
@@ -425,11 +426,13 @@ static inline void local_r4k_flush_cache
 	 * Do indexed flush, too much work to get the (possible) TLB refills
 	 * to work correctly.
 	 */
-	addr = INDEX_BASE + (addr & (dcache_size - 1));
 	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
-		r4k_blast_dcache_page_indexed(addr);
-		if (exec && !cpu_icache_snoops_remote_store)
-			r4k_blast_scache_page_indexed(addr);
+		index = INDEX_BASE + (addr & (dcache_size - 1));
+		r4k_blast_dcache_page_indexed(index);
+		if (exec && !cpu_icache_snoops_remote_store) {
+			index = INDEX_BASE + (addr & (scache_size - 1));
+			r4k_blast_scache_page_indexed(index);
+		}
 	}
 	if (exec) {
 		if (cpu_has_vtag_icache) {
@@ -437,8 +440,10 @@ static inline void local_r4k_flush_cache
 
 			if (cpu_context(cpu, mm) != 0)
 				drop_mmu_context(mm, cpu);
-		} else
-			r4k_blast_icache_page_indexed(addr);
+		} else {
+			index = INDEX_BASE + (addr & (icache_size - 1));
+			r4k_blast_icache_page_indexed(index);
+		}
 	}
 }
 

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] local_r4k_flush_cache_page fix
  2006-01-31 15:03 [PATCH] local_r4k_flush_cache_page fix Atsushi Nemoto
@ 2006-02-01  6:31 ` Atsushi Nemoto
  2006-02-01 16:37   ` Atsushi Nemoto
  2006-02-03  5:14 ` Atsushi Nemoto
  2006-03-13  9:23 ` Atsushi Nemoto
  2 siblings, 1 reply; 9+ messages in thread
From: Atsushi Nemoto @ 2006-02-01  6:31 UTC (permalink / raw)
  To: linux-mips; +Cc: ralf

>>>>> On Wed, 01 Feb 2006 00:03:56 +0900 (JST), Atsushi Nemoto <anemo@mba.ocn.ne.jp> said:
anemo> If dcache_size != icache_size or dcache_size != scache_size,
anemo> icache/scache does not flushed properly.  Use correct cache
anemo> size to calculate index value for scache/icache.

BTW, I wonder if current code (with or without this patch) works
properly for physically indexed cache.  Though I do not know if there
were physically indexed icache, there are certainly physically indexed
dcache (ex. MIPS 20KC).

For those physically indexed caches, we should use 'pfn' argument
passed to flush_cache_page ?

---
Atsushi Nemoto

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] local_r4k_flush_cache_page fix
  2006-02-01  6:31 ` Atsushi Nemoto
@ 2006-02-01 16:37   ` Atsushi Nemoto
  0 siblings, 0 replies; 9+ messages in thread
From: Atsushi Nemoto @ 2006-02-01 16:37 UTC (permalink / raw)
  To: linux-mips; +Cc: ralf

>>>>> On Wed, 01 Feb 2006 15:31:54 +0900 (JST), Atsushi Nemoto <anemo@mba.ocn.ne.jp> said:

anemo> BTW, I wonder if current code (with or without this patch)
anemo> works properly for physically indexed cache.  Though I do not
anemo> know if there were physically indexed icache, there are
anemo> certainly physically indexed dcache (ex. MIPS 20KC).

anemo> For those physically indexed caches, we should use 'pfn'
anemo> argument passed to flush_cache_page ?

I'm thinking of introducing MIPS_CACHE_PINDEX and 'cpu_has_pindex_dcache'.

I guess secondary cache is also physically indexed.  Is there any
virtually indexed secondary cache ?

---
Atsushi Nemoto

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] local_r4k_flush_cache_page fix
  2006-01-31 15:03 [PATCH] local_r4k_flush_cache_page fix Atsushi Nemoto
  2006-02-01  6:31 ` Atsushi Nemoto
@ 2006-02-03  5:14 ` Atsushi Nemoto
  2006-02-03 14:47   ` Ralf Baechle
  2006-03-13  9:23 ` Atsushi Nemoto
  2 siblings, 1 reply; 9+ messages in thread
From: Atsushi Nemoto @ 2006-02-03  5:14 UTC (permalink / raw)
  To: linux-mips; +Cc: ralf

>>>>> On Wed, 01 Feb 2006 00:03:56 +0900 (JST), Atsushi Nemoto <anemo@mba.ocn.ne.jp> said:
anemo> If dcache_size != icache_size or dcache_size != scache_size,
anemo> icache/scache does not flushed properly.  Use correct cache
anemo> size to calculate index value for scache/icache.

Sorry, this patch was wrong !

We should use mask value based on the waysize (not whole cache size).

And now I think it would be better to do it in __BUILD_BLAST_CACHE().

I'll post a new patch later.

---
Atsushi Nemoto

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] local_r4k_flush_cache_page fix
  2006-02-03  5:14 ` Atsushi Nemoto
@ 2006-02-03 14:47   ` Ralf Baechle
  2006-02-03 16:53     ` Atsushi Nemoto
  0 siblings, 1 reply; 9+ messages in thread
From: Ralf Baechle @ 2006-02-03 14:47 UTC (permalink / raw)
  To: Atsushi Nemoto; +Cc: linux-mips

On Fri, Feb 03, 2006 at 02:14:24PM +0900, Atsushi Nemoto wrote:

> 
> >>>>> On Wed, 01 Feb 2006 00:03:56 +0900 (JST), Atsushi Nemoto <anemo@mba.ocn.ne.jp> said:
> anemo> If dcache_size != icache_size or dcache_size != scache_size,
> anemo> icache/scache does not flushed properly.  Use correct cache
> anemo> size to calculate index value for scache/icache.
> 
> Sorry, this patch was wrong !
> 
> We should use mask value based on the waysize (not whole cache size).
> 
> And now I think it would be better to do it in __BUILD_BLAST_CACHE().
> 
> I'll post a new patch later.

Maciej ran over what seems to be the same issue; I attach his patch below.
Could you check if it resolves your issues?

  Ralf

Date: Tue, 31 Jan 2006 15:38:37 +0000 (GMT)
From: "Maciej W. Rozycki" <macro@mips.com>
To: Ralf Baechle <ralf@mips.com>

Ralf,

 This patch fixes a problem with set-associative caches, where depending 
on the address passed to flush_cache_page() some ways may not indeed be 
invalidated.  This has been observed with a 24KEc and a 64K D-cache.  The 
S-cache part of the fix wasn't tested. ;-)

 As suggested by Nigel, alternatively blast_?cache_page_indexed() 
functions might be changed to mask out way selection bits, in which case 
the Atsushi's fix is the right one (barring magic number removal).

  Maciej

Signed-off-by: Maciej W. Rozycki <macro@mips.com>

patch-mips-2.6.15-rc7-20060109-dc_aliases-4
diff -up --recursive --new-file linux-mips-2.6.15-rc7-20060109.macro/arch/mips/mm/c-r4k.c linux-mips-2.6.15-rc7-20060109/arch/mips/mm/c-r4k.c
--- linux-mips-2.6.15-rc7-20060109.macro/arch/mips/mm/c-r4k.c	Fri Dec  9 06:11:21 2005
+++ linux-mips-2.6.15-rc7-20060109/arch/mips/mm/c-r4k.c	Tue Jan 31 15:27:11 2006
@@ -375,7 +375,7 @@ static inline void local_r4k_flush_cache
 {
 	struct flush_cache_page_args *fcp_args = args;
 	struct vm_area_struct *vma = fcp_args->vma;
-	unsigned long addr = fcp_args->addr;
+	unsigned long addr = fcp_args->addr, iaddr;
 	int exec = vma->vm_flags & VM_EXEC;
 	struct mm_struct *mm = vma->vm_mm;
 	pgd_t *pgdp;
@@ -425,11 +425,15 @@ static inline void local_r4k_flush_cache
 	 * Do indexed flush, too much work to get the (possible) TLB refills
 	 * to work correctly.
 	 */
-	addr = INDEX_BASE + (addr & (dcache_size - 1));
 	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
-		r4k_blast_dcache_page_indexed(addr);
-		if (exec && !cpu_icache_snoops_remote_store)
-			r4k_blast_scache_page_indexed(addr);
+		iaddr = INDEX_BASE +
+			(addr & (current_cpu_data.dcache.waysize - 1));
+		r4k_blast_dcache_page_indexed(iaddr);
+		if (exec && !cpu_icache_snoops_remote_store) {
+			iaddr = INDEX_BASE +
+				(addr & (current_cpu_data.scache.waysize - 1));
+			r4k_blast_scache_page_indexed(iaddr);
+		}
 	}
 	if (exec) {
 		if (cpu_has_vtag_icache) {
@@ -437,8 +441,11 @@ static inline void local_r4k_flush_cache
 
 			if (cpu_context(cpu, mm) != 0)
 				drop_mmu_context(mm, cpu);
-		} else
-			r4k_blast_icache_page_indexed(addr);
+		} else {
+			iaddr = INDEX_BASE +
+				(addr & (current_cpu_data.icache.waysize - 1));
+			r4k_blast_icache_page_indexed(iaddr);
+		}
 	}
 }
 
@@ -1032,7 +1039,8 @@ static void __init probe_pcache(void)
 	case CPU_SB1:
 		break;
 	case CPU_24K:
-		if (!(read_c0_config7() & (1 << 16)))
+	case CPU_34K:
+		if (!(read_c0_config7() & _24K_CONF7_AR))
 	default:
 			if (c->dcache.waysize > PAGE_SIZE)
 				c->dcache.flags |= MIPS_CACHE_ALIASES;
diff -up --recursive --new-file linux-mips-2.6.15-rc7-20060109.macro/include/asm-mips/mipsregs.h linux-mips-2.6.15-rc7-20060109/include/asm-mips/mipsregs.h
--- linux-mips-2.6.15-rc7-20060109.macro/include/asm-mips/mipsregs.h	Thu Dec  8 05:58:58 2005
+++ linux-mips-2.6.15-rc7-20060109/include/asm-mips/mipsregs.h	Fri Jan 27 14:56:22 2006
@@ -533,6 +533,9 @@
 #define MIPS_CONF3_LPA		(_ULCAST_(1) <<  7)
 #define MIPS_CONF3_DSP		(_ULCAST_(1) << 10)
 
+/* Bits specific to the MIPS 24K, etc. CPUs.  */
+#define _24K_CONF7_AR		(_ULCAST_(1) << 16)
+
 /*
  * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
  */

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] local_r4k_flush_cache_page fix
  2006-02-03 14:47   ` Ralf Baechle
@ 2006-02-03 16:53     ` Atsushi Nemoto
  0 siblings, 0 replies; 9+ messages in thread
From: Atsushi Nemoto @ 2006-02-03 16:53 UTC (permalink / raw)
  To: ralf; +Cc: linux-mips

>>>>> On Fri, 3 Feb 2006 14:47:39 +0000, Ralf Baechle <ralf@linux-mips.org> said:

ralf> Maciej ran over what seems to be the same issue; I attach his
ralf> patch below.  Could you check if it resolves your issues?

It looks OK.  But now it can be fixed in one place --
_BUILD_BLAST_CACHE().  I also try to fix for physically indexed caches
(not tested while I do not have such platform...).

Here is a revised one.  Not including Maceij's 34K fix :-)

Description:

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>

diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index e51c38c..69dfd53 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -369,6 +369,7 @@ static void r4k_flush_cache_mm(struct mm
 struct flush_cache_page_args {
 	struct vm_area_struct *vma;
 	unsigned long addr;
+	unsigned long pfn;
 };
 
 static inline void local_r4k_flush_cache_page(void *args)
@@ -376,6 +377,7 @@ static inline void local_r4k_flush_cache
 	struct flush_cache_page_args *fcp_args = args;
 	struct vm_area_struct *vma = fcp_args->vma;
 	unsigned long addr = fcp_args->addr;
+	unsigned long paddr = fcp_args->pfn << PAGE_SHIFT;
 	int exec = vma->vm_flags & VM_EXEC;
 	struct mm_struct *mm = vma->vm_mm;
 	pgd_t *pgdp;
@@ -425,11 +427,12 @@ static inline void local_r4k_flush_cache
 	 * Do indexed flush, too much work to get the (possible) TLB refills
 	 * to work correctly.
 	 */
-	addr = INDEX_BASE + (addr & (dcache_size - 1));
 	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
-		r4k_blast_dcache_page_indexed(addr);
-		if (exec && !cpu_icache_snoops_remote_store)
-			r4k_blast_scache_page_indexed(addr);
+		r4k_blast_dcache_page_indexed(cpu_has_pindexed_dcache ?
+					      paddr : addr);
+		if (exec && !cpu_icache_snoops_remote_store) {
+			r4k_blast_scache_page_indexed(paddr);
+		}
 	}
 	if (exec) {
 		if (cpu_has_vtag_icache) {
@@ -449,6 +452,7 @@ static void r4k_flush_cache_page(struct 
 
 	args.vma = vma;
 	args.addr = addr;
+	args.pfn = pfn;
 
 	on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1);
 }
@@ -1026,6 +1030,7 @@ static void __init probe_pcache(void)
 	switch (c->cputype) {
 	case CPU_20KC:
 	case CPU_25KF:
+		c->dcache.flags |= MIPS_CACHE_PINDEX;
 	case CPU_R10000:
 	case CPU_R12000:
 	case CPU_SB1:
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
index 0a97a94..f74a52d 100644
--- a/arch/mips/mm/c-tx39.c
+++ b/arch/mips/mm/c-tx39.c
@@ -227,7 +227,6 @@ static void tx39_flush_cache_page(struct
 	 * Do indexed flush, too much work to get the (possible) TLB refills
 	 * to work correctly.
 	 */
-	page = (KSEG0 + (page & (dcache_size - 1)));
 	if (cpu_has_dc_aliases || exec)
 		tx39_blast_dcache_page_indexed(page);
 	if (exec)
diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h
index 78c9cc2..3f2b6d9 100644
--- a/include/asm-mips/cpu-features.h
+++ b/include/asm-mips/cpu-features.h
@@ -96,6 +96,9 @@
 #ifndef cpu_has_ic_fills_f_dc
 #define cpu_has_ic_fills_f_dc	(cpu_data[0].icache.flags & MIPS_CACHE_IC_F_DC)
 #endif
+#ifndef cpu_has_pindexed_dcache
+#define cpu_has_pindexed_dcache	(cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX)
+#endif
 
 /*
  * I-Cache snoops remote store.  This only matters on SMP.  Some multiprocessors
diff --git a/include/asm-mips/cpu-info.h b/include/asm-mips/cpu-info.h
index d5cf519..140be1c 100644
--- a/include/asm-mips/cpu-info.h
+++ b/include/asm-mips/cpu-info.h
@@ -39,6 +39,7 @@ struct cache_desc {
 #define MIPS_CACHE_ALIASES	0x00000004	/* Cache could have aliases */
 #define MIPS_CACHE_IC_F_DC	0x00000008	/* Ic can refill from D-cache */
 #define MIPS_IC_SNOOPS_REMOTE	0x00000010	/* Ic snoops remote stores */
+#define MIPS_CACHE_PINDEX	0x00000020	/* Physically indexed cache */
 
 struct cpuinfo_mips {
 	unsigned long		udelay_val;
diff --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h
index cc53196..a108940 100644
--- a/include/asm-mips/r4kcache.h
+++ b/include/asm-mips/r4kcache.h
@@ -273,7 +273,8 @@ static inline void blast_##pfx##cache##l
 									\
 static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \
 {									\
-	unsigned long start = page;					\
+	unsigned long indexmask = current_cpu_data.desc.waysize - 1;	\
+	unsigned long start = INDEX_BASE + (page & indexmask);		\
 	unsigned long end = start + PAGE_SIZE;				\
 	unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit;	\
 	unsigned long ws_end = current_cpu_data.desc.ways <<		\

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] local_r4k_flush_cache_page fix
  2006-01-31 15:03 [PATCH] local_r4k_flush_cache_page fix Atsushi Nemoto
  2006-02-01  6:31 ` Atsushi Nemoto
  2006-02-03  5:14 ` Atsushi Nemoto
@ 2006-03-13  9:23 ` Atsushi Nemoto
  2006-04-14  3:03   ` Geoff Levand
  2 siblings, 1 reply; 9+ messages in thread
From: Atsushi Nemoto @ 2006-03-13  9:23 UTC (permalink / raw)
  To: ralf; +Cc: linux-mips

>>>>> On Wed, 01 Feb 2006 00:03:56 +0900 (JST), Atsushi Nemoto <anemo@mba.ocn.ne.jp> said:
anemo> If dcache_size != icache_size or dcache_size != scache_size,
anemo> icache/scache does not flushed properly.  Use correct cache size to
anemo> calculate index value for scache/icache.

Ping.  I believe current c-r4k.c still broken for CPUs with large
set-assotiative cache or physically indexed cache.  Here is a patch
against current GIT tree.


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>

diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 0668e9b..9572ed4 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -375,6 +375,7 @@ static void r4k_flush_cache_mm(struct mm
 struct flush_cache_page_args {
 	struct vm_area_struct *vma;
 	unsigned long addr;
+	unsigned long pfn;
 };
 
 static inline void local_r4k_flush_cache_page(void *args)
@@ -382,6 +383,7 @@ static inline void local_r4k_flush_cache
 	struct flush_cache_page_args *fcp_args = args;
 	struct vm_area_struct *vma = fcp_args->vma;
 	unsigned long addr = fcp_args->addr;
+	unsigned long paddr = fcp_args->pfn << PAGE_SHIFT;
 	int exec = vma->vm_flags & VM_EXEC;
 	struct mm_struct *mm = vma->vm_mm;
 	pgd_t *pgdp;
@@ -431,11 +433,12 @@ static inline void local_r4k_flush_cache
 	 * Do indexed flush, too much work to get the (possible) TLB refills
 	 * to work correctly.
 	 */
-	addr = INDEX_BASE + (addr & (dcache_size - 1));
 	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
-		r4k_blast_dcache_page_indexed(addr);
-		if (exec && !cpu_icache_snoops_remote_store)
-			r4k_blast_scache_page_indexed(addr);
+		r4k_blast_dcache_page_indexed(cpu_has_pindexed_dcache ?
+					      paddr : addr);
+		if (exec && !cpu_icache_snoops_remote_store) {
+			r4k_blast_scache_page_indexed(paddr);
+		}
 	}
 	if (exec) {
 		if (cpu_has_vtag_icache) {
@@ -455,6 +458,7 @@ static void r4k_flush_cache_page(struct 
 
 	args.vma = vma;
 	args.addr = addr;
+	args.pfn = pfn;
 
 	on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1);
 }
@@ -956,6 +960,7 @@ static void __init probe_pcache(void)
 	switch (c->cputype) {
 	case CPU_20KC:
 	case CPU_25KF:
+		c->dcache.flags |= MIPS_CACHE_PINDEX;
 	case CPU_R10000:
 	case CPU_R12000:
 	case CPU_SB1:
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
index 7c572be..fe232e3 100644
--- a/arch/mips/mm/c-tx39.c
+++ b/arch/mips/mm/c-tx39.c
@@ -210,7 +210,6 @@ static void tx39_flush_cache_page(struct
 	 * Do indexed flush, too much work to get the (possible) TLB refills
 	 * to work correctly.
 	 */
-	page = (KSEG0 + (page & (dcache_size - 1)));
 	if (cpu_has_dc_aliases || exec)
 		tx39_blast_dcache_page_indexed(page);
 	if (exec)
diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h
index 78c9cc2..3f2b6d9 100644
--- a/include/asm-mips/cpu-features.h
+++ b/include/asm-mips/cpu-features.h
@@ -96,6 +96,9 @@
 #ifndef cpu_has_ic_fills_f_dc
 #define cpu_has_ic_fills_f_dc	(cpu_data[0].icache.flags & MIPS_CACHE_IC_F_DC)
 #endif
+#ifndef cpu_has_pindexed_dcache
+#define cpu_has_pindexed_dcache	(cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX)
+#endif
 
 /*
  * I-Cache snoops remote store.  This only matters on SMP.  Some multiprocessors
diff --git a/include/asm-mips/cpu-info.h b/include/asm-mips/cpu-info.h
index d5cf519..140be1c 100644
--- a/include/asm-mips/cpu-info.h
+++ b/include/asm-mips/cpu-info.h
@@ -39,6 +39,7 @@ struct cache_desc {
 #define MIPS_CACHE_ALIASES	0x00000004	/* Cache could have aliases */
 #define MIPS_CACHE_IC_F_DC	0x00000008	/* Ic can refill from D-cache */
 #define MIPS_IC_SNOOPS_REMOTE	0x00000010	/* Ic snoops remote stores */
+#define MIPS_CACHE_PINDEX	0x00000020	/* Physically indexed cache */
 
 struct cpuinfo_mips {
 	unsigned long		udelay_val;
diff --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h
index 9632c27..0bcb79a 100644
--- a/include/asm-mips/r4kcache.h
+++ b/include/asm-mips/r4kcache.h
@@ -257,7 +257,8 @@ static inline void blast_##pfx##cache##l
 									\
 static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \
 {									\
-	unsigned long start = page;					\
+	unsigned long indexmask = current_cpu_data.desc.waysize - 1;	\
+	unsigned long start = INDEX_BASE + (page & indexmask);		\
 	unsigned long end = start + PAGE_SIZE;				\
 	unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit;	\
 	unsigned long ws_end = current_cpu_data.desc.ways <<		\

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] local_r4k_flush_cache_page fix
  2006-03-13  9:23 ` Atsushi Nemoto
@ 2006-04-14  3:03   ` Geoff Levand
  2006-04-14  3:14     ` Atsushi Nemoto
  0 siblings, 1 reply; 9+ messages in thread
From: Geoff Levand @ 2006-04-14  3:03 UTC (permalink / raw)
  To: Atsushi Nemoto; +Cc: ralf, linux-mips

Nemoto-san,

Your changes caused me some problems with linux-2.6.16.1 on tx4937:

/ # ps -A
CPU 0 Unable to handle kernel paging request at virtual address 7fa99400, epc == 80031018, ra == 80030
Oops[#1]:
Cpu 0
$ 0   : 00000000 10008401 7fa99400 7fa99400
$ 4   : 7fa99000 00000004 00000000 7fa9a000
$ 8   : 7fa99400 00000001 00000001 fffffff8
$12   : 00000006 00000000 00000000 2ace3bdc
$16   : 7fa99000 81338de0 00000004 80290000
$20   : 7fa24278 87ea0000 00000000 81338de0
$24   : 00000050 800305ac
$28   : 87e36000 87e37dd8 00000000 800318b0
Hi    : ffffffe0
Lo    : 00000002
epc   : 80031018 tx49_blast_icache32_page_indexed+0x220/0x6c8     Not tainted
ra    : 800318b0 r4k_flush_cache_page+0x22c/0x274
Status: 10008403    KERNEL EXL IE
Cause : 10000008
BadVA : 7fa99400
PrId  : 00002d30
Modules linked in:
Process ps (pid: 23, threadinfo=87e36000, task=8124a468)
Stack : 00000010 87e37e38 87e37e34 87e37ea8 813495f4 7fa99fc4 000013b4 87ea0000
        0000001b 0000001b 7fa99fc4 813b4fc4 800520c4 80051f94 00000000 00000001
        00000001 800a8194 00000000 00000001 87e37e30 87e37e34 81027680 813495f4
        87ea0000 81338e14 0000001b 81338de0 00000000 87ea0000 7fa24278 81157898
        00000000 1010e140 10008bcc 800d1ca0 81157898 8114c2dc 7fa24278 87e37f18
        ...
Call Trace:
 [<800520c4>] access_process_vm+0x1cc/0x200
 [<80051f94>] access_process_vm+0x9c/0x200
 [<800a8194>] __path_lookup_intent_open+0x60/0xc8
 [<800d1ca0>] proc_pid_cmdline+0x6c/0x11c
 [<800d272c>] proc_info_read+0x78/0xd0
 [<8004e4d0>] tasklet_action+0xc8/0x1a4
 [<80090da8>] vfs_read+0xa8/0x1bc
 [<80090d80>] vfs_read+0x80/0x1bc
 [<80091228>] sys_read+0x54/0xa0
 [<8009026c>] do_sys_open+0x11c/0x16c
 [<8002c624>] stack_done+0x20/0x3c


Code: 24880400  0800c427  01001821 <bc400000> bc400020  bc400040  bc400060  bc400080  bc4000a0
Segmentation fault

The revert below seemed to make it work.

-Geoff


Index: 2.6.16.1/arch/mips/mm/c-r4k.c
===================================================================
--- 2.6.16.1.orig/arch/mips/mm/c-r4k.c	2006-03-19 21:53:29.000000000 -0800
+++ 2.6.16.1/arch/mips/mm/c-r4k.c	2006-04-13 19:39:02.000000000 -0700
@@ -383,7 +383,6 @@
 	struct flush_cache_page_args *fcp_args = args;
 	struct vm_area_struct *vma = fcp_args->vma;
 	unsigned long addr = fcp_args->addr;
-	unsigned long paddr = fcp_args->pfn << PAGE_SHIFT;
 	int exec = vma->vm_flags & VM_EXEC;
 	struct mm_struct *mm = vma->vm_mm;
 	pgd_t *pgdp;
@@ -433,11 +432,11 @@
 	 * Do indexed flush, too much work to get the (possible) TLB refills
 	 * to work correctly.
 	 */
+	addr = INDEX_BASE + (addr & (dcache_size - 1));
 	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
-		r4k_blast_dcache_page_indexed(cpu_has_pindexed_dcache ?
-					      paddr : addr);
+ 		r4k_blast_dcache_page_indexed(addr);
 		if (exec && !cpu_icache_snoops_remote_store) {
-			r4k_blast_scache_page_indexed(paddr);
+			r4k_blast_scache_page_indexed(addr);
 		}
 	}
 	if (exec) {

Atsushi Nemoto wrote:
>>>>>> On Wed, 01 Feb 2006 00:03:56 +0900 (JST), Atsushi Nemoto <anemo@mba.ocn.ne.jp> said:
> anemo> If dcache_size != icache_size or dcache_size != scache_size,
> anemo> icache/scache does not flushed properly.  Use correct cache size to
> anemo> calculate index value for scache/icache.
> 
> Ping.  I believe current c-r4k.c still broken for CPUs with large
> set-assotiative cache or physically indexed cache.  Here is a patch
> against current GIT tree.
> 
> 
> 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>
> 
> diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
> index 0668e9b..9572ed4 100644
> --- a/arch/mips/mm/c-r4k.c
> +++ b/arch/mips/mm/c-r4k.c
> @@ -375,6 +375,7 @@ static void r4k_flush_cache_mm(struct mm
>  struct flush_cache_page_args {
>  	struct vm_area_struct *vma;
>  	unsigned long addr;
> +	unsigned long pfn;
>  };
>  
>  static inline void local_r4k_flush_cache_page(void *args)
> @@ -382,6 +383,7 @@ static inline void local_r4k_flush_cache
>  	struct flush_cache_page_args *fcp_args = args;
>  	struct vm_area_struct *vma = fcp_args->vma;
>  	unsigned long addr = fcp_args->addr;
> +	unsigned long paddr = fcp_args->pfn << PAGE_SHIFT;
>  	int exec = vma->vm_flags & VM_EXEC;
>  	struct mm_struct *mm = vma->vm_mm;
>  	pgd_t *pgdp;
> @@ -431,11 +433,12 @@ static inline void local_r4k_flush_cache
>  	 * Do indexed flush, too much work to get the (possible) TLB refills
>  	 * to work correctly.
>  	 */
> -	addr = INDEX_BASE + (addr & (dcache_size - 1));
>  	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
> -		r4k_blast_dcache_page_indexed(addr);
> -		if (exec && !cpu_icache_snoops_remote_store)
> -			r4k_blast_scache_page_indexed(addr);
> +		r4k_blast_dcache_page_indexed(cpu_has_pindexed_dcache ?
> +					      paddr : addr);
> +		if (exec && !cpu_icache_snoops_remote_store) {
> +			r4k_blast_scache_page_indexed(paddr);
> +		}
>  	}
>  	if (exec) {
>  		if (cpu_has_vtag_icache) {
> @@ -455,6 +458,7 @@ static void r4k_flush_cache_page(struct 
>  
>  	args.vma = vma;
>  	args.addr = addr;
> +	args.pfn = pfn;
>  
>  	on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1);
>  }
> @@ -956,6 +960,7 @@ static void __init probe_pcache(void)
>  	switch (c->cputype) {
>  	case CPU_20KC:
>  	case CPU_25KF:
> +		c->dcache.flags |= MIPS_CACHE_PINDEX;
>  	case CPU_R10000:
>  	case CPU_R12000:
>  	case CPU_SB1:
> diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
> index 7c572be..fe232e3 100644
> --- a/arch/mips/mm/c-tx39.c
> +++ b/arch/mips/mm/c-tx39.c
> @@ -210,7 +210,6 @@ static void tx39_flush_cache_page(struct
>  	 * Do indexed flush, too much work to get the (possible) TLB refills
>  	 * to work correctly.
>  	 */
> -	page = (KSEG0 + (page & (dcache_size - 1)));
>  	if (cpu_has_dc_aliases || exec)
>  		tx39_blast_dcache_page_indexed(page);
>  	if (exec)
> diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h
> index 78c9cc2..3f2b6d9 100644
> --- a/include/asm-mips/cpu-features.h
> +++ b/include/asm-mips/cpu-features.h
> @@ -96,6 +96,9 @@
>  #ifndef cpu_has_ic_fills_f_dc
>  #define cpu_has_ic_fills_f_dc	(cpu_data[0].icache.flags & MIPS_CACHE_IC_F_DC)
>  #endif
> +#ifndef cpu_has_pindexed_dcache
> +#define cpu_has_pindexed_dcache	(cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX)
> +#endif
>  
>  /*
>   * I-Cache snoops remote store.  This only matters on SMP.  Some multiprocessors
> diff --git a/include/asm-mips/cpu-info.h b/include/asm-mips/cpu-info.h
> index d5cf519..140be1c 100644
> --- a/include/asm-mips/cpu-info.h
> +++ b/include/asm-mips/cpu-info.h
> @@ -39,6 +39,7 @@ struct cache_desc {
>  #define MIPS_CACHE_ALIASES	0x00000004	/* Cache could have aliases */
>  #define MIPS_CACHE_IC_F_DC	0x00000008	/* Ic can refill from D-cache */
>  #define MIPS_IC_SNOOPS_REMOTE	0x00000010	/* Ic snoops remote stores */
> +#define MIPS_CACHE_PINDEX	0x00000020	/* Physically indexed cache */
>  
>  struct cpuinfo_mips {
>  	unsigned long		udelay_val;
> diff --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h
> index 9632c27..0bcb79a 100644
> --- a/include/asm-mips/r4kcache.h
> +++ b/include/asm-mips/r4kcache.h
> @@ -257,7 +257,8 @@ static inline void blast_##pfx##cache##l
>  									\
>  static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \
>  {									\
> -	unsigned long start = page;					\
> +	unsigned long indexmask = current_cpu_data.desc.waysize - 1;	\
> +	unsigned long start = INDEX_BASE + (page & indexmask);		\
>  	unsigned long end = start + PAGE_SIZE;				\
>  	unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit;	\
>  	unsigned long ws_end = current_cpu_data.desc.ways <<		\
> 
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] local_r4k_flush_cache_page fix
  2006-04-14  3:03   ` Geoff Levand
@ 2006-04-14  3:14     ` Atsushi Nemoto
  0 siblings, 0 replies; 9+ messages in thread
From: Atsushi Nemoto @ 2006-04-14  3:14 UTC (permalink / raw)
  To: geoffrey.levand; +Cc: ralf, linux-mips

On Thu, 13 Apr 2006 20:03:56 -0700, Geoff Levand <geoffrey.levand@am.sony.com> wrote:
> Nemoto-san,
> 
> Your changes caused me some problems with linux-2.6.16.1 on tx4937:

Yes, it's my mistake.  I posted a patch on 4 Apr and the fix is in
linux-mips.org git tree.  (both master and linux-2.6.16-stable
branch).

---
Atsushi Nemoto

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2006-04-14  3:02 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-01-31 15:03 [PATCH] local_r4k_flush_cache_page fix Atsushi Nemoto
2006-02-01  6:31 ` Atsushi Nemoto
2006-02-01 16:37   ` Atsushi Nemoto
2006-02-03  5:14 ` Atsushi Nemoto
2006-02-03 14:47   ` Ralf Baechle
2006-02-03 16:53     ` Atsushi Nemoto
2006-03-13  9:23 ` Atsushi Nemoto
2006-04-14  3:03   ` Geoff Levand
2006-04-14  3:14     ` Atsushi Nemoto

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox