[PATCH v2 0/1] aarch64: clear ZA state of SME before clone and clone3
Richard Sandiford
richard.sandiford@arm.com
Thu Jul 3 09:28:49 GMT 2025
Rich Felker <dalias@libc.org> writes:
> On Wed, Jul 02, 2025 at 11:12:13AM -0400, enh wrote:
>> On Tue, Jul 1, 2025 at 5:35 PM Rich Felker <dalias@libc.org> wrote:
>> >
>> > On Tue, Jul 01, 2025 at 10:44:49AM -0400, Rich Felker wrote:
>> > > On Tue, Jul 01, 2025 at 02:24:58PM +0100, Yury Khrustalev wrote:
>> > > > Hi everyone,
>> > > >
>> > > > ** Rich,
>> > > >
>> > > > On Mon, Jun 30, 2025 at 03:43:27PM -0400, Rich Felker wrote:
>> > > > > On Mon, Jun 30, 2025 at 06:27:44PM +0100, Yury Khrustalev wrote:
>> > > > > ...
>> > > > > > > I have not heard any good reason. This is my position too. Libc must
>> > > > > > > not be required to do anything here, because the user could be using a
>> > > > > > > libc older than the kernel and older than the application that's using
>> > > > > > > the new register file. The kernel which adds support for expanded
>> > > > > > > register file is *always*, *100%* responsible for doing whatever is
>> > > > > > > needed to make the addition of the new register file non-ABI-breaking.
>> > > > > > > And in the case of this stuff, that includes performing the
>> > > > > > > lazy-save-and-clear at *all* fork/clone operations, kernel-side.
>> > > > > >
>> > > > > > There are limits to what kernel can do compared to userspace. In userspace,
>> > > > > > we can call __arm_za_disable() (see section about this function in [1])
>> > > > > > but we can't do this on the kernel side. This function does 3 things:
>> > > > > >
>> > > > > > (a) Save ZA buffer by calling __arm_tpidr2_save() (see [1])
>> > > > > > (b) Set TPIDR2_EL0 to null
>> > > > > > (c) Set PSTATE.ZA to 0
>> > > > > >
>> > > > > > and the kernel can only do the last 2 things (b) and (c) because it never reads
>> > > > > > or writes the ZA save buffer and it never uses the contents of TPIDR2 directly.
>> > > > >
>> > > > > That's a matter of policy choice, not "can't". The kernel absolutely
>> > > > > can do what's in the body of __arm_tpidr2_save, namely loading the
>> > > > > address of the save buffer from TPIDR2_EL0 and dumping the register
>> > > > > file at that location.
>> > > >
>> > > > I think that a mere technical possibility for the kernel to do something is not
>> > > > a valid justification for assigning the responsibility for this to the kernel.
>> > > >
>> > > > I guess we could call it a "policy choice" but there are reasons for this
>> > > > "policy" and we shouldn't consider changing it here.
>> > > >
>> > > > JFYI, a similar situation exists with setjmp() and longjmp() where we ought to deal
>> > > > with the consistency of the ZA save buffer on the userspace side (see [1,2]) and
>> > > > the kernel is not involved here.
>> > > >
>> > > > Working with ZA save buffer from the kernel is incorrect and may corrupt userspace
>> > > > memory and it would also lead to unnecessary coupling of the current version of ABI
>> > > > into the kernel syscall interface. The ABI related to ZA state of SME could be extended
>> > > > in the future, and this won't play well with the kernel having to deal with all the changes.
>> > > >
>> > > > So far I haven't seen any compelling reason not to proceed with this change. I think
>> > > > I and my colleagues have provided enough justification at this point.
>> > > >
>> > > > [1]: https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=a7373e457f0b5953d230f7756627036b1711dcc3
>> > > > [2]: https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=a7f6fd976c17b82dc198290b4ab7087f35855a0e
>> > >
>> > > Are you claiming that the situation I expected to work:
>> > >
>> > > - kernel has added SME support
>> > > - libc version is pre-SME
>> > > - application is using SME
>> > >
>> > > necessarily breaks due to lack of handling in setjmp/longjmp?
>> > >
>> > > If so, this is a very unfortunate breakage mode that's not expected
>> > > and does not follow what I would deem ABI stability policy. But I can
>> > > see why, if true, it would make it largely useless for the kernel to
>> > > try to do the right thing here.
>> > >
>> > > At present I would not suspect we have applications trying to use SME,
>> > > since out hwcap.h does not expose a definition for the bit. But if
>> > > this is the kind of ABI stability we're going to expect for ARM, where
>> > > new hwcaps can break ABI compat unless libc has been updated to be
>> > > aware of them, I think we should add functionality that masks off all
>> > > hwcaps unknown to libc in the startup code, so that applications don't
>> > > see this or similarly breaking things as available in the future
>> > > unless/until there's the necessary support for them in place.
>> >
>> > One more thing: can you clarify if use of SME imposes a reference to
>> > a symbol (__arm_tpidr2_save or otherwise) that's expected to be
>> > provided by libc?
>>
>> no, that comes from compiler-rt for llvm (and presumably libgcc for gcc).
>
> Could that perhaps be fixed? If support by libc is needed for this to
> work safely, it should depend on a symbol in libc.
That was the original plan. The problem is that some distros have a
strong aversion to adding new ABI symbols to glibc outside of a major
release tick. In contrast, the changes to setjmp & longjmp (and clone)
are backportable to existing release series without any change/addition
to the ABI.
So this is a case where technical concerns and commercial concerns
somewhat conflict (or perhaps more accurately, technical concerns around
distro management conflict with technical concerns about failure modes
for new hardware features). The current approach allows more distro
releases to support SME than the more purist approach would.
Thanks,
Richard
More information about the Libc-alpha
mailing list