diff options
| author | Dave Martin <Dave.Martin@arm.com> | 2017-01-05 11:50:57 -0500 |
|---|---|---|
| committer | Michael Ellerman <mpe@ellerman.id.au> | 2017-01-19 22:55:19 -0500 |
| commit | b34ca60148c53971d373643195cc5c4d5d20be78 (patch) | |
| tree | 434266b9f31e68d97566b46a3c777ae2dab3f579 | |
| parent | 99dfe80a2a246c600440a815741fd2e74a8b4977 (diff) | |
powerpc/ptrace: Preserve previous TM fprs/vsrs on short regset write
Ensure that if userspace supplies insufficient data to PTRACE_SETREGSET
to fill all the check pointed registers, the thread's old check pointed
registers are preserved.
Fixes: 9d3918f7c0e5 ("powerpc/ptrace: Enable support for NT_PPC_CVSX")
Fixes: 19cbcbf75a0c ("powerpc/ptrace: Enable support for NT_PPC_CFPR")
Cc: stable@vger.kernel.org # v4.8+
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
| -rw-r--r-- | arch/powerpc/kernel/ptrace.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 10543eb1f8f3..925a4ef90559 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
| @@ -1026,6 +1026,10 @@ static int tm_cfpr_set(struct task_struct *target, | |||
| 1026 | flush_fp_to_thread(target); | 1026 | flush_fp_to_thread(target); |
| 1027 | flush_altivec_to_thread(target); | 1027 | flush_altivec_to_thread(target); |
| 1028 | 1028 | ||
| 1029 | for (i = 0; i < 32; i++) | ||
| 1030 | buf[i] = target->thread.TS_CKFPR(i); | ||
| 1031 | buf[32] = target->thread.ckfp_state.fpscr; | ||
| 1032 | |||
| 1029 | /* copy to local buffer then write that out */ | 1033 | /* copy to local buffer then write that out */ |
| 1030 | i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1); | 1034 | i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1); |
| 1031 | if (i) | 1035 | if (i) |
| @@ -1290,6 +1294,9 @@ static int tm_cvsx_set(struct task_struct *target, | |||
| 1290 | flush_altivec_to_thread(target); | 1294 | flush_altivec_to_thread(target); |
| 1291 | flush_vsx_to_thread(target); | 1295 | flush_vsx_to_thread(target); |
| 1292 | 1296 | ||
| 1297 | for (i = 0; i < 32 ; i++) | ||
| 1298 | buf[i] = target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET]; | ||
| 1299 | |||
| 1293 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, | 1300 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, |
| 1294 | buf, 0, 32 * sizeof(double)); | 1301 | buf, 0, 32 * sizeof(double)); |
| 1295 | if (!ret) | 1302 | if (!ret) |
