[PATCH v1 2/4] arm64/signal: Include TPIDR2 in the signal context

Szabolcs Nagy szabolcs.nagy at arm.com
Mon Oct 31 08:05:06 PDT 2022


The 10/28/2022 19:50, Mark Brown wrote:
> Add a new signal frame record for TPIDR2 using the same format as we
> already use for ESR with different magic, a header with the value from the
> register appended as the only data. If SME is supported then this record is
> always included.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>

this looks good from userspace point of view.

originally the magic numbers made some sense, e.g.
esr used 0x45535201 which is ascii encoded "ESR\01",
the new ones seem random. probably does not matter.

Reviewed-by: Szabolcs Nagy <szabolcs.nagy at arm.com>

> ---
>  arch/arm64/include/uapi/asm/sigcontext.h |  8 ++++
>  arch/arm64/kernel/signal.c               | 59 ++++++++++++++++++++++++
>  2 files changed, 67 insertions(+)
> 
> diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h
> index 4aaf31e3bf16..6315e1b8e2c4 100644
> --- a/arch/arm64/include/uapi/asm/sigcontext.h
> +++ b/arch/arm64/include/uapi/asm/sigcontext.h
> @@ -140,6 +140,14 @@ struct sve_context {
>  
>  #define SVE_SIG_FLAG_SM	0x1	/* Context describes streaming mode */
>  
> +/* TPIDR2_EL0 context */
> +#define TPIDR2_MAGIC	0x45a4209c
> +
> +struct tpidr2_context {
> +	struct _aarch64_ctx head;
> +	__u64 tpidr2;
> +};
> +
>  #define ZA_MAGIC	0x54366345
>  
>  struct za_context {
> diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
> index 9ad911f1647c..ac4fb42a9613 100644
> --- a/arch/arm64/kernel/signal.c
> +++ b/arch/arm64/kernel/signal.c
> @@ -56,6 +56,7 @@ struct rt_sigframe_user_layout {
>  	unsigned long fpsimd_offset;
>  	unsigned long esr_offset;
>  	unsigned long sve_offset;
> +	unsigned long tpidr2_offset;
>  	unsigned long za_offset;
>  	unsigned long extra_offset;
>  	unsigned long end_offset;
> @@ -219,6 +220,7 @@ static int restore_fpsimd_context(struct fpsimd_context __user *ctx)
>  struct user_ctxs {
>  	struct fpsimd_context __user *fpsimd;
>  	struct sve_context __user *sve;
> +	struct tpidr2_context __user *tpidr2;
>  	struct za_context __user *za;
>  };
>  
> @@ -358,6 +360,32 @@ extern int preserve_sve_context(void __user *ctx);
>  
>  #ifdef CONFIG_ARM64_SME
>  
> +static int preserve_tpidr2_context(struct tpidr2_context __user *ctx)
> +{
> +	int err = 0;
> +
> +	current->thread.tpidr2_el0 = read_sysreg_s(SYS_TPIDR2_EL0);
> +
> +	__put_user_error(TPIDR2_MAGIC, &ctx->head.magic, err);
> +	__put_user_error(sizeof(*ctx), &ctx->head.size, err);
> +	__put_user_error(current->thread.tpidr2_el0, &ctx->tpidr2, err);
> +
> +	return err;
> +}
> +
> +static int restore_tpidr2_context(struct user_ctxs *user)
> +{
> +	u64 tpidr2_el0;
> +	int err = 0;
> +
> +	/* Magic and size were validated deciding to call this function */
> +	__get_user_error(tpidr2_el0, &user->tpidr2->tpidr2, err);
> +	if (!err)
> +		current->thread.tpidr2_el0 = tpidr2_el0;
> +
> +	return err;
> +}
> +
>  static int preserve_za_context(struct za_context __user *ctx)
>  {
>  	int err = 0;
> @@ -447,6 +475,8 @@ static int restore_za_context(struct user_ctxs *user)
>  #else /* ! CONFIG_ARM64_SME */
>  
>  /* Turn any non-optimised out attempts to use these into a link error: */
> +extern int preserve_tpidr2_context(void __user *ctx);
> +extern int restore_tpidr2_context(struct user_ctxs *user);
>  extern int preserve_za_context(void __user *ctx);
>  extern int restore_za_context(struct user_ctxs *user);
>  
> @@ -465,6 +495,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
>  
>  	user->fpsimd = NULL;
>  	user->sve = NULL;
> +	user->tpidr2 = NULL;
>  	user->za = NULL;
>  
>  	if (!IS_ALIGNED((unsigned long)base, 16))
> @@ -531,6 +562,19 @@ static int parse_user_sigframe(struct user_ctxs *user,
>  			user->sve = (struct sve_context __user *)head;
>  			break;
>  
> +		case TPIDR2_MAGIC:
> +			if (!system_supports_sme())
> +				goto invalid;
> +
> +			if (user->tpidr2)
> +				goto invalid;
> +
> +			if (size != sizeof(*user->tpidr2))
> +				goto invalid;
> +
> +			user->tpidr2 = (struct tpidr2_context __user *)head;
> +			break;
> +
>  		case ZA_MAGIC:
>  			if (!system_supports_sme())
>  				goto invalid;
> @@ -663,6 +707,9 @@ static int restore_sigframe(struct pt_regs *regs,
>  			err = restore_fpsimd_context(user.fpsimd);
>  	}
>  
> +	if (err == 0 && system_supports_sme() && user.tpidr2)
> +		err = restore_tpidr2_context(&user);
> +
>  	if (err == 0 && system_supports_sme() && user.za)
>  		err = restore_za_context(&user);
>  
> @@ -757,6 +804,11 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
>  		else
>  			vl = task_get_sme_vl(current);
>  
> +		err = sigframe_alloc(user, &user->tpidr2_offset,
> +				     sizeof(struct tpidr2_context));
> +		if (err)
> +			return err;
> +
>  		if (thread_za_enabled(&current->thread))
>  			vq = sve_vq_from_vl(vl);
>  
> @@ -814,6 +866,13 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user,
>  		err |= preserve_sve_context(sve_ctx);
>  	}
>  
> +	/* TPIDR2 if supported */
> +	if (system_supports_sme() && err == 0) {
> +		struct tpidr2_context __user *tpidr2_ctx =
> +			apply_user_offset(user, user->tpidr2_offset);
> +		err |= preserve_tpidr2_context(tpidr2_ctx);
> +	}
> +
>  	/* ZA state if present */
>  	if (system_supports_sme() && err == 0 && user->za_offset) {
>  		struct za_context __user *za_ctx =
> -- 
> 2.30.2
> 



More information about the linux-arm-kernel mailing list