diff options
author | Victor Kamensky <victor.kamensky@linaro.org> | 2014-06-03 19:21:30 +0100 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-07-23 00:10:48 +0100 |
commit | dd7d4626b70d246242c57c4a9ffaecb961570406 (patch) | |
tree | 35e252bc2894cea3915d44e7b96c1c083731bbbb | |
parent | ab7ccd91004b55c29910c999f51bc40880646810 (diff) |
arm64: ptrace: fix empty registers set in prstatus of aarch32 process corev3.10/topic/ptracev3.10/topic/arm64-ptrace
Currently core file of aarch32 process prstatus note has empty
registers set. As result aarch32 core files create by V8 kernel are
not very useful.
It happens because compat_gpr_get and compat_gpr_set functions can
copy registers values to/from either kbuf or ubuf. ELF core file
collection function fill_thread_core_info calls compat_gpr_get
with kbuf set and ubuf set to 0. But current compat_gpr_get and
compat_gpr_set function handle copy to/from only ubuf case.
Fix is to handle kbuf and ubuf as two separate cases in similar
way as other functions like user_regset_copyout, user_regset_copyin do.
Signed-off-by: Victor Kamensky <victor.kamensky@linaro.org>
Acked-by: Will Deacon <will.deacon@arm.com>
Cc: stable@vger.kernel.org
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
(cherry picked from commit 2227901a0230d8fde81ba9c602d649839390f56b)
Signed-off-by: Mark Brown <broonie@linaro.org>
Conflicts:
arch/arm64/kernel/ptrace.c
-rw-r--r-- | arch/arm64/kernel/ptrace.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 85536688f753..9212dc4bcd09 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -672,12 +672,16 @@ static int compat_gpr_get(struct task_struct *target, reg = (void *)&task_pt_regs(target)->regs[idx]; } - ret = copy_to_user(ubuf, reg, sizeof(compat_ulong_t)); + if (kbuf) { + memcpy(kbuf, ®, sizeof(reg)); + kbuf += sizeof(reg); + } else { + ret = copy_to_user(ubuf, ®, sizeof(reg)); + if (ret) + break; - if (ret) - break; - else - ubuf += sizeof(compat_ulong_t); + ubuf += sizeof(reg); + } } return ret; @@ -705,7 +709,18 @@ static int compat_gpr_set(struct task_struct *target, for (i = 0; i < num_regs; ++i) { unsigned int idx = start + i; - void *reg; + compat_ulong_t reg; + + if (kbuf) { + memcpy(®, kbuf, sizeof(reg)); + kbuf += sizeof(reg); + } else { + ret = copy_from_user(®, ubuf, sizeof(reg)); + if (ret) + return ret; + + ubuf += sizeof(reg); + } switch (idx) { case 15: |