aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/kernel/ptrace.c
diff options
context:
space:
mode:
authorGravatar Ralf Baechle <ralf@linux-mips.org> 2015-04-13 16:01:37 +0200
committerGravatar Ralf Baechle <ralf@linux-mips.org> 2015-04-13 16:01:37 +0200
commit98b0429b7abd5c05efdb23f3eba02ec3f696748e (patch)
tree44e6028c3be974dd42665510ada6a09fb5f8f1be /arch/mips/kernel/ptrace.c
parentMIPS: BCM63xx: Provide a plat_post_dma_flush hook (diff)
parentMIPS: MSA: Fix big-endian FPR_IDX implementation (diff)
downloadlinux-98b0429b7abd5c05efdb23f3eba02ec3f696748e.tar.gz
linux-98b0429b7abd5c05efdb23f3eba02ec3f696748e.tar.bz2
linux-98b0429b7abd5c05efdb23f3eba02ec3f696748e.zip
Merge branch '4.1-fp' into mips-for-linux-next
Diffstat (limited to 'arch/mips/kernel/ptrace.c')
-rw-r--r--arch/mips/kernel/ptrace.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 6d1e3f8005f7..d544e774eea6 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -47,6 +47,26 @@
#define CREATE_TRACE_POINTS
#include <trace/events/syscalls.h>
+static void init_fp_ctx(struct task_struct *target)
+{
+ /* If FP has been used then the target already has context */
+ if (tsk_used_math(target))
+ return;
+
+ /* Begin with data registers set to all 1s... */
+ memset(&target->thread.fpu.fpr, ~0, sizeof(target->thread.fpu.fpr));
+
+ /* ...and FCSR zeroed */
+ target->thread.fpu.fcr31 = 0;
+
+ /*
+ * Record that the target has "used" math, such that the context
+ * just initialised, and any modifications made by the caller,
+ * aren't discarded.
+ */
+ set_stopped_child_used_math(target);
+}
+
/*
* Called by kernel/ptrace.c when detaching..
*
@@ -146,6 +166,7 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
if (!access_ok(VERIFY_READ, data, 33 * 8))
return -EIO;
+ init_fp_ctx(child);
fregs = get_fpu_regs(child);
for (i = 0; i < 32; i++) {
@@ -445,6 +466,8 @@ static int fpr_set(struct task_struct *target,
/* XXX fcr31 */
+ init_fp_ctx(target);
+
if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t))
return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
&target->thread.fpu,
@@ -666,12 +689,7 @@ long arch_ptrace(struct task_struct *child, long request,
case FPR_BASE ... FPR_BASE + 31: {
union fpureg *fregs = get_fpu_regs(child);
- if (!tsk_used_math(child)) {
- /* FP not yet used */
- memset(&child->thread.fpu, ~0,
- sizeof(child->thread.fpu));
- child->thread.fpu.fcr31 = 0;
- }
+ init_fp_ctx(child);
#ifdef CONFIG_32BIT
if (test_thread_flag(TIF_32BIT_FPREGS)) {
/*