Skip to content

apple_sep: probe() succeeds even when SEPOS never answers the boot handshake #594

Description

@brentkearney

apple_sep's probe() returns success as soon as MSG_BOOT_TZ0 is queued. The rest of the boot sequence — MSG_BOOT_TZ0_ACK2 triggering load_fw_and_shmem(), then MSG_BOOT_IMG4 and its ack — runs asynchronously from the mailbox RX callback with no timeout and no completion check. If SEPOS never replies, the driver stays bound with no firmware loaded, no shared memory, and nothing in dmesg.

The easiest way to hit this is unbind followed by bind. SEPOS boots once per power cycle and ignores a second MSG_BOOT_TZ0, so the rebound driver looks healthy but the SEP is unusable until reboot.

Steps to reproduce

  1. Boot a machine whose sep node is enabled and confirm the driver is bound:

    ls -l /sys/bus/platform/devices/396400000.sep/driver
    
  2. Unbind, then bind again:

    echo 396400000.sep | sudo tee /sys/bus/platform/drivers/apple_sep/unbind
    echo 396400000.sep | sudo tee /sys/bus/platform/drivers/apple_sep/bind
    
  3. Read dmesg and check the mailbox receive interrupt count:

    grep 396408000.mbox-recv /proc/interrupts
    

Expected: either the rebind fails with an error, or the driver reports that the SEP did not complete its boot handshake.

Actual: bind succeeds, the driver symlink reappears, and dmesg shows nothing from apple_sep. SEPOS never replies: with a kprobe on the driver's mailbox RX callback and a control kprobe on apple_mbox_recv_irq, the five seconds after bind recorded 45 mailbox interrupts from other coprocessors and 0 SEP messages. The 396408000.mbox-recv interrupt count stayed at 13, the same value it reached after the cold bind earlier in the same boot. Since MSG_BOOT_TZ0_ACK2 never arrives, load_fw_and_shmem() never runs and fw_mapped stays false.

The first unbind also trips the IOMMU WARNs in #591; they are a separate bug in the unmap path and are fixed by #592. Unbinding the rebound driver is silent, because remove() skips the unmap when fw_mapped is false.

Why it matters

  • A bound driver with no firmware loaded is indistinguishable from a working one without a kprobe on the mailbox callback. Anyone iterating on this driver via unbind/bind gets silent failure.
  • The same code path applies on a cold boot: if SEPOS rejects MSG_BOOT_TZ0 for any reason (bad local-policy-manifest, wrong firmware region), probe() still succeeds and the only symptom is later consumers failing.

Possible fixes

  • Have process_boot_msg() record handshake progress and warn (or fail a completion that probe() waits on with a timeout) when MSG_BOOT_TZ0_ACK2 or MSG_BOOT_IMG4_ACK does not arrive.
  • Alternatively, if unbind/bind is not meant to be supported for a boot-once coprocessor, suppress the bind/unbind attributes so the driver cannot be detached in the first place.

Environment

Machine Apple MacBook Pro (16-inch, 2021), apple,j316s / apple,t6000
Kernel 7.1.6-1-1-ARCH (linux-asahi 7.1.6.asahi1-1), aarch64
Distribution Arch Linux ARM (Omarchy)
Config CONFIG_APPLE_SEP=y

t600x does not enable the sep node, so reproducing here required adding aliases { sep = &sep; } and status = "okay" to t6000-j316s.dtb. The sep node ships enabled on t8103-j293, t8103-j313, t8103-j456, and t8103-j457.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions