Files
ARMSX2/pcsx2
J1coding 766dd7c45e vtlb: bound the page protection table indexes
A tester's Namco Museum 50th Anniversary crash on an M2 iPad turned out to be
memory corruption rather than anything to do with the software renderer he
thought he was hitting. The store that died was a softmem write through a page
table entry whose high word had gone from 1 to 2. ProtMode_Manual is 2, it is a
u32, and it lives at offset four of an eight byte record, so something had
written a protection mode over the top half of a vtlbdata.pmap pointer.

It comes from the fastmem branch of HandlePageFault. PSM resolves the whole
physical map rather than just main RAM, so a fault on VU memory arrives here
with an offset far past the end of m_PageProtectInfo, which is a fixed 8192
entries. Nothing checked that. The read alone is out of bounds, and when the
aliased value happens to equal ProtMode_Write the handler carries on into
mmap_ClearCpuBlock and writes. The branch twenty lines below has always had the
bound check; this one never did, and now does the same thing.

Nothing real is suppressed by it. Anything PSM resolves outside main RAM is ROM
or VU memory, neither of which is ever under EE write protection, so the right
answer for those faults is the else branch that was already there, handing them
to the backpatcher.

mmap_MarkCountedRamPage had the same unbounded index and a signed int on top of
it, which went negative and indexed backwards whenever the pointer landed below
Main. Clang has been warning about that conversion the whole time. Bounded the
same way as mmap_GetRamPageInfo, and the warning goes with it. No caller reaches
either case today since they all come through mmap_GetRamPageInfo first, so that
half is closing a trap rather than fixing live breakage.

A lot had to line up, which is why it lasted this long. 16K pages mean VU0
memory can never be folded into fastmem so it faults on every touch, the arena
base makes the aliased half read as exactly ProtMode_Write so the guard passes
because of what it is corrupting, and the game has to touch VU0 memory from the
EE and then reprogram the TLB to spread the poisoned entry around. It writes
once and stops, so it leaves nothing behind in the log.
2026-08-01 14:23:46 +02:00
..
2026-07-31 00:18:48 +02:00