> On 26 May 2026, at 14:50, Sergey Bugaev <[email protected]> wrote: > > But that answers neither of my two questions :)
Sergey, sorry for the runaround. Digging through the source now. MIG's inline vs out-of-line is decided at type-declaration time, not at runtime. In mig/type.c around line 632 (itVarArrayDecl), only the unbounded `array[*]` form sets itIndefinite, which is the flag that allows the switch to out-of-line above ~2048 bytes. `array[*:1024]` keeps a fixed bound so it stays inline regardless of new_state_count. The generated _Xthread_set_state confirms it from the other side, it rejects msgt_inline != TRUE with MIG_BAD_ARGUMENTS and has the +56 offset hardcoded in the size check. So there is no MIG knob to flip this RPC to out-of-line. On the user-page question, my earlier intuition was off. On LP64 copyinmsg in gnumach/ipc/copy_user.c does a plain copyin of the whole user message into a kalloc'd kmsg, so the new_state pointer the stub passes to thread_set_state is into that kmsg, not into the user's pages. Even on the genuine out-of-line path (ipc_kmsg.c around line 1442), vm_map_copyin produces a kernel-side vm_map_copy_t, the kernel never holds a raw user pointer. That moves me away from the kernel-side copy workaround and towards relaxing the struct instead. Replacing __int128 v[32] with int64_t v[64] in aarch64_float_state drops alignof from 16 to 8, which matches what MIG actually delivers (+56 from the message body, 8-aligned), and the direct cast in thread_setstatus becomes well-defined with no workaround needed. Your own db8dacb5 flagged the __int128 portability concern so it feels like a soft landing. No public aarch64 ABI consumer yet, so the break seems acceptable, but happy to hear if either of you sees a reason to prefer the kernel-side copy. Paulo
