Hi Tamar,

On Tue, Jul 15, 2025 at 07:00:02AM +0000, Tamar Christina wrote:
> Hi Yury,
> 
> Thanks for the clear comments!

Thanks goes to Richard!

> > -----Original Message-----
> > From: Yury Khrustalev <yury.khrusta...@arm.com>
> > Sent: Thursday, June 19, 2025 2:40 PM
> > To: gcc-patches@gcc.gnu.org
> > Cc: Richard Sandiford <richard.sandif...@arm.com>; Mark Rutland
> > <mark.rutl...@arm.com>
> > Subject: [PATCH 1/1] aarch64: Adapt unwinder to linux's SME signal behaviour
> > 
> > From: Richard Sandiford <richard.sandif...@arm.com>
> > 
> > SME uses a lazy save system to manage ZA.  The idea is that,
> > if a function with ZA state wants to call a "normal" function,
> > it can leave its state in ZA and instead set up a lazy save buffer.
> > If, unexpectedly, that normal function contains a nested use of ZA,
> > that nested use of ZA must commit the lazy save first.
> > 
> > This lazy save system uses a special system register called TPIDR2_EL0.
> > See:
> > 
> >   https://github.com/ARM-software/abi-
> > aa/blob/main/aapcs64/aapcs64.rst#66the-za-lazy-saving-scheme
> > 
> > for details.
> > 
> > The ABI specifies that, on entry to an exception handler, the following
> > things must be true:
> > 
> > * PSTATE.SM must be 0 (the processor must be in non-streaming mode)
> > 
> > * PSTATE.ZA must be 0 (ZA must be off)
> > 
> > * TPIDR2_EL0 must be 0 (there must be no uncommitted lazy save)
> > 
> > This is normally done by making _Unwind_RaiseException & friends
> > commit any lazy save before they unwind.  This also has the side
> > effect of ensuring that TPIDR2_EL0 is never left pointing to a
> > lazy save buffer that has been unwound.
> > 
> > However, things get more complicated with signals.  If:
> > 
> > (a) a signal is raised while ZA is dormant (that is, while there is an
> >     uncommitted lazy save);
> > 
> > (b) the signal handler throws an exception; and
> > 
> > (c) that exception is caught outside the signal handler
> > 
> > something must ensure that the lazy save from (a) is committed.
> > 
> > This would be simple if the signal handler was entered with ZA and
> > TPIDR2_EL0 intact.  However, for various good reasons that are out
> > of scope here, this is not done.  Instead, Linux now clears both
> > TPIDR2_EL0 and PSTATE.ZA before entering a signal handler, see:
> > 
> >   https://lore.kernel.org/all/20250417190113.3778111-1-
> > mark.rutl...@arm.com/
> > 
> > for details.
> > 
> > Therefore, it is the unwinder that must simulate a commit of the lazy
> > save from (a).  It can do this by reading the previous values of
> > TPIDR2_EL0 and ZA from the sigcontext.
> > 
> > The SME-related sigcontext structures were only added to linux's
> > asm/sigcontext.h relatively recently and we can't rely on GCC being
> > built against such recent kernel header files.  The patch therefore uses
> > defines relevant macros if they are not defined and provide types that
> > comply with ABI layout of the corresponding linux types.
> > 
> > The patch includes some ugly casting in an attempt to support big-endian
> > ILP32, even though SME on big-endian ILP32 linux should never be a thing.
> > We can remove it if we also remove ILP32 support from GCC.
> > 
> 
> ILP32 is currently deprecated and we'll probably try to remove it this year.
> Perhaps a middle ground is to wrap them in __ILP32__ so we know to find
> them when we remove the support?

I could certainly add #if defined (__ILP32__) for the type casting bits, if
you think this is helpful for the future refactoring.

> OK with that change, but give others a day or two to object.
> 
> I assume this is something we'd want to backport?

Yes, we plan to back-port it to GCC 15 and 14 (it's the first version where
SME support was added to).

Thanks,
Yury

Reply via email to