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
|