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, so the driver stays bound with no firmware loaded, no shared memory, and nothing in dmesg when SEPOS never answers. 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.

Impact

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

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 requires 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.

Steps to reproduce

SEPOS boots once per power cycle and ignores a second MSG_BOOT_TZ0, so unbind followed by bind is the easiest way to reach this state.

  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 behavior

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

Actual behavior

bind succeeds, the driver symlink reappears, and dmesg shows nothing from apple_sep. Evidence that 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 value it reached after the cold bind earlier in the same boot.
  • MSG_BOOT_TZ0_ACK2 never arrives, so load_fw_and_shmem() never runs and fw_mapped stays false.

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

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 and bind are not meant to be supported for a boot-once coprocessor, suppress the bind and unbind attributes so the driver cannot be detached at all.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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