aboutsummaryrefslogtreecommitdiff
path: root/arch/arm64
diff options
context:
space:
mode:
authorVictor Kamensky <victor.kamensky@linaro.org>2014-06-03 19:21:30 +0100
committerMark Brown <broonie@kernel.org>2014-10-24 13:18:21 +0100
commit9efcded7f200e658058bf790e4936aa17a989da7 (patch)
tree5fcc2b535e6f36e5866556f09e0cc480e4527b5c /arch/arm64
parent8aaf231854e4397874817d9a02783b783ad77716 (diff)
arm64: ptrace: fix empty registers set in prstatus of aarch32 process core
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@kernel.org> Conflicts: arch/arm64/kernel/ptrace.c
Diffstat (limited to 'arch/arm64')
-rw-r--r--arch/arm64/kernel/ptrace.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 9fa78cd0f092..71c6a623e226 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -650,12 +650,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 (ret)
- break;
- else
- ubuf += sizeof(compat_ulong_t);
+ if (kbuf) {
+ memcpy(kbuf, &reg, sizeof(reg));
+ kbuf += sizeof(reg);
+ } else {
+ ret = copy_to_user(ubuf, &reg, sizeof(reg));
+ if (ret)
+ break;
+
+ ubuf += sizeof(reg);
+ }
}
return ret;
@@ -683,7 +687,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(&reg, kbuf, sizeof(reg));
+ kbuf += sizeof(reg);
+ } else {
+ ret = copy_from_user(&reg, ubuf, sizeof(reg));
+ if (ret)
+ return ret;
+
+ ubuf += sizeof(reg);
+ }
switch (idx) {
case 15: