Page MenuHomeFreeBSD

powerpc/radix: fix double page offset in mmu_radix_sync_icache()
ClosedPublic

Authored by pkubaj on Mon, Sep 21, 8:58 AM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Oct 13, 3:34 AM
Unknown Object (File)
Tue, Oct 6, 7:11 PM
Unknown Object (File)
Tue, Oct 6, 3:19 PM
Unknown Object (File)
Sun, Oct 4, 4:28 PM
Unknown Object (File)
Sat, Oct 3, 3:35 PM
Unknown Object (File)
Thu, Oct 1, 9:06 PM
Unknown Object (File)
Thu, Oct 1, 4:58 PM
Unknown Object (File)
Thu, Oct 1, 2:23 PM
Subscribers

Details

Summary

mmu_radix_sync_icache() adds the offset of va within its page to the
physical address it gets from mmu_radix_extract_locked(). That address
already includes the offset - the extract routines return the physical
address of the byte, not of the frame - so the offset is counted twice
and __syncicache() is handed frame + 2 * offset.

The hash MMU counterpart, moea64_sync_icache(), has to add the offset
because PVO_PADDR() yields only the frame. Here the addition is wrong.

Fixes: 6f0b2a235a13 ("powerpc/pmap: Add pmap_sync_icache() for radix pmap")

MFC after: 1 week

Test Plan

POWER9 pseries guest (radix MMU, 512 GB RAM), GENERIC64LE built natively
from main at 42c69445ca33, with and without this change.

RAM on that machine ends at 0x8000000000, and so does the direct map.
A small test program maps the last page of RAM (0x7ffffff000) read-only
and executable through /dev/mem, drops privileges and jumps to an
all-zero word that is already present in that page; nothing is written.
The first illegal instruction trap at a given srr0 makes
ppc_instr_emulate() call pmap_sync_icache(curpmap, srr0, 4), and the
retry then ends in SIGILL.

kernelpage offset 0x030page offset 0x808
unfixedSIGILLpanic
fixedSIGILLSIGILL (same for 0x80c and 0x840)

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable