Subject: current pmap cache problem (Re: Looking for something to do ;))
To: None <port-mips@netbsd.org>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: port-mips
Date: 09/30/2004 01:35:10
(Note I'm not a MIPS guy, so maybe I'm wrong...)

> If it works for you, I will commit the changes -- Nishimura-san may bitch,
> but he hasn't come up with better code;

Well, I guess Nishimura-san's goal is to replace current mips pmap
completely, so it will take loooong time and he won't _patch_
current (broken?) pmap ;-)

I think the "real fix" is not easy, but the problem is simple,
virtual alias, isn't it?

Current pmap_zero_page() and pmap_copy_page() uses KSEG0
but zeroed or copied pages are accessed via KSEG2 later,
so these functions generate a bunch of virtual aliases.
The ugly (but simple) workaround is to flush cache for such KSEG0
pages, but current pmap_zero_page() and pmap_copy_page() do it
only if (MIPS_HAS_R4K_MMU && mips_sdcache_line_size == 0),
which is not correct.

The intention of checking L2cache size there is to check
if virtual alias will be handled by virtual coherency exceptions
(that is supported by R4000/R4400 CPUs with L2 cache)
but R4600/R4700/R5000 don't have any hardware support for VCE
even with L2 cache.

The better (but not the best, of cource ;-p) fix is to prepare
some variable in mips/cache.c which indicates if virtual aliases
will be handled by hardware or not and use it instead of
current mips_sdcache_line_size. The simple check is
"the machine has R4000/R4400 with L2cache or R10000,"
but in the perfect world, maybe we should also check
which CPU has virtual-indexed-physically-tagged cache
and L1 cache size is larger than pagesize.

On the other hand, current VCE handlers flush L2 cache anyway
and cpu_lwp_fork() in mips/vm_machdep.c have to flush cache
to avold virtual alias in kernel stack created by
pmap_zero_page() even on R4000 with L2, so I think
it's better to flush cache the KSEG0 page unconditionally
at least in pmap_zero_page()...

I guess pmap_pv_page_alloc() has the same problem
since it uses KSEG0. mips/mem.c also allows to access
any KVA via KSEG0.
---
Izumi Tsutsui
tsutsui@ceres.dti.ne.jp