> On 26 May 2026, at 12:55, Sergey Bugaev <[email protected]> wrote: > > Jess is right that generally, fixing the underlying cause is better > than adding workarounds. But in this case, thread_set_state is a > generic API that is defined to work on a thread_state_t, which is an > array[*:1024] of natural_t. So MIG cannot be blamed for not aligning > it for int128.
This is the exact reason I cannot use MIG for that, at least not on the current thread_set_state current ABI, natural_t is 1 byte alignment, for 32 bit CPUs it will align to 4 bytes, 64 to 8 and these alignments will apply to pretty much all other types (from int8 to int64) The exception happens with 128 bit types in 64bit architectures that support them which x86_64 and aarch64 do, the alignment required for them is 16 bytes. The issue happens as the alignment in calculation in MIG doesn’t take in consideration an alignment that’s bigger than the architecture default, so in the case of aarch64 and x86_64 it will be 8 bytes not 16. Alignment is not only required within the struct in memory, but the the __int128 themselves must be aligned in the entire device memory. An __int128 location must start within a memory address that’s a multiple of 16. If not they can’t be used in atomic operators and multi threaded behaviour is not guaranteed. To solve this in MI we would need to add support for this type of alignment, I implemented it on my forks https://github.com/paulofduarte/mig/tree/int128 and https://github.com/paulofduarte/gnumach/tree/mach-int128 . But we would also need to use an ABI that has an input using __int128 for it to be align to that. This means creating a new ABI or changing the existing one. First option is horrible, as it’ll make porting existing userspace more complex, second breaks compatibility with all consumers. So both in my opinion should not be done. > What I don't remember is how MIG decides whether to pass data in-line > or out-of-line. Is it dependent on size (i.e. new_state_count)? And if > the data is transferred out-of-line, does the kernel just get a > pointer into the user's page? -- possibly unaligned? It basically traverse the the message type and calculate the alignment for every field and compute the overall alignment. If you are interested, this commit I changed exactly the function that does this calculation on this commit: https://github.com/paulofduarte/mig/commit/1e850060ffc52f15b901176e244d904fbe0e7195 I debated opening a patch for this change, but this will be the first type in MIG and mach that is not supported by i386, and I genuinely cannot think of an use case for it. So I am leaving it for now. > Also pay attention to thread_set_self_state, that too only does > natural_t alignment. And that evidently worked for me, since sigreturn > definitely restores the float registers state (see > sysdeps/mach/hurd/aarch64/sigreturn.c:__sigreturn2). I cannot understand how this worked for you to be honest, it failed for me in every single test. And it usually fails by mangling the data on set and surfacing on get. > I wonder, does your compiler perhaps want a different alignment for > __int128 than mine did? Are you (not) using aarch64-gnu-gcc? It’s possible, but I don’t really understand which flag could that be, I tried every combination I can think and that combined with the swapped fields on the locore.S , I couldn’t get the thread set state to work on the tests, until I fixed the locore.S and the thread set methods by the realignment or stop using __int128 Paulo
