[PATCH v2 12/21] arm64/sme: Implement ZT0 ptrace support
Luis Machado
luis.machado at arm.com
Fri Nov 11 02:31:00 PST 2022
On 11/1/22 14:33, Mark Brown wrote:
> Implement support for a new note type NT_ARM64_ZT providing access to
Should we use NT_AARCH64_ZT instead? This would align with our previous choice of PT_AARCH64_MEMTAG_MTE.
And we have a precedent with PT_AARCH64_ARCHEXT as well.
> ZT0 when implemented. Since ZT0 is a register with constant size this is
> much simpler than for other SME state.
>
> As ZT0 is only accessible when PSTATE.ZA is set writes to ZT0 cause
> PSTATE.ZA to be set, the main alternative would be to return -EBUSY in
> this case but this seemed more constructive. Practical users are also
> going to be working with ZA anyway and have some understanding of the
> state.
>
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
> arch/arm64/kernel/ptrace.c | 54 ++++++++++++++++++++++++++++++++++++++
> include/uapi/linux/elf.h | 1 +
> 2 files changed, 55 insertions(+)
>
> diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
> index 85105375bea5..a508f3a69d9f 100644
> --- a/arch/arm64/kernel/ptrace.c
> +++ b/arch/arm64/kernel/ptrace.c
> @@ -1145,6 +1145,51 @@ static int za_set(struct task_struct *target,
> return ret;
> }
>
> +static int zt_get(struct task_struct *target,
> + const struct user_regset *regset,
> + struct membuf to)
> +{
> + if (!system_supports_sme2())
> + return -EINVAL;
> +
> + /*
> + * If PSTATE.ZA is not set then ZT will be zeroed when it is
> + * enabled so report the current register value as zero.
> + */
> + if (thread_za_enabled(&target->thread))
> + membuf_write(&to, thread_zt_state(&target->thread),
> + ZT_SIG_REG_BYTES);
> + else
> + membuf_zero(&to, ZT_SIG_REG_BYTES);
> +
> + return 0;
> +}
> +
> +static int zt_set(struct task_struct *target,
> + const struct user_regset *regset,
> + unsigned int pos, unsigned int count,
> + const void *kbuf, const void __user *ubuf)
> +{
> + int ret;
> +
> + if (!system_supports_sme2())
> + return -EINVAL;
> +
> + if (!thread_za_enabled(&target->thread)) {
> + sme_alloc(target);
> + if (!target->thread.sme_state)
> + return -ENOMEM;
> + }
> +
> + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> + thread_zt_state(&target->thread),
> + 0, ZT_SIG_REG_BYTES);
> + if (ret == 0)
> + target->thread.svcr |= SVCR_ZA_MASK;
> +
> + return ret;
> +}
> +
> #endif /* CONFIG_ARM64_SME */
>
> #ifdef CONFIG_ARM64_PTR_AUTH
> @@ -1367,6 +1412,7 @@ enum aarch64_regset {
> #ifdef CONFIG_ARM64_SVE
> REGSET_SSVE,
> REGSET_ZA,
> + REGSET_ZT,
> #endif
> #ifdef CONFIG_ARM64_PTR_AUTH
> REGSET_PAC_MASK,
> @@ -1474,6 +1520,14 @@ static const struct user_regset aarch64_regsets[] = {
> .regset_get = za_get,
> .set = za_set,
> },
> + [REGSET_ZT] = { /* SME ZA */
> + .core_note_type = NT_ARM_ZT,
> + .n = 1,
> + .size = ZT_SIG_REG_BYTES,
> + .align = sizeof(u64),
> + .regset_get = zt_get,
> + .set = zt_set,
> + },
> #endif
> #ifdef CONFIG_ARM64_PTR_AUTH
> [REGSET_PAC_MASK] = {
> diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
> index c7b056af9ef0..3a73c853c537 100644
> --- a/include/uapi/linux/elf.h
> +++ b/include/uapi/linux/elf.h
> @@ -434,6 +434,7 @@ typedef struct elf64_shdr {
> #define NT_ARM_PAC_ENABLED_KEYS 0x40a /* arm64 ptr auth enabled keys (prctl()) */
> #define NT_ARM_SSVE 0x40b /* ARM Streaming SVE registers */
> #define NT_ARM_ZA 0x40c /* ARM SME ZA registers */
> +#define NT_ARM_ZT 0x40d /* ARM SME ZT registers */
I guess the above comment means this would also need to be NT_AARCH64_ZT, but historically we've been using NT_ARM_* even for AARCH64.
So I suppose this is OK.
> #define NT_ARC_V2 0x600 /* ARCv2 accumulator/extra registers */
> #define NT_VMCOREDD 0x700 /* Vmcore Device Dump Note */
> #define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers */
More information about the linux-arm-kernel
mailing list