[PATCH 1/3] powerpc: Split user/kernel definitions of struct pt_regs

Madhavan Srinivasan maddy at linux.vnet.ibm.com
Sun Oct 14 17:36:12 AEDT 2018



On Saturday 13 October 2018 04:26 PM, Michael Ellerman wrote:
> We use a shared definition for struct pt_regs in uapi/asm/ptrace.h.
> That means the layout of the structure is ABI, ie. we can't change it.
>
> That would be fine if it was only used to describe the user-visible
> register state of a process, but it's also the struct we use in the
> kernel to describe the registers saved in an interrupt frame.
>
> We'd like more flexibility in the content (and possibly layout) of the
> kernel version of the struct, but currently that's not possible.
>
> So split the definition into a user-visible definition which remains
> unchanged, and a kernel internal one.
>
> At the moment they're still identical, and we check that at build
> time. That's because we have code (in ptrace etc.) that assumes that
> they are the same. We will fix that code in future patches, and then
> we can break the strict symmetry between the two structs.

Nice and awesome. But just trying to understand. What will
*regs will point to in the "struct sigcontext".


>
> Signed-off-by: Michael Ellerman <mpe at ellerman.id.au>
> ---
>   arch/powerpc/include/asm/ptrace.h      | 27 ++++++++++++++++++
>   arch/powerpc/include/uapi/asm/ptrace.h |  7 ++++-
>   arch/powerpc/kernel/ptrace.c           | 39 ++++++++++++++++++++++++++
>   3 files changed, 72 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
> index 447cbd1bee99..3dd15024db93 100644
> --- a/arch/powerpc/include/asm/ptrace.h
> +++ b/arch/powerpc/include/asm/ptrace.h
> @@ -26,6 +26,33 @@
>   #include <uapi/asm/ptrace.h>
>   #include <asm/asm-const.h>
>
> +#ifndef __ASSEMBLY__
> +struct pt_regs
> +{
> +	union {
> +		struct user_pt_regs user_regs;
> +		struct {
> +			unsigned long gpr[32];
> +			unsigned long nip;
> +			unsigned long msr;
> +			unsigned long orig_gpr3;
> +			unsigned long ctr;
> +			unsigned long link;
> +			unsigned long xer;
> +			unsigned long ccr;
> +#ifdef CONFIG_PPC64
> +			unsigned long softe;
> +#else
> +			unsigned long mq;
> +#endif
> +			unsigned long trap;
> +			unsigned long dar;
> +			unsigned long dsisr;
> +			unsigned long result;
> +		};
> +	};
> +};
> +#endif
>
>   #ifdef __powerpc64__
>
> diff --git a/arch/powerpc/include/uapi/asm/ptrace.h b/arch/powerpc/include/uapi/asm/ptrace.h
> index 55c7a131d2ab..f5f1ccc740fc 100644
> --- a/arch/powerpc/include/uapi/asm/ptrace.h
> +++ b/arch/powerpc/include/uapi/asm/ptrace.h
> @@ -29,7 +29,12 @@
>
>   #ifndef __ASSEMBLY__
>
> -struct pt_regs {
> +#ifdef __KERNEL__
> +struct user_pt_regs
> +#else
> +struct pt_regs
> +#endif
> +{
>   	unsigned long gpr[32];
>   	unsigned long nip;
>   	unsigned long msr;
> diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
> index 4e372f54088f..939d7f81bbbe 100644
> --- a/arch/powerpc/kernel/ptrace.c
> +++ b/arch/powerpc/kernel/ptrace.c
> @@ -3335,3 +3335,42 @@ void do_syscall_trace_leave(struct pt_regs *regs)
>
>   	user_enter();
>   }
> +
> +void __init pt_regs_check(void)
> +{
> +	BUILD_BUG_ON(offsetof(struct pt_regs, gpr) !=
> +		     offsetof(struct user_pt_regs, gpr));
> +	BUILD_BUG_ON(offsetof(struct pt_regs, nip) !=
> +		     offsetof(struct user_pt_regs, nip));
> +	BUILD_BUG_ON(offsetof(struct pt_regs, msr) !=
> +		     offsetof(struct user_pt_regs, msr));
> +	BUILD_BUG_ON(offsetof(struct pt_regs, msr) !=
> +		     offsetof(struct user_pt_regs, msr));
> +	BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
> +		     offsetof(struct user_pt_regs, orig_gpr3));
> +	BUILD_BUG_ON(offsetof(struct pt_regs, ctr) !=
> +		     offsetof(struct user_pt_regs, ctr));
> +	BUILD_BUG_ON(offsetof(struct pt_regs, link) !=
> +		     offsetof(struct user_pt_regs, link));
> +	BUILD_BUG_ON(offsetof(struct pt_regs, xer) !=
> +		     offsetof(struct user_pt_regs, xer));
> +	BUILD_BUG_ON(offsetof(struct pt_regs, ccr) !=
> +		     offsetof(struct user_pt_regs, ccr));
> +#ifdef __powerpc64__
> +	BUILD_BUG_ON(offsetof(struct pt_regs, softe) !=
> +		     offsetof(struct user_pt_regs, softe));
> +#else
> +	BUILD_BUG_ON(offsetof(struct pt_regs, mq) !=
> +		     offsetof(struct user_pt_regs, mq));
> +#endif
> +	BUILD_BUG_ON(offsetof(struct pt_regs, trap) !=
> +		     offsetof(struct user_pt_regs, trap));
> +	BUILD_BUG_ON(offsetof(struct pt_regs, dar) !=
> +		     offsetof(struct user_pt_regs, dar));
> +	BUILD_BUG_ON(offsetof(struct pt_regs, dsisr) !=
> +		     offsetof(struct user_pt_regs, dsisr));
> +	BUILD_BUG_ON(offsetof(struct pt_regs, result) !=
> +		     offsetof(struct user_pt_regs, result));
> +
> +	BUILD_BUG_ON(sizeof(struct user_pt_regs) > sizeof(struct pt_regs));
> +}



More information about the Linuxppc-dev mailing list