Here is a (revised) patch to fix some preempt issues around fpu and ptrace. For now, get_fpu_regs() is used in ptrace code only and the condition 'tsk == current' should always be false. So we can just remove _save_fp() call instead of disabling preemption. diff -ur linux-mips/arch/mips/kernel/ptrace.c linux/arch/mips/kernel/ptrace.c --- linux-mips/arch/mips/kernel/ptrace.c 2005-04-18 11:42:47.000000000 +0900 +++ linux/arch/mips/kernel/ptrace.c 2005-05-10 11:41:35.000000000 +0900 @@ -169,10 +169,12 @@ if (!cpu_has_fpu) break; + preempt_disable(); flags = read_c0_status(); __enable_fpu(); __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); write_c0_status(flags); + preempt_enable(); break; } default: diff -ur linux-mips/arch/mips/kernel/ptrace32.c linux/arch/mips/kernel/ptrace32.c --- linux-mips/arch/mips/kernel/ptrace32.c 2005-04-18 11:42:47.000000000 +0900 +++ linux/arch/mips/kernel/ptrace32.c 2005-05-10 11:38:51.000000000 +0900 @@ -155,10 +155,12 @@ if (!cpu_has_fpu) break; + preempt_disable(); flags = read_c0_status(); __enable_fpu(); __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); write_c0_status(flags); + preempt_enable(); break; } default: diff -ur linux-mips/include/asm-mips/fpu.h linux/include/asm-mips/fpu.h --- linux-mips/include/asm-mips/fpu.h 2005-05-10 10:21:31.000000000 +0900 +++ linux/include/asm-mips/fpu.h 2005-05-10 11:38:38.000000000 +0900 @@ -132,8 +132,10 @@ static inline fpureg_t *get_fpu_regs(struct task_struct *tsk) { if (cpu_has_fpu) { + preempt_disable(); if ((tsk == current) && __is_fpu_owner()) _save_fp(current); + preempt_enable(); return tsk->thread.fpu.hard.fpr; } --- Atsushi Nemoto