Currently ptrace doesn't flush the register state when the
checkpointed GPRs of a 32-bit thread are accessed. This can cause core
dumps to have stale data in the checkpointed GPR note.
---
 arch/powerpc/kernel/ptrace.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 6618570c6d56..be8ca03a0bd5 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -2124,6 +2124,16 @@ static int tm_cgpr32_get(struct task_struct *target,
                     unsigned int pos, unsigned int count,
                     void *kbuf, void __user *ubuf)
 {
+       if (!cpu_has_feature(CPU_FTR_TM))
+               return -ENODEV;
+
+       if (!MSR_TM_ACTIVE(target->thread.regs->msr))
+               return -ENODATA;
+
+       flush_tmregs_to_thread(target);
+       flush_fp_to_thread(target);
+       flush_altivec_to_thread(target);
+
        return gpr32_get_common(target, regset, pos, count, kbuf, ubuf,
                        &target->thread.ckpt_regs.gpr[0]);
 }
@@ -2133,6 +2143,16 @@ static int tm_cgpr32_set(struct task_struct *target,
                     unsigned int pos, unsigned int count,
                     const void *kbuf, const void __user *ubuf)
 {
+       if (!cpu_has_feature(CPU_FTR_TM))
+               return -ENODEV;
+
+       if (!MSR_TM_ACTIVE(target->thread.regs->msr))
+               return -ENODATA;
+
+       flush_tmregs_to_thread(target);
+       flush_fp_to_thread(target);
+       flush_altivec_to_thread(target);
+
        return gpr32_set_common(target, regset, pos, count, kbuf, ubuf,
                        &target->thread.ckpt_regs.gpr[0]);
 }
-- 
2.13.6

Reply via email to