summaryrefslogtreecommitdiff
path: root/arch/mips/kernel/ptrace32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/ptrace32.c')
-rw-r--r--arch/mips/kernel/ptrace32.c53
1 files changed, 33 insertions, 20 deletions
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index 40e212d6b26b..afcf27a877cb 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -30,9 +30,9 @@
#include <asm/fpu.h>
#include <asm/mipsregs.h>
#include <asm/mipsmtregs.h>
-#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/reg.h>
+#include <asm/syscall.h>
#include <linux/uaccess.h>
#include <asm/bootinfo.h>
@@ -81,7 +81,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
/* Read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
struct pt_regs *regs;
- union fpureg *fregs;
unsigned int tmp;
regs = task_pt_regs(child);
@@ -91,25 +90,37 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
case 0 ... 31:
tmp = regs->regs[addr];
break;
- case FPR_BASE ... FPR_BASE + 31:
+#ifdef CONFIG_MIPS_FP_SUPPORT
+ case FPR_BASE ... FPR_BASE + 31: {
+ union fpureg *fregs;
+
if (!tsk_used_math(child)) {
/* FP not yet used */
tmp = -1;
break;
}
fregs = get_fpu_regs(child);
- if (test_thread_flag(TIF_32BIT_FPREGS)) {
+ if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) {
/*
* The odd registers are actually the high
* order bits of the values stored in the even
- * registers - unless we're using r2k_switch.S.
+ * registers.
*/
tmp = get_fpr32(&fregs[(addr & ~1) - FPR_BASE],
addr & 1);
break;
}
- tmp = get_fpr32(&fregs[addr - FPR_BASE], 0);
+ tmp = get_fpr64(&fregs[addr - FPR_BASE], 0);
+ break;
+ }
+ case FPC_CSR:
+ tmp = child->thread.fpu.fcr31;
break;
+ case FPC_EIR:
+ /* implementation / version register */
+ tmp = boot_cpu_data.fpu_id;
+ break;
+#endif /* CONFIG_MIPS_FP_SUPPORT */
case PC:
tmp = regs->cp0_epc;
break;
@@ -125,13 +136,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
case MMLO:
tmp = regs->lo;
break;
- case FPC_CSR:
- tmp = child->thread.fpu.fcr31;
- break;
- case FPC_EIR:
- /* implementation / version register */
- tmp = boot_cpu_data.fpu_id;
- break;
case DSP_BASE ... DSP_BASE + 5: {
dspreg_t *dregs;
@@ -141,7 +145,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
goto out;
}
dregs = __get_dsp_regs(child);
- tmp = (unsigned long) (dregs[addr - DSP_BASE]);
+ tmp = dregs[addr - DSP_BASE];
break;
}
case DSP_CONTROL:
@@ -195,7 +199,14 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
switch (addr) {
case 0 ... 31:
regs->regs[addr] = data;
+ /* System call number may have been changed */
+ if (addr == 2)
+ mips_syscall_update_nr(child, regs);
+ else if (addr == 4 &&
+ mips_syscall_is_indirect(child, regs))
+ mips_syscall_update_nr(child, regs);
break;
+#ifdef CONFIG_MIPS_FP_SUPPORT
case FPR_BASE ... FPR_BASE + 31: {
union fpureg *fregs = get_fpu_regs(child);
@@ -205,11 +216,11 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
sizeof(child->thread.fpu));
child->thread.fpu.fcr31 = 0;
}
- if (test_thread_flag(TIF_32BIT_FPREGS)) {
+ if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) {
/*
* The odd registers are actually the high
* order bits of the values stored in the even
- * registers - unless we're using r2k_switch.S.
+ * registers.
*/
set_fpr32(&fregs[(addr & ~1) - FPR_BASE],
addr & 1, data);
@@ -218,6 +229,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
set_fpr64(&fregs[addr - FPR_BASE], 0, data);
break;
}
+ case FPC_CSR:
+ child->thread.fpu.fcr31 = data;
+ break;
+#endif /* CONFIG_MIPS_FP_SUPPORT */
case PC:
regs->cp0_epc = data;
break;
@@ -227,9 +242,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
case MMLO:
regs->lo = data;
break;
- case FPC_CSR:
- child->thread.fpu.fcr31 = data;
- break;
case DSP_BASE ... DSP_BASE + 5: {
dspreg_t *dregs;
@@ -267,6 +279,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
(struct user_pt_regs __user *) (__u64) data);
break;
+#ifdef CONFIG_MIPS_FP_SUPPORT
case PTRACE_GETFPREGS:
ret = ptrace_getfpregs(child, (__u32 __user *) (__u64) data);
break;
@@ -274,7 +287,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
case PTRACE_SETFPREGS:
ret = ptrace_setfpregs(child, (__u32 __user *) (__u64) data);
break;
-
+#endif
case PTRACE_GET_THREAD_AREA:
ret = put_user(task_thread_info(child)->tp_value,
(unsigned int __user *) (unsigned long) data);