Skip to content

Commit

Permalink
powerpc: Split user/kernel definitions of struct pt_regs
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
mpe committed Oct 14, 2018
1 parent 7f995d3 commit 002af93
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 1 deletion.
27 changes: 27 additions & 0 deletions arch/powerpc/include/asm/ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__

Expand Down
7 changes: 6 additions & 1 deletion arch/powerpc/include/uapi/asm/ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
39 changes: 39 additions & 0 deletions arch/powerpc/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

0 comments on commit 002af93

Please sign in to comment.