Fixing the R4000 end of page bug
Stephen M. Rumble <stephen.rumble <at> utoronto.ca>
2006-07-27 11:49:53 GMT
Hello all,
I've begun looking into fixing some long-standing problems with revision 2.2
R4000 CPUs on SGI systems and would like any input whatsoever from those more
experienced with MIPS. The most prominent bug in this revision occurs when a
branch or jump exists as the last instruction in a page, the following page
(containing the delay slot instruction) is not mapped, and a few other
conditions (including a data cache miss) are met by the two prior instructions.
The errata sheet doesn't seem terribly clear as to what all of the conditions
are, but identifying a jump or branch in the last slot suffices in finding a
potentially vulnerable instruction sequence. I would start here and attempt to
make the test more specific afterwards so as not to work around unproblematic
pages unnecessarily.
The seemingly obvious fix is to guarantee that the following page is always
mapped in the TLB when the troublesome page also exists there. In looking at the
code, this appears fairly intrusive and also rather complicated. We'd need to go
to pains to swap in the next page when servicing a lookup on a bad page, remove
wired mappings when switching contexts, remove the wired mapping when replacing
a problematic mapped page, deal with consecutive pages that may be problematic,
etc, etc. And even then, theoretically a program could have N consecutive bad
pages and require N wired entries in the TLB. The best solution is to ensure
that a jump never occurs on an end of page boundary thus requiring no kernel
workarounds to be enabled, but the gnu toolchain doesn't appear to support this,
though other, less serious workarounds are now in gcc4.
In trying to consider an alternative solution, I thought of dynamically altering
the troublesome sequence when it is placed into the pmap via pmap_enter() under
the assumption that changing the sequence would avoid the problem entirely. The
instruction immediately preceding the branch or jump could be changed into a
(Continue reading)