diff options
Diffstat (limited to 'arch/mips/kernel/ptrace32.c')
| -rw-r--r-- | arch/mips/kernel/ptrace32.c | 53 |
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); |
