X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fmips%2Fkernel%2Fptrace.c;h=ceaf3e947cc602c26e9236e3daeef33212fffad4;hb=9464c7cf61b9433057924c36e6e02f303a00e768;hp=1c74235f7d42bb0866f6b4b32b6175333022c6ae;hpb=41689045f6a3cbe0550e1d34e9cc20d2e8c432ba;p=linux-2.6.git diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 1c74235f7..ceaf3e947 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -14,6 +14,7 @@ * At this time Linux/MIPS64 only supports syscall tracing, even for 32-bit * binaries. */ +#include #include #include #include @@ -119,11 +120,11 @@ int ptrace_getfpregs (struct task_struct *child, __u32 __user *data) __put_user ((__u64) -1, i + (__u64 __user *) data); } - __put_user (child->thread.fpu.fcr31, data + 64); - if (cpu_has_fpu) { unsigned int flags, tmp; + __put_user (child->thread.fpu.hard.fcr31, data + 64); + preempt_disable(); if (cpu_has_mipsmt) { unsigned int vpflags = dvpe(); @@ -141,6 +142,7 @@ int ptrace_getfpregs (struct task_struct *child, __u32 __user *data) preempt_enable(); __put_user (tmp, data + 65); } else { + __put_user (child->thread.fpu.soft.fcr31, data + 64); __put_user ((__u32) 0, data + 65); } @@ -160,7 +162,10 @@ int ptrace_setfpregs (struct task_struct *child, __u32 __user *data) for (i = 0; i < 32; i++) __get_user (fregs[i], i + (__u64 __user *) data); - __get_user (child->thread.fpu.fcr31, data + 64); + if (cpu_has_fpu) + __get_user (child->thread.fpu.hard.fcr31, data + 64); + else + __get_user (child->thread.fpu.soft.fcr31, data + 64); /* FIR may not be written. */ @@ -171,9 +176,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) { int ret; - if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT)) - goto out; - switch (request) { /* when I and D space are separate, these will need to be fixed. */ case PTRACE_PEEKTEXT: /* read word at location addr. */ @@ -239,7 +241,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) tmp = regs->lo; break; case FPC_CSR: - tmp = child->thread.fpu.fcr31; + if (cpu_has_fpu) + tmp = child->thread.fpu.hard.fcr31; + else + tmp = child->thread.fpu.soft.fcr31; break; case FPC_EIR: { /* implementation / version register */ unsigned int flags; @@ -331,9 +336,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) if (!tsk_used_math(child)) { /* FP not yet used */ - memset(&child->thread.fpu, ~0, - sizeof(child->thread.fpu)); - child->thread.fpu.fcr31 = 0; + memset(&child->thread.fpu.hard, ~0, + sizeof(child->thread.fpu.hard)); + child->thread.fpu.hard.fcr31 = 0; } #ifdef CONFIG_32BIT /* @@ -364,7 +369,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) regs->lo = data; break; case FPC_CSR: - child->thread.fpu.fcr31 = data; + if (cpu_has_fpu) + child->thread.fpu.hard.fcr31 = data; + else + child->thread.fpu.soft.fcr31 = data; break; case DSP_BASE ... DSP_BASE + 5: { dspreg_t *dregs; @@ -482,6 +490,8 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) goto out; if (!test_thread_flag(TIF_SYSCALL_TRACE)) goto out; + if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT)) + goto out_tsk; /* The 0x80 provides a way for the tracing parent to distinguish between a syscall stop and SIGTRAP delivery */