[PATCH v2 0/1] aarch64: clear ZA state of SME before clone and clone3

Rich Felker dalias@libc.org
Tue Jul 1 14:44:49 GMT 2025


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.

Rich


More information about the Libc-alpha mailing list