aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2015-10-27 08:13:38 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-11-03 08:40:42 -0500
commit55a423b6f105fa323168f15f4bb67f23b21da44e (patch)
tree518b2d2983596039f5ab0ba4d1d069aa8b7cc0b8
parentef12cb904e096335ef179bfe30e637a9c2464343 (diff)
s390/kernel: fix ptrace peek/poke for floating point registers
git commit 155e839a814834a3b4b31e729f4716e59d3d2dd4 "s390/kernel: dynamically allocate FP register save area" introduced a regression in regard to ptrace. If the vector register extension is not present or unused the ptrace peek of a floating pointer register return incorrect data and the ptrace poke to a floating pointer register overwrites the task structure starting at task->thread.fpu.fprs. Cc: stable@kernel.org # v4.3 Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/kernel/ptrace.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 3ccd9008a4dc..01c37b36caf9 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -244,7 +244,7 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr)
244 ((addr_t) child->thread.fpu.vxrs + 2*offset); 244 ((addr_t) child->thread.fpu.vxrs + 2*offset);
245 else 245 else
246 tmp = *(addr_t *) 246 tmp = *(addr_t *)
247 ((addr_t) &child->thread.fpu.fprs + offset); 247 ((addr_t) child->thread.fpu.fprs + offset);
248 248
249 } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) { 249 } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
250 /* 250 /*
@@ -388,7 +388,7 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
388 child->thread.fpu.vxrs + 2*offset) = data; 388 child->thread.fpu.vxrs + 2*offset) = data;
389 else 389 else
390 *(addr_t *)((addr_t) 390 *(addr_t *)((addr_t)
391 &child->thread.fpu.fprs + offset) = data; 391 child->thread.fpu.fprs + offset) = data;
392 392
393 } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) { 393 } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
394 /* 394 /*
@@ -622,7 +622,7 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
622 ((addr_t) child->thread.fpu.vxrs + 2*offset); 622 ((addr_t) child->thread.fpu.vxrs + 2*offset);
623 else 623 else
624 tmp = *(__u32 *) 624 tmp = *(__u32 *)
625 ((addr_t) &child->thread.fpu.fprs + offset); 625 ((addr_t) child->thread.fpu.fprs + offset);
626 626
627 } else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) { 627 } else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
628 /* 628 /*
@@ -747,7 +747,7 @@ static int __poke_user_compat(struct task_struct *child,
747 child->thread.fpu.vxrs + 2*offset) = tmp; 747 child->thread.fpu.vxrs + 2*offset) = tmp;
748 else 748 else
749 *(__u32 *)((addr_t) 749 *(__u32 *)((addr_t)
750 &child->thread.fpu.fprs + offset) = tmp; 750 child->thread.fpu.fprs + offset) = tmp;
751 751
752 } else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) { 752 } else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
753 /* 753 /*