Subject: Re: sh4 pmap bug? (Re: port-dreamcast/34243)
To: None <port-sh3@NetBSD.org>
From: Valeriy E. Ushakov <uwe@ptc.spbu.ru>
List: port-sh3
Date: 08/24/2006 03:34:25
On Thu, Aug 24, 2006 at 00:02:33 +0900, Izumi Tsutsui wrote:

> I'm not familiar with SH, but it looks VIPT
> (virtually indexed and physical tagged) cache
> handling problem, which is also annoying on mips.

Yes, that's it.  I wrote a small self-contained testcase to reproduce
this bug that basicly does:

	func[] = { binary code for: mov.l @r4, r0; rts; nop; }

	write(fd, func);
	code = mmap(fd, RX);
	data = mmap(fd, RW);

	if (show how to avoid the bug)
            *(uint32_t*)data = *(uint32_t*)code;
            // breakpoint does that by writing to the code page

	(*code)(data);  // stuck


> Maybe we should check virtual cache index in pmap_pv_enter() and
> allow multiple mappings if VA pages being mapped have the same
> virtual indexes like mips pmap?

My reading of Schimmel's book sections 2.2.5 and 3.3.6 is that for
that to work the cache must use write-allocate so that if we write via
one alias, we cause the line to be loaded into the cache so that
references via the other alias pick up the change.  We run SH4 in
write-through (w/out write-allocate) mode by default, so we cannot use
those less strict aliasing rules or add logic to check that both
aliased mappings are read-only (but I'm not sure if the added
complexity in the TLB miss processing path makes it worthwhile).


> Or mapping the pages uncached?

That would work but that would also hurt performance.


> Or MI VM (or ld.elf_so) should be fixed to avoid such mappings?

Let's see.  The bug we are trying to avoid is when a single
instruction needs both aliases mapped by the TLB.  In SH3 ISA that can
only happen if one reference is the instruction fetch and the other is
the operand of that instruction.  We should be able to detect that
situation when we create a would-be alias and force a copy to avoid
aliasing.  There still will be a corner case of aliases that are
shared writable and executable mappings, but I'm not sure we care
about those in practice :).

A quick and minimal fix (as far as we are concerned with parctical
aspects and not theroretical correctness over all possible situations)
would be to tweak ld.so to force COW for the aliased pages after
mapping the object into memory.


SY, Uwe
-- 
uwe@ptc.spbu.ru                         |       Zu Grunde kommen
http://snark.ptc.spbu.ru/~uwe/          |       Ist zu Grunde gehen