Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc: Split user/kernel definitions of struct pt_regs

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.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>

+72 -1
+27
arch/powerpc/include/asm/ptrace.h
··· 26 26 #include <uapi/asm/ptrace.h> 27 27 #include <asm/asm-const.h> 28 28 29 + #ifndef __ASSEMBLY__ 30 + struct pt_regs 31 + { 32 + union { 33 + struct user_pt_regs user_regs; 34 + struct { 35 + unsigned long gpr[32]; 36 + unsigned long nip; 37 + unsigned long msr; 38 + unsigned long orig_gpr3; 39 + unsigned long ctr; 40 + unsigned long link; 41 + unsigned long xer; 42 + unsigned long ccr; 43 + #ifdef CONFIG_PPC64 44 + unsigned long softe; 45 + #else 46 + unsigned long mq; 47 + #endif 48 + unsigned long trap; 49 + unsigned long dar; 50 + unsigned long dsisr; 51 + unsigned long result; 52 + }; 53 + }; 54 + }; 55 + #endif 29 56 30 57 #ifdef __powerpc64__ 31 58
+6 -1
arch/powerpc/include/uapi/asm/ptrace.h
··· 29 29 30 30 #ifndef __ASSEMBLY__ 31 31 32 - struct pt_regs { 32 + #ifdef __KERNEL__ 33 + struct user_pt_regs 34 + #else 35 + struct pt_regs 36 + #endif 37 + { 33 38 unsigned long gpr[32]; 34 39 unsigned long nip; 35 40 unsigned long msr;
+39
arch/powerpc/kernel/ptrace.c
··· 3335 3335 3336 3336 user_enter(); 3337 3337 } 3338 + 3339 + void __init pt_regs_check(void) 3340 + { 3341 + BUILD_BUG_ON(offsetof(struct pt_regs, gpr) != 3342 + offsetof(struct user_pt_regs, gpr)); 3343 + BUILD_BUG_ON(offsetof(struct pt_regs, nip) != 3344 + offsetof(struct user_pt_regs, nip)); 3345 + BUILD_BUG_ON(offsetof(struct pt_regs, msr) != 3346 + offsetof(struct user_pt_regs, msr)); 3347 + BUILD_BUG_ON(offsetof(struct pt_regs, msr) != 3348 + offsetof(struct user_pt_regs, msr)); 3349 + BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) != 3350 + offsetof(struct user_pt_regs, orig_gpr3)); 3351 + BUILD_BUG_ON(offsetof(struct pt_regs, ctr) != 3352 + offsetof(struct user_pt_regs, ctr)); 3353 + BUILD_BUG_ON(offsetof(struct pt_regs, link) != 3354 + offsetof(struct user_pt_regs, link)); 3355 + BUILD_BUG_ON(offsetof(struct pt_regs, xer) != 3356 + offsetof(struct user_pt_regs, xer)); 3357 + BUILD_BUG_ON(offsetof(struct pt_regs, ccr) != 3358 + offsetof(struct user_pt_regs, ccr)); 3359 + #ifdef __powerpc64__ 3360 + BUILD_BUG_ON(offsetof(struct pt_regs, softe) != 3361 + offsetof(struct user_pt_regs, softe)); 3362 + #else 3363 + BUILD_BUG_ON(offsetof(struct pt_regs, mq) != 3364 + offsetof(struct user_pt_regs, mq)); 3365 + #endif 3366 + BUILD_BUG_ON(offsetof(struct pt_regs, trap) != 3367 + offsetof(struct user_pt_regs, trap)); 3368 + BUILD_BUG_ON(offsetof(struct pt_regs, dar) != 3369 + offsetof(struct user_pt_regs, dar)); 3370 + BUILD_BUG_ON(offsetof(struct pt_regs, dsisr) != 3371 + offsetof(struct user_pt_regs, dsisr)); 3372 + BUILD_BUG_ON(offsetof(struct pt_regs, result) != 3373 + offsetof(struct user_pt_regs, result)); 3374 + 3375 + BUILD_BUG_ON(sizeof(struct user_pt_regs) > sizeof(struct pt_regs)); 3376 + }