[PATCH 00/14] arm64: Preparatory FPSIMD/SVE/SME fixes
Mark Rutland
mark.rutland at arm.com
Tue Apr 8 09:46:31 PDT 2025
On Fri, Apr 04, 2025 at 07:06:50PM +0100, Mark Brown wrote:
> On Fri, Apr 04, 2025 at 06:44:21PM +0100, Mark Rutland wrote:
>
> > * The ptrace ABI for SME is written around the assumption that
> > SVE_PT_REGS_FPSIMD and SVE_PT_REGS_SVE are separate bit flags, whereas
> > in reality these are different values (0 and 1 respectively) for
> > bit 0 of the user_sve_header flags.
>
> The documentation definitely doesn't reflect what actually got
> implemented, IIRC the errors are more around returning the header only
> rather than the assumption that they're separate flags but at this point
> it doesn't really matter given that the documentation is clearly wrong.
I think it matters because the kernel code was also written to that
incorrect assumption, and the reason the effective behaviour differs
from the documented behaviour is because the assumption is incorrect.
This means portions of the code are wildly misleading, and this caused
secondary problems such as providing register data when we didn't intend
to, which I assume is what you mean by "the errors are more around
returning the header only".
>From a quick scan, both GDB and LLVM determine whether streaming mode is
active based on whether the NT_ARM_SSVE header indicates
SVE_PT_REGS_SVE. We can make that work, but it doesn't work in all cases
today (see below).
> > I haven't yet worked through all of the implications of this, but
> > AFAICT we can't reliably indicate the value of PSTATE.SM, and
> > userspace cannot reliably save/restore a task's state in all cases.
>
> Userspace should be able to read by looking the SSVE registers, if you
> get SVE format register state back you're in streaming mode. Streaming
> mode state will always be saved in SVE format so a read of streaming SVE
> vector state will come out with the SVE bit set, if we're not in
> streaming mode it won't be set.
Unfortunately, that's not always true today.
While fpsimd_save_user_state() will save streaming mode state into the
FP_STATE_SVE format, other code can manipulate the task into a state
where thread_sm_enabled() is true, but the task's registers are saved in
the FPSIMD format. That combination is broken for a number of reasons,
but you seemed to permit this deliberately in commit:
bbc6172eefdb276b ("arm64/fpsimd: SME no longer requires SVE register state")
... which says:
| Now that we track the type of the stored register state separately
| to what is active in the task, it is valid to have the FPSIMD
| register state stored while in streaming mode.
I will assume that commit message is misleading, and that we do not want
to permit that case. It's possible to get a task into a bad state
regardless of that commit.
We can fix that in a number of ways, but we need to think of the shape
of ABI we actually want, e.g. whether writes to NT_ARM_SSVE with
SVE_PT_REGS_FPSIMD should be rejected outright.
> For writes writing to the SVE register set will disable streaming mode,
> writes to the streaming SVE register set will enable it.
Yep.
Mark.
More information about the linux-arm-kernel
mailing list