From: Ralf Baechle Date: Thu, 6 Oct 2005 16:39:32 +0000 (+0100) Subject: Protect manipulation of c0_status against preemption and multithreading. X-Git-Tag: v2.6.15-rc1~731^2~1^2~38 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=101b3531a693ad890f33f2f04323592cd376616a;p=linux-2.6 Protect manipulation of c0_status against preemption and multithreading. Signed-off-by: Ralf Baechle --- diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 122433f835..fcceab8f2e 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -126,10 +127,21 @@ int ptrace_getfpregs (struct task_struct *child, __u32 __user *data) __put_user (child->thread.fpu.hard.fcr31, data + 64); - flags = read_c0_status(); - __enable_fpu(); - __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp)); - write_c0_status(flags); + preempt_disable(); + if (cpu_has_mipsmt) { + unsigned int vpflags = dvpe(); + flags = read_c0_status(); + __enable_fpu(); + __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp)); + write_c0_status(flags); + evpe(vpflags); + } else { + flags = read_c0_status(); + __enable_fpu(); + __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp)); + write_c0_status(flags); + } + preempt_enable(); __put_user (tmp, data + 65); } else { __put_user (child->thread.fpu.soft.fcr31, data + 64); @@ -284,10 +296,21 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) if (!cpu_has_fpu) break; - flags = read_c0_status(); - __enable_fpu(); - __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); - write_c0_status(flags); + preempt_disable(); + if (cpu_has_mipsmt) { + unsigned int vpflags = dvpe(); + flags = read_c0_status(); + __enable_fpu(); + __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); + write_c0_status(flags); + evpe(vpflags); + } else { + flags = read_c0_status(); + __enable_fpu(); + __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); + write_c0_status(flags); + } + preempt_enable(); break; } case DSP_BASE ... DSP_BASE + 5: { diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c index c28cdddd4c..9a9b049721 100644 --- a/arch/mips/kernel/ptrace32.c +++ b/arch/mips/kernel/ptrace32.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -191,10 +192,21 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) if (!cpu_has_fpu) break; - flags = read_c0_status(); - __enable_fpu(); - __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); - write_c0_status(flags); + preempt_disable(); + if (cpu_has_mipsmt) { + unsigned int vpflags = dvpe(); + flags = read_c0_status(); + __enable_fpu(); + __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); + write_c0_status(flags); + evpe(vpflags); + } else { + flags = read_c0_status(); + __enable_fpu(); + __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); + write_c0_status(flags); + } + preempt_enable(); break; } case DSP_BASE ... DSP_BASE + 5: