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

Richard Sandiford richard.sandiford@arm.com
Thu Jun 12 12:53:53 GMT 2025


Adhemerval Zanella Netto <adhemerval.zanella@linaro.org> writes:
> On 11/06/25 12:36, Yury Khrustalev wrote:
>> Hi everyone,
>> 
>> There are several sub-threads, so I'll reply here to provide some summary.
>> 
>> 1. Changes in the kernel address most common scenarios wrt ZA state of SME.
>> 
>> 2. Since clone() is part of API available to userspace via libc wrapper,
>>    it is possible that some corner cases are still not covered, which is why
>>    this Glibc patch series is still useful. Ideally, we also want all libc-s
>>    to be aligned on this so that userspace programs could expect the same
>>    behaviour.
>
> For thread discussion my understanding was that SME status between v5.19 and
> v6.12 is broken due multiple issues (and disabled on stable releases), and
> from 6.12 to 6.16 was marked BROKEN.
>
> And starting from 6.16 there should be no need to no extra care by userland
> to clear ZA state of SME before fork, as indicated by kernel commit
> cde5c32db55740659fca6d56c09b88800d88fd29:
>
>     Ideally we'd require that userspace ensures that a task is in the "ZA
>     off" state (with PSTATE.ZA==0 and TPIDR2_EL0==NULL) prior to issuing a
>     clone syscall, and have the kernel force this state for new threads.
>     Unfortunately, contemporary C libraries do not do this, and simply
>     forcing this state within the implementation of clone would break
>     fork().  
>
> I do not think it would be worth to handle the old broken kernels (v5.19 to
> v6.12) and adding this patch to fix potentially corner cases adds some doubt 
> whether the kernel does have SME in an workable condition; nor it is clear 
> what exactly are the corner cases is trying to prevent.

I think that's putting the burden of proof in the wrong place.

In principle, the lazy save scheme allows any normal ("private-ZA")
function to call __arm_za_disable for any reason.  Calling __arm_za_disable
is a conservatively correct thing to do.  The question then is more:
can we prove that not calling __arm_za_disable is behaviourally
equivalent to calling __arm_za_disable as far as the lazy save
scheme is concerned?

>From a QoI perspective, functions are discouraged from calling
__arm_za_disable if (a) the function could plausibly be used in the
middle of an SME operation, (b) it's easy to prove that not calling
__arm_za_disable is behaviourally equivalent to calling __arm_za_disable,
and (c) the function does not tend to force the kernel to save ZA state.

I think clone fails on at least (a) and (b).  Calling clone in the middle of
an SME operation seems significantly outside the normal expected use of SME.
And clone is a complex syscall with many options, so it's difficult to
prove that not calling __arm_za_disable is behaviourally equivalent to
calling __arm_za_disable.

So IMO, if there's doubt about whether all uses of clone are correct
without __arm_za_disable (or glibc's local equivalent), the choice
should be to call __arm_za_disable.

In particular, it shouldn't be up to code higher up the stack to become
SME aware if they are using the correct libc functions (rather than
trying to use asm to do syscalls directly).

Thanks,
Richard


More information about the Libc-alpha mailing list