Repository navigation
physmem, dart: flush another CPU's TLB on that CPU (port from MakrSas/Inferno) - #57
Merged
Merged
Conversation
…/Inferno) A DART mapping is revoked on whichever thread wrote to the IOMMU. On the t8030 that is seldom the thread of the CPU whose TLB holds the translation: an application core tears down a mapping that the SEP core, or another application core, has been translating through. tcg_iommu_unmap_notify called tlb_flush(notifier->cpu) from that foreign thread. Pyre's tlb_flush_by_mmuidx documents that it must run on the owning CPU (assert_cpu_is_self, compiled out in release builds). It frees and reallocates the tables it resizes while the owner keeps reading them without a lock, so the owner can read freed memory as TLB entries and write guest data wherever those point. Upstream MakrSas saw this as a heap that malloc spun in forever, dirty bitmaps holding ASCII where pointers belonged, and "Bad ram pointer". A flush for another CPU is now queued to that CPU with async_run_on_cpu, the way tcg_commit hands over a changed memory map. The owner is kicked and flushes at its next exit. Until then it can still use the stale translation, which is the same as a few cycles of DART latency. apple_dart_notify_remap also replayed the whole page table for every notifier after each remap. Only a notifier that asked for MAP events gets anything from a replay. TCG registers one notifier per CPU for UNMAP alone, and the UNMAP event just before it already did that notifier's work, so the replay is now skipped for UNMAP-only notifiers. Ported from MakrSas/Inferno commit 80b488f ("tcg: flush another CPU's TLB on that CPU", branch ios), under the same licences as the files it touches. Original author: Makr <ngrom33@gmail.com>. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ported from MakrSas/Inferno
iosbranch, commit 80b488f ("tcg: flush another CPU's TLB on that CPU"), by Makr (GPL/AGPL fork of Inferno, same licences as the files touched). Commit authorship is kept.What it fixes
tcg_iommu_unmap_notify(system/physmem.c) runs on whichever thread wrote to the IOMMU. On t8030 that is usually an application core tearing down a DART mapping that the SEP core (or another app core) has cached in its softmmu TLB. It calledtlb_flush(notifier->cpu)directly from that thread, but Pyre'stlb_flush_by_mmuidxmust run on the owning CPU (assert_cpu_is_self, which is compiled out in release builds). The flush frees or resizes the TLB tables while their owner keeps reading them without a lock, which is a use-after-free. MakrSas saw it as malloc spinning in a corrupted heap, dirty bitmaps full of ASCII, and "Bad ram pointer".async_run_on_cpu, the same waytcg_commithands over a memory-map change. A flush for the calling CPU stays synchronous.apple_dart_notify_remapno longer replays the whole page table for notifiers that only asked for UNMAP events (TCG's per-CPU notifiers). The UNMAP event sent just before the replay already flushed those notifiers, so for them the walk did nothing.Possibly relevant to Scion-Project/scion#89 (SEP panic at
-smp 7). The SEP vCPU translates through DARTs that app cores modify, and more app cores means more concurrent remaps. This is not verified: ChefKissInc#89 was never reproduced on the Mac, and the samesarspanic has also been seen after a hard quit (stale anti-replay state, see #24).No changes in accel/tcg, tcg/ or target/arm.
Testing
Android cross build, run on the Android emulator (
emulator-5554). Tested as one combined build with #58 against masterd9118068e5:tools/restore_bench.py, iOS 14.0 18A5351d restore ramdisk, real SEP ROM and firmware,-smp 4): every run reachedwaiting_hostwith no panic. Timings, from two interleaved batches against master, 11 runs each, all reachingwaiting_host.waiting_host(median)There is no measurable change. The spread in the busy batch is host load on the emulator, not a difference between the builds.
tools/emu_test.py patch-check, 14.8 / 26.6.2 / 27.0.1 research kernels): JSON identical to master's. The only difference from the scratchbaseline.jsonis the "IOMFB: always detect the simulator system type" row, which master kernel_patches: fix ~3% iOS 14.8 boot panic (IOMFB 'bandwidth values not found') #41 added and master shows too.hw/arm/tests/run-a13-tests.py, Android binary on the emulator): 29/29 passed.🤖 Generated with Claude Code