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.c60
1 files changed, 33 insertions, 27 deletions
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index b52e1d2b33e0..7da9b76db4d9 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -137,13 +137,13 @@ int ptrace_getfpregs(struct task_struct *child, __u32 __user *data)
137 if (cpu_has_mipsmt) { 137 if (cpu_has_mipsmt) {
138 unsigned int vpflags = dvpe(); 138 unsigned int vpflags = dvpe();
139 flags = read_c0_status(); 139 flags = read_c0_status();
140 __enable_fpu(); 140 __enable_fpu(FPU_AS_IS);
141 __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp)); 141 __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
142 write_c0_status(flags); 142 write_c0_status(flags);
143 evpe(vpflags); 143 evpe(vpflags);
144 } else { 144 } else {
145 flags = read_c0_status(); 145 flags = read_c0_status();
146 __enable_fpu(); 146 __enable_fpu(FPU_AS_IS);
147 __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp)); 147 __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
148 write_c0_status(flags); 148 write_c0_status(flags);
149 } 149 }
@@ -408,6 +408,7 @@ long arch_ptrace(struct task_struct *child, long request,
408 /* Read the word at location addr in the USER area. */ 408 /* Read the word at location addr in the USER area. */
409 case PTRACE_PEEKUSR: { 409 case PTRACE_PEEKUSR: {
410 struct pt_regs *regs; 410 struct pt_regs *regs;
411 fpureg_t *fregs;
411 unsigned long tmp = 0; 412 unsigned long tmp = 0;
412 413
413 regs = task_pt_regs(child); 414 regs = task_pt_regs(child);
@@ -418,26 +419,28 @@ long arch_ptrace(struct task_struct *child, long request,
418 tmp = regs->regs[addr]; 419 tmp = regs->regs[addr];
419 break; 420 break;
420 case FPR_BASE ... FPR_BASE + 31: 421 case FPR_BASE ... FPR_BASE + 31:
421 if (tsk_used_math(child)) { 422 if (!tsk_used_math(child)) {
422 fpureg_t *fregs = get_fpu_regs(child); 423 /* FP not yet used */
424 tmp = -1;
425 break;
426 }
427 fregs = get_fpu_regs(child);
423 428
424#ifdef CONFIG_32BIT 429#ifdef CONFIG_32BIT
430 if (test_thread_flag(TIF_32BIT_FPREGS)) {
425 /* 431 /*
426 * The odd registers are actually the high 432 * The odd registers are actually the high
427 * order bits of the values stored in the even 433 * order bits of the values stored in the even
428 * registers - unless we're using r2k_switch.S. 434 * registers - unless we're using r2k_switch.S.
429 */ 435 */
430 if (addr & 1) 436 if (addr & 1)
431 tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32); 437 tmp = fregs[(addr & ~1) - 32] >> 32;
432 else 438 else
433 tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff); 439 tmp = fregs[addr - 32];
434#endif 440 break;
435#ifdef CONFIG_64BIT
436 tmp = fregs[addr - FPR_BASE];
437#endif
438 } else {
439 tmp = -1; /* FP not yet used */
440 } 441 }
442#endif
443 tmp = fregs[addr - FPR_BASE];
441 break; 444 break;
442 case PC: 445 case PC:
443 tmp = regs->cp0_epc; 446 tmp = regs->cp0_epc;
@@ -483,13 +486,13 @@ long arch_ptrace(struct task_struct *child, long request,
483 if (cpu_has_mipsmt) { 486 if (cpu_has_mipsmt) {
484 unsigned int vpflags = dvpe(); 487 unsigned int vpflags = dvpe();
485 flags = read_c0_status(); 488 flags = read_c0_status();
486 __enable_fpu(); 489 __enable_fpu(FPU_AS_IS);
487 __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); 490 __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
488 write_c0_status(flags); 491 write_c0_status(flags);
489 evpe(vpflags); 492 evpe(vpflags);
490 } else { 493 } else {
491 flags = read_c0_status(); 494 flags = read_c0_status();
492 __enable_fpu(); 495 __enable_fpu(FPU_AS_IS);
493 __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); 496 __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
494 write_c0_status(flags); 497 write_c0_status(flags);
495 } 498 }
@@ -554,22 +557,25 @@ long arch_ptrace(struct task_struct *child, long request,
554 child->thread.fpu.fcr31 = 0; 557 child->thread.fpu.fcr31 = 0;
555 } 558 }
556#ifdef CONFIG_32BIT 559#ifdef CONFIG_32BIT
557 /* 560 if (test_thread_flag(TIF_32BIT_FPREGS)) {
558 * The odd registers are actually the high order bits 561 /*
559 * of the values stored in the even registers - unless 562 * The odd registers are actually the high
560 * we're using r2k_switch.S. 563 * order bits of the values stored in the even
561 */ 564 * registers - unless we're using r2k_switch.S.
562 if (addr & 1) { 565 */
563 fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff; 566 if (addr & 1) {
564 fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long long) data) << 32; 567 fregs[(addr & ~1) - FPR_BASE] &=
565 } else { 568 0xffffffff;
566 fregs[addr - FPR_BASE] &= ~0xffffffffLL; 569 fregs[(addr & ~1) - FPR_BASE] |=
567 fregs[addr - FPR_BASE] |= data; 570 ((u64)data) << 32;
571 } else {
572 fregs[addr - FPR_BASE] &= ~0xffffffffLL;
573 fregs[addr - FPR_BASE] |= data;
574 }
575 break;
568 } 576 }
569#endif 577#endif
570#ifdef CONFIG_64BIT
571 fregs[addr - FPR_BASE] = data; 578 fregs[addr - FPR_BASE] = data;
572#endif
573 break; 579 break;
574 } 580 }
575 case PC: 581 case PC: