Skip to content

iommu/apple-dart: preserve the T8122 common scanout aperture - #316

Merged
scottjones merged 3 commits into
integration/aurorafrom
fix/t8122-scanout-aperture-20261031
Nov 2, 2026
Merged

scottjones merged 3 commits into
integration/aurorafrom
fix/t8122-scanout-aperture-20261031

Conversation

@DjDeveloperr

@DjDeveloperr DjDeveloperr commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

The T8122 external-display gate appends the external scanout DART to the display subsystem. Its default DMA window is 0..0xffffeffff, while the internal display DART uses 0x10000000000..0x10fffffffff. apple_dart_of_xlate() rejects their empty intersection before domain allocation can apply a consumer aperture.

Apply the existing consumer apple,dma-range override during specifier parsing, retaining validation of five-cell specifiers and the override. Give T8122's display subsystem an explicit common aperture matching the inherited internal-display alias. External PIODMA remains a separate consumer with its original low aperture. Document the property and add KUnit cases.

This draft addresses a reproduced DT/code inconsistency. It does not establish the cause of earlier internal-DART faults or demonstrate working external output. The external-DCP firmware-ready gate and m1n1 opt-in are unchanged. The J613 target is currently offline, so no candidate has been deployed or hardware-tested.

Validation:

  • ASAN/UBSAN fixture executing the production parser and of_xlate() reproduces the original rejection, accepts both scanout streams with the common aperture, preserves separate PIODMA, and rejects malformed windows/specifiers. OF and device plumbing are mocked.
  • Affected ARM64 C object compiled with the new KUnit cases included; symbol inspection confirmed both cases. Requested CI passed KUnit, explicitly including apple_dart_test_consumer_window and apple_dart_test_invalid_consumer_window (1,743 passes, 3 expected skips, no failures/errors or kernel splats).
  • DTBs built; J613/J615 audits confirm the shared scanout window, unchanged PIODMA default, disabled external processor, and absence of a fabricated firmware-ready marker.
  • dt-doc-validate and targeted dt-validate pass for both DTBs. Buffered/O_DIRECT artifact hashes match. Checkpatch passes all three commits with zero errors/warnings.
  • The Rust-enabled Asahi-profile build preparation and retry hit a compiler panic in unchanged Rust macro code (HashSet variances_of). The affected-C build bypassed Rust preparation with CONFIG_RUST=n; this is not a successful full kernel build. Toolchain buffered/direct hashes matched at a subsequent audit, so the panic's cause remains unresolved.

The requested CI also completed the full kernel package build and packaged-kernel boot test successfully. The local native-guest Rust panic remains unresolved.

Before marking ready: validate internal display plus external output and lifecycle on hardware with a verified recovery path.

Document the display consumer's optional DMA aperture, which can differ
from the defaults of individual scanout DARTs. Include the T8122 display
subsystem compatible so its shared aperture is checked by this binding.

Assisted-by: OpenAI Codex (gpt-6.1-sol)
Signed-off-by: DjDeveloperr <hey@djdev.me>
Domain allocation already lets a consumer specify apple,dma-range, but
of_xlate intersects the provider defaults before that override is read.
A consumer with a common scanout alias and DARTs with disjoint defaults
therefore fails configuration before its domain can be allocated.

Apply the same consumer aperture while parsing each specifier, retaining
validation of both explicit five-cell windows and the override. Share the
alignment, overflow and alias-width checks. Consumers without an override
keep their existing windows.

Add KUnit cases for the J613 high scanout alias across internal/external
DART defaults, independent low PIODMA, malformed overrides and invalid
five-cell specifiers. An ASAN/UBSAN fixture executing the production parser
and of_xlate reproduces the old rejection and accepts the common window.

Assisted-by: OpenAI Codex (gpt-6.1-sol)
Signed-off-by: DjDeveloperr <hey@djdev.me>
The display gate adds the external display DART to the shared display
subsystem. Its low PIODMA default does not overlap the internal display's
inherited 1 TiB alias, so their defaults cannot be intersected for scanout.

Describe the subsystem's common scanout aperture explicitly, matching the
internal DART. The external PIODMA consumer retains its existing low
aperture and the external processor still requires the firmware-ready
gate. This is a software-validated candidate; hardware external-display
qualification remains pending.

Assisted-by: OpenAI Codex (gpt-6.1-sol)
Signed-off-by: DjDeveloperr <hey@djdev.me>
@DjDeveloperr DjDeveloperr added the ci:build Build, test and boot the kernel for this PR now label Oct 31, 2026
@DjDeveloperr
DjDeveloperr marked this pull request as ready for review November 2, 2026 08:13

@scottjones scottjones left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We tested this on our J613 and it fixes the internal display faults. This is the cause of the internal DART faults, not only an inconsistency.

Without it, with the dcpext opt-in:

  • Every boot logs display-subsystem: non-overlapping DMA windows three times, and the display subsystem never joins an IOMMU group.
  • On boots unlocked by passphrase, the first swap faulted (6 of 7; the seventh never reached a swap) on disp0's DART (NO PTE FOR IOVA at addresses like 0x10008c31500, which look like raw DRAM addresses) and the internal DCP crashed.
  • With a key file, the session came up before the panel. Nothing was ever swapped and the panel stayed black.
  • We have that rejection in all 7 of our saved opt-in boots. The window check isn't in the trees where external display was first tested working (a372a72, and #127's base), which would explain why it worked there.

With it: no rejection, the display subsystem gets its IOMMU group, the panel is fine, and there are 0 DART faults.

Alone, it didn't give an external picture on 14.7 firmware. The mode set succeeded, then every swap_start was refused. That's a separate bug, now #327: on this firmware swap_start's reply is 8 bytes, the classic template expected 24, and it read the 0xff fill as a refusal.

With #327 and a framebuffer-leak fix equivalent to #325 on top, at 3840x2160:

  • 10 minutes of load at about 29 swaps a second, 18,276 submits and 18,276 completions.
  • DPMS cycles and monitor disable and enable clean, and a 20-minute soak with references flat.
  • The lab's device suspend test passed.
  • By hand this morning on the same build: a picture on both screens, replug on both left ports, video, and s2idle with both screens back.

One note on how we tested: lab boots take the device tree from m1n1 on the ESP, so our test kernel added the same apple,dma-range from the display gate. The kernel side here is what we ran. Your device tree change was compiled but not booted.

SEP's own apple,dma-range on this Mac still worked on these boots. We didn't test J615, or the T8140 display subsystem's window, which now goes through the same path.

@chriskearney chriskearney left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 56e6f92. No source blockers.

Applying the consumer aperture before the cross-DART intersection fixes the ordering problem: domain allocation already honored that aperture, but could never be reached after an empty intersection. The extracted validator preserves alignment, overflow and same-IAS-alias checks. A malformed five-cell specifier is still rejected before applying an override; consumers without the property retain their previous behavior, and PIODMA remains a separate consumer with its low window.

The new KUnit cases cover those parser boundaries. CI run 41411534239 passed, including both new cases: 1,744 passed, three skipped. These tests exercise the parser, not the complete of_xlate attachment path. Our review was source/evidence inspection; we did not build or boot a candidate locally.

Scott's retained J613 logs show the common aperture's exact DT bytes, successful IOMMU-group attachment and no NO PTE faults on the fixed test stack. That stack injected the property from the gate because lab boots retained the installed boot.bin; this is evidence for the driver with equivalent input, not a boot of this PR's DTB. All retained fixed boots used automatic unlock. A manual passphrase boot is being coordinated, so I am not claiming the original passphrase-first-swap symptom has been directly retested yet. J615 and T8140 remain unqualified by hardware here.

Non-blocking documentation follow-up: update the stale draft/offline/no-hardware wording in the body, and retain the distinction between the tested kernel-side fix and the compiled DT change. Deployment needs the kernel and updated DTB together; the external-display opt-in remains unchanged.

@chriskearney

chriskearney commented Nov 2, 2026 •

Copy link
Copy Markdown

Follow-up to my review: I inspected the retained files from the requested J613 passphrase-unlock boot, job j1102-222814-eb60, using 7.2.11-la325-ARCH (artifact ead417fa30adbe32ca989bb0d0a8ea5f811b1748513485d9c3ec576b6cf0d2d2, boot f80f86d088db44959cda2279671defdc).

The one-shot cmdline removed the normal keyfile argument and named a missing file. The journal records that failure at 2.99 s, forwarding password requests to Plymouth, and a later unlock attempt at 19.33 s. Scott confirms he entered the passphrase. This adds evidence for the original manual-unlock boot profile, rather than another automatic-unlock run.

The retained check shows the external opt-in enabled, the exact common-aperture bytes, display-subsystem in IOMMU group 9, eDP enabled and DP-2 connected/enabled (the connector advertises 4K modes; that list does not prove the active mode). The kernel log shows appledrm took fb0 before the password prompt, and the external DCP completed a 3840×2160@60 modeset at 25.76 s. It has no non-overlapping-window rejection, NO PTE fault, swap_start rejection or DCP crash. Scott reports a picture on both physical screens. The retained screencaptures show only the internal desktop, so they do not independently establish the external picture. This was a bounded boot check, not another load/soak test.

The new deferred-probe messages appeared at 13.31 s while waiting for unlock. Later in the same boot the keyboard LED driver attached and brightness restore completed; the RTC registered too. OMT’s retained hardware.probe-errors check also records all four deferred devices as subsequently bound. Physical keyboard-backlight function was not tested, and the cause of the timing difference is not established.

The overall job remains tests_failed: boot-health and the targeted check passed, while OMT's sole regression was packages.kernel-updates for the custom kernel. OMT check statuses match the preceding automatic-unlock run using the same artifact. A speakersafetyd “Invalid sample rate” userspace panic and restart also appear in both runs; its cause remains uninvestigated. The job and fresh device readback confirm return to known-good 7.2.11-10-1-ARCH; the retained revert check records boot.bin matching its preflight hash and the opt-in removed. The earlier caveats remain: this is the instrumented superset stack with the gate-injected property, not an exact-head/clean-DTB boot, and it does not extend hardware coverage to other models.

@scottjones
scottjones added this pull request to the merge queue Nov 2, 2026
Merged via the queue into integration/aurora with commit 2a74b27 Nov 2, 2026
40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:build Build, test and boot the kernel for this PR now

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants