[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