aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/ptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/ptrace.c')
-rw-r--r--arch/mips/kernel/ptrace.c39
1 files changed, 17 insertions, 22 deletions
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index a17a7023d7c9..7d97709e715f 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -120,9 +120,10 @@ int ptrace_getfpregs(struct task_struct *child, __u32 __user *data)
120 return -EIO; 120 return -EIO;
121 121
122 if (tsk_used_math(child)) { 122 if (tsk_used_math(child)) {
123 fpureg_t *fregs = get_fpu_regs(child); 123 union fpureg *fregs = get_fpu_regs(child);
124 for (i = 0; i < 32; i++) 124 for (i = 0; i < 32; i++)
125 __put_user(fregs[i], i + (__u64 __user *) data); 125 __put_user(get_fpr64(&fregs[i], 0),
126 i + (__u64 __user *)data);
126 } else { 127 } else {
127 for (i = 0; i < 32; i++) 128 for (i = 0; i < 32; i++)
128 __put_user((__u64) -1, i + (__u64 __user *) data); 129 __put_user((__u64) -1, i + (__u64 __user *) data);
@@ -158,7 +159,8 @@ int ptrace_getfpregs(struct task_struct *child, __u32 __user *data)
158 159
159int ptrace_setfpregs(struct task_struct *child, __u32 __user *data) 160int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
160{ 161{
161 fpureg_t *fregs; 162 union fpureg *fregs;
163 u64 fpr_val;
162 int i; 164 int i;
163 165
164 if (!access_ok(VERIFY_READ, data, 33 * 8)) 166 if (!access_ok(VERIFY_READ, data, 33 * 8))
@@ -166,8 +168,10 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
166 168
167 fregs = get_fpu_regs(child); 169 fregs = get_fpu_regs(child);
168 170
169 for (i = 0; i < 32; i++) 171 for (i = 0; i < 32; i++) {
170 __get_user(fregs[i], i + (__u64 __user *) data); 172 __get_user(fpr_val, i + (__u64 __user *)data);
173 set_fpr64(&fregs[i], 0, fpr_val);
174 }
171 175
172 __get_user(child->thread.fpu.fcr31, data + 64); 176 __get_user(child->thread.fpu.fcr31, data + 64);
173 177
@@ -408,7 +412,7 @@ long arch_ptrace(struct task_struct *child, long request,
408 /* Read the word at location addr in the USER area. */ 412 /* Read the word at location addr in the USER area. */
409 case PTRACE_PEEKUSR: { 413 case PTRACE_PEEKUSR: {
410 struct pt_regs *regs; 414 struct pt_regs *regs;
411 fpureg_t *fregs; 415 union fpureg *fregs;
412 unsigned long tmp = 0; 416 unsigned long tmp = 0;
413 417
414 regs = task_pt_regs(child); 418 regs = task_pt_regs(child);
@@ -433,14 +437,12 @@ long arch_ptrace(struct task_struct *child, long request,
433 * order bits of the values stored in the even 437 * order bits of the values stored in the even
434 * registers - unless we're using r2k_switch.S. 438 * registers - unless we're using r2k_switch.S.
435 */ 439 */
436 if (addr & 1) 440 tmp = get_fpr32(&fregs[(addr & ~1) - FPR_BASE],
437 tmp = fregs[(addr & ~1) - 32] >> 32; 441 addr & 1);
438 else
439 tmp = fregs[addr - 32];
440 break; 442 break;
441 } 443 }
442#endif 444#endif
443 tmp = fregs[addr - FPR_BASE]; 445 tmp = get_fpr32(&fregs[addr - FPR_BASE], 0);
444 break; 446 break;
445 case PC: 447 case PC:
446 tmp = regs->cp0_epc; 448 tmp = regs->cp0_epc;
@@ -548,7 +550,7 @@ long arch_ptrace(struct task_struct *child, long request,
548 regs->regs[addr] = data; 550 regs->regs[addr] = data;
549 break; 551 break;
550 case FPR_BASE ... FPR_BASE + 31: { 552 case FPR_BASE ... FPR_BASE + 31: {
551 fpureg_t *fregs = get_fpu_regs(child); 553 union fpureg *fregs = get_fpu_regs(child);
552 554
553 if (!tsk_used_math(child)) { 555 if (!tsk_used_math(child)) {
554 /* FP not yet used */ 556 /* FP not yet used */
@@ -563,19 +565,12 @@ long arch_ptrace(struct task_struct *child, long request,
563 * order bits of the values stored in the even 565 * order bits of the values stored in the even
564 * registers - unless we're using r2k_switch.S. 566 * registers - unless we're using r2k_switch.S.
565 */ 567 */
566 if (addr & 1) { 568 set_fpr32(&fregs[(addr & ~1) - FPR_BASE],
567 fregs[(addr & ~1) - FPR_BASE] &= 569 addr & 1, data);
568 0xffffffff;
569 fregs[(addr & ~1) - FPR_BASE] |=
570 ((u64)data) << 32;
571 } else {
572 fregs[addr - FPR_BASE] &= ~0xffffffffLL;
573 fregs[addr - FPR_BASE] |= data;
574 }
575 break; 570 break;
576 } 571 }
577#endif 572#endif
578 fregs[addr - FPR_BASE] = data; 573 set_fpr64(&fregs[addr - FPR_BASE], 0, data);
579 break; 574 break;
580 } 575 }
581 case PC: 576 case PC: