aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/ptrace.c
diff options
context:
space:
mode:
authorPaul Burton <paul.burton@imgtec.com>2014-02-13 06:26:41 -0500
committerRalf Baechle <ralf@linux-mips.org>2014-03-26 18:09:09 -0400
commitbbd426f542cb61f2322e15dab4507f2661090c06 (patch)
tree66cc94a921b0342a4a412646d549562a578fc257 /arch/mips/kernel/ptrace.c
parent490b004febb3fe9aca7330a729b29fe935be3b31 (diff)
MIPS: Simplify FP context access
This patch replaces the fpureg_t typedef with a "union fpureg" enabling easier access to 32 & 64 bit values. This allows the access macros used in cp1emu.c to be simplified somewhat. It will also make it easier to expand the width of the FP registers as will be done in a future patch in order to support the 128 bit registers introduced with MSA. No behavioural change is intended by this patch. Signed-off-by: Paul Burton <paul.burton@imgtec.com> Reviewed-by: Qais Yousef <qais.yousef@imgtec.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/6532/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
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: