XXNU Source Handbook Offline reading instructions
Part 13 · Chapter 13.17

SPTM, TXM, and Exclaves: security boundaries and entry/exit map

Security index · ARM64 exception levels · VM and pmap

This checkout contains substantial XNU-side integration for SPTM, TXM, and Exclaves. It shows the objects XNU supplies, the calls it makes, the state it preserves, and the checks it performs before accepting results. The production monitor/secure-kernel implementations and parts of their library interfaces are supplied separately. Reading a call site establishes its local contract, not the complete implementation of the destination.

The mechanisms have different responsibilities

Mechanism Responsibility visible from XNU Principal local source
SPTM Bootstrap protection contract; typed physical frames and page tables; validated mapping/retyping interfaces; protected-domain dispatch/resumption arm64/sptm, locore.s
TXM Code-signing and execution-policy operations; signature/profile/trust objects; address-space and executable-region association; protected state shared with XNU code_signing/txm.c, SPTM pmap integration
Exclaves / SK integration Scheduling-context entry, RPC/upcalls, task/resource authorization, secure-memory handoff, shared buffers, and service access to XNU facilities exclaves.c, xnuproxy, resources

These interfaces cooperate. For example, XNU uses SPTM to transfer pages to TXM or SK; TXM associates executable policy with XNU address spaces; an Exclaves upcall can request VM pages or VFS I/O from XNU. The secure RPC protocol, physical frame type, and executable policy object are different kinds of state.

SPTM, TXM, and Exclaves: security boundaries and entry/exit map diagram
SPTM, TXM, and Exclaves: security boundaries and entry/exit map diagram · Open SVG
Mermaid source
flowchart TD
    U[XNU userspace] -->|Mach traps / exec / mapping requests| X[XNU]
    X -->|Typed page and mapping operations| S[SPTM interface]
    X -->|Code-signing selectors and address-space operations| T[TXM interface]
    X -->|Hosted scheduler request and sk_enter| K[Secure kernel interface]
    K -->|RPC reply or upcall request| X
    X -->|Checked upcall dispatch| V[VM / VFS / IOKit / task lifecycle]
    T -.-> A[External protected implementation]
    S -.-> A
    K -.-> E[External secure kernel and Exclaves services]

The dashed edges identify implementation boundaries, not a complete privilege hierarchy or a claim that every service directly calls every monitor.

Detailed reading route

  1. SPTM: bootstrap contract, frame/table types, mapping operations, epochs and result buffers, call hooks, interrupts and lockdown.
  2. TXM: stack/register ABI, return/error handling, shared data and page transfer, signature/trust lifecycle, address-space and executable mapping policy.
  3. Exclaves overview, then execution: the control trap, per-thread context, proxy RPC, hosted scheduler, secure entry, upcalls, waits and resumption.
  4. Exclaves resources and memory: task attachment, resource capabilities, physical ownership and shared mappings.
  5. Exclaves services: storage, sensors, driver callbacks, notifications, always-on work and diagnostics.

Keep the existing exception-entry, exception-return, and pmap lifetime guides open when following these paths down to machine state.

Kernel entry and exit points

“Entry” must identify the domain being entered. A userspace trap enters XNU; a library call exits XNU into a protected domain; an upcall returns service work to XNU; an interrupt temporarily re-enters XNU while a protected call remains active.

Trigger XNU-side path and boundary Completion or return
Initial SPTM bootstrap _start in start_sptm.s; external SPTM_LOAD_DISPATCH_ID / SPTM_DOMAIN_ENTER Assembly continues after fixup-completion call, then enters C bootstrap
SPTM operation during runtime sptm_* API; _sptm_pre_entry_hook protects XNU state _sptm_post_exit_hook; caller examines operation-specific outputs
TXM operation txm_kernel_call → stack acquisition/register setup → txm_enter Stack shared-return parsing, stack release, possible page-donation retry
XNU userspace requests Exclaves work _exclaves_ctl_trap validates operation, authorization and inputs Operation result and, for endpoint calls, IPC-buffer copyout
XNU executes a secure scheduling request exclaves_scheduler_request → exclaves_enter → sk_enter Ringgate status, response decode, host-side response handling
Secure RPC asks XNU to perform work Proxy response reports UPCALL; exclaves_call_upcall_handler dispatches Handler completion populates response; proxy loop resumes secure context
Interrupt during TXM XNU handles interrupt; registered xnu_return_to_gl2 sees txm_thread_stack Tail branch to txm_resume, with stack in x0
Interrupt during Exclaves/SK Dispatcher sees TH_EXCLAVES_EXECUTION after the TXM test Tail branch to sk_resume
Interrupt during SPTM Neither preceding protected-domain indicator matches Tail branch to sptm_resume_from_exception
Protected-domain panic via the SPTM entry point _start recognizes SPTM_CPU_PANIC and branches to panic_from_sptm; the source lists SPTM, TXM, and cL4 callers Fatal XNU panic/reporting path
Exclaves panic service Dedicated context marked TH_EXCLAVES_RESUME_PANIC_THREAD Special scheduler/panic protocol; distinct from ordinary endpoint completion

Sources: SPTM boot, entry/exit hooks, TXM call path, control trap, scheduler request, secure entry, proxy loop, resume selector, SPTM panic entry, Exclaves panic context.

Normal call completion differs from interrupt resumption

At bootstrap XNU registers the address of its protected-domain return dispatcher:

Source: registered XNU return address

	extern void xnu_return_to_gl2(void);
	const sptm_vaddr_t handler_addr = (sptm_vaddr_t) ptrauth_strip((void *)xnu_return_to_gl2, ptrauth_key_function_pointer);
	sptm_register_xnu_exc_return(handler_addr);

The interrupted-domain state remains associated with the current XNU thread. thread->txm_thread_stack identifies active TXM execution. Exclaves keeps an interrupt-safe state word separately from ordinary RPC/upcall state: the former may be read from interrupt context and is modified by the current thread with interrupts disabled. Thread fields and synchronization contract.

xnu_return_to_gl2 tests TXM first, SK second, and otherwise resumes SPTM. It uses tail branches, followed by unreachable loops. These are resume operations for an unfinished protected call; they are not normal C returns to the dispatcher. When the protected call eventually completes normally, the original call continuation performs its own cleanup and result handling. Selector body.

An interrupted saved state's PC can be a re-entry handler rather than the protected instruction that was interrupted. ml_get_backtrace_pc uses saved x14 when its frame-pointer test recognizes a non-XNU stack. The stack-range helper checks bootstrap-supplied SPTM/TXM ranges; it is not a universal recognizer of every possible secure stack. A backtrace PC, an exception-return PC, and the C caller's continuation can therefore differ without describing three separate user requests. Backtrace interpretation.

Exception levels, guarded execution, and configuration

The SPTM assembly explicitly describes its initial transition as a trap to GL2. The entry macro is externally defined. This tree does not justify replacing that terminology with a guessed hvc instruction or a complete “XNU EL1 → monitor EL2” register sequence. Guest hypercalls, architectural exception levels, and Apple's guarded-domain interfaces have separate visible evidence; the existing exception-level guide distinguishes them.

Similarly, sk_enter, txm_enter and the three resume routines establish named library boundaries, but their bodies are not supplied here. The local C code shows arguments, thread state and results. It does not expose every privileged register save, secure page-table switch, capability check, or exception vector inside those destinations.

Build selection is part of the contract. files.arm64 chooses SPTM-specific bootstrap/pmap files. MakeInc.def derives enablement from platform/device configuration, links sptm_xnu and TrustedExecutionMonitor_Kernel, and separately enables Exclaves configuration. Exclaves generated transport also depends on available SDK modules. Not every source branch appears in the same kernel binary. Architecture files, build selection and archives, Tightbeam generation.

How to assess the security claims in these guides

The source supports concrete distinctions:

The detailed pages identify the specific code establishing each distinction. They also identify absent headers/layouts, external implementation, configuration branches and stale comments where the executable bodies establish a different sequence. No monitor, kernel, hardware protection test or secure service was executed for this documentation.

Search the handbook

Search every chapter, interface and code excerpt.

    Diagram

    Source preview

    Open full file