aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 510452812594..7da6e324dd35 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -46,6 +46,26 @@
46#define CREATE_TRACE_POINTS 46#define CREATE_TRACE_POINTS
47#include <trace/events/syscalls.h> 47#include <trace/events/syscalls.h>
48 48
49static void init_fp_ctx(struct task_struct *target)
50{
51 /* If FP has been used then the target already has context */
52 if (tsk_used_math(target))
53 return;
54
55 /* Begin with data registers set to all 1s... */
56 memset(&target->thread.fpu.fpr, ~0, sizeof(target->thread.fpu.fpr));
57
58 /* ...and FCSR zeroed */
59 target->thread.fpu.fcr31 = 0;
60
61 /*
62 * Record that the target has "used" math, such that the context
63 * just initialised, and any modifications made by the caller,
64 * aren't discarded.
65 */
66 set_stopped_child_used_math(target);
67}
68
49/* 69/*
50 * Called by kernel/ptrace.c when detaching.. 70 * Called by kernel/ptrace.c when detaching..
51 * 71 *
@@ -142,6 +162,7 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
142 if (!access_ok(VERIFY_READ, data, 33 * 8)) 162 if (!access_ok(VERIFY_READ, data, 33 * 8))
143 return -EIO; 163 return -EIO;
144 164
165 init_fp_ctx(child);
145 fregs = get_fpu_regs(child); 166 fregs = get_fpu_regs(child);
146 167
147 for (i = 0; i < 32; i++) { 168 for (i = 0; i < 32; i++) {
@@ -439,6 +460,8 @@ static int fpr_set(struct task_struct *target,
439 460
440 /* XXX fcr31 */ 461 /* XXX fcr31 */
441 462
463 init_fp_ctx(target);
464
442 if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t)) 465 if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t))
443 return user_regset_copyin(&pos, &count, &kbuf, &ubuf, 466 return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
444 &target->thread.fpu, 467 &target->thread.fpu,
@@ -660,12 +683,7 @@ long arch_ptrace(struct task_struct *child, long request,
660 case FPR_BASE ... FPR_BASE + 31: { 683 case FPR_BASE ... FPR_BASE + 31: {
661 union fpureg *fregs = get_fpu_regs(child); 684 union fpureg *fregs = get_fpu_regs(child);
662 685
663 if (!tsk_used_math(child)) { 686 init_fp_ctx(child);
664 /* FP not yet used */
665 memset(&child->thread.fpu, ~0,
666 sizeof(child->thread.fpu));
667 child->thread.fpu.fcr31 = 0;
668 }
669#ifdef CONFIG_32BIT 687#ifdef CONFIG_32BIT
670 if (test_thread_flag(TIF_32BIT_FPREGS)) { 688 if (test_thread_flag(TIF_32BIT_FPREGS)) {
671 /* 689 /*