Quoting Oleg Nesterov <o...@redhat.com>:

The commit a8a4b03ab95f ("powerpc: Hard wire PT_SOFTE value to 1 in
ptrace & signals") changed ptrace_get_reg(PT_SOFTE) to report 0x1,
but PTRACE_GETREGS still copies pt_regs->softe as is.

This is not consistent and this breaks the user-regs-peekpoke test
from https://sourceware.org/systemtap/wiki/utrace/tests/

Reported-by: Jan Kratochvil <jan.kratoch...@redhat.com>
Signed-off-by: Oleg Nesterov <o...@redhat.com>
---
 arch/powerpc/kernel/ptrace/ptrace-tm.c   | 8 +++++++-
 arch/powerpc/kernel/ptrace/ptrace-view.c | 8 +++++++-
 2 files changed, 14 insertions(+), 2 deletions(-)


I think the following should work, and not require the first patch (compile tested only).

diff --git a/arch/powerpc/kernel/ptrace/ptrace-tm.c b/arch/powerpc/kernel/ptrace/ptrace-tm.c
index 54f2d076206f..f779b3bc0279 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-tm.c
+++ b/arch/powerpc/kernel/ptrace/ptrace-tm.c
@@ -104,8 +104,14 @@ int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset,
                     offsetof(struct pt_regs, msr) + sizeof(long));

        membuf_write(&to, &target->thread.ckpt_regs.orig_gpr3,
-                       sizeof(struct user_pt_regs) -
-                       offsetof(struct pt_regs, orig_gpr3));
+ offsetof(struct pt_regs, softe) - offsetof(struct pt_regs, orig_gpr3));
+       membuf_store(&to, 1UL);
+
+       BUILD_BUG_ON(offsetof(struct pt_regs, trap) !=
+                    offsetof(struct pt_regs, softe) + sizeof(long));
+
+       membuf_write(&to, &target->thread.ckpt_regs.trap,
+                    sizeof(struct user_pt_regs) - offsetof(struct pt_regs, 
trap));
        return membuf_zero(&to, ELF_NGREG * sizeof(unsigned long) -
                        sizeof(struct user_pt_regs));
 }
diff --git a/arch/powerpc/kernel/ptrace/ptrace-view.c b/arch/powerpc/kernel/ptrace/ptrace-view.c
index 7e6478e7ed07..736bfbf33890 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-view.c
+++ b/arch/powerpc/kernel/ptrace/ptrace-view.c
@@ -234,9 +234,21 @@ static int gpr_get(struct task_struct *target, const struct user_regset *regset,
        BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
                     offsetof(struct pt_regs, msr) + sizeof(long));

+#ifdef CONFIG_PPC64
+       membuf_write(&to, &target->thread.regs->orig_gpr3,
+ offsetof(struct pt_regs, softe) - offsetof(struct pt_regs, orig_gpr3));
+       membuf_store(&to, 1UL);
+
+       BUILD_BUG_ON(offsetof(struct pt_regs, trap) !=
+                    offsetof(struct pt_regs, softe) + sizeof(long));
+
+       membuf_write(&to, &target->thread.regs->trap,
+                    sizeof(struct user_pt_regs) - offsetof(struct pt_regs, 
trap));
+#else
        membuf_write(&to, &target->thread.regs->orig_gpr3,
                        sizeof(struct user_pt_regs) -
                        offsetof(struct pt_regs, orig_gpr3));
+#endif
        return membuf_zero(&to, ELF_NGREG * sizeof(unsigned long) -
                                 sizeof(struct user_pt_regs));
 }
---
Christophe

Reply via email to