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
F172979894: D59870.diff
Tue, Sep 22, 2:50 PM
Unknown Object (File)
Tue, Sep 22, 11:40 AM
Unknown Object (File)
Tue, Sep 22, 10:32 AM
Unknown Object (File)
Tue, Sep 22, 10:30 AM
Unknown Object (File)
Mon, Sep 21, 10:49 PM
Unknown Object (File)
Mon, Sep 21, 7:10 PM
Unknown Object (File)
Mon, Sep 21, 2:07 PM
Unknown Object (File)
Mon, Sep 21, 1:52 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 Skipped
Unit
Tests Skipped
Build Status
Buildable 77131
Build 74014: arc lint + arc unit