* [PATCH] Make sure cpu_has_fpu is used only in atomic context
[not found] ` <20060901.170817.118968734.nemoto@toshiba-tops.co.jp>
@ 2006-10-08 15:10 ` Atsushi Nemoto
2006-10-09 16:02 ` Ralf Baechle
0 siblings, 1 reply; 2+ messages in thread
From: Atsushi Nemoto @ 2006-10-08 15:10 UTC (permalink / raw)
To: linux-mips; +Cc: ralf, mlachwani
Make sure cpu_has_fpu (which uses smp_processor_id()) is used
only in atomic context.
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
arch/mips/kernel/proc.c | 2 +-
arch/mips/kernel/process.c | 2 +-
arch/mips/kernel/ptrace.c | 18 ++++++++++--------
arch/mips/kernel/ptrace32.c | 3 ++-
arch/mips/kernel/traps.c | 16 +++++++++-------
arch/mips/math-emu/cp1emu.c | 7 +++----
include/asm-mips/fpu.h | 6 ++++--
7 files changed, 30 insertions(+), 24 deletions(-)
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
index 46ee5a6..4ed37ba 100644
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -107,7 +107,7 @@ #endif
seq_printf(m, "processor\t\t: %ld\n", n);
sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",
- cpu_has_fpu ? " FPU V%d.%d" : "");
+ cpu_data[n].options & MIPS_CPU_FPU ? " FPU V%d.%d" : "");
seq_printf(m, fmt, cpu_name[cpu_data[n].cputype <= CPU_LAST ?
cpu_data[n].cputype : CPU_UNKNOWN],
(version >> 4) & 0x0f, version & 0x0f,
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 045d987..9f307eb 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -115,7 +115,7 @@ #endif
status |= KU_USER;
regs->cp0_status = status;
clear_used_math();
- lose_fpu();
+ clear_fpu_owner();
if (cpu_has_dsp)
__init_dsp();
regs->cp0_epc = pc;
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 9c3b5fc..1fd705a 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -106,6 +106,7 @@ int ptrace_setregs (struct task_struct *
int ptrace_getfpregs (struct task_struct *child, __u32 __user *data)
{
int i;
+ unsigned int tmp;
if (!access_ok(VERIFY_WRITE, data, 33 * 8))
return -EIO;
@@ -121,10 +122,10 @@ int ptrace_getfpregs (struct task_struct
__put_user (child->thread.fpu.fcr31, data + 64);
+ preempt_disable();
if (cpu_has_fpu) {
- unsigned int flags, tmp;
+ unsigned int flags;
- preempt_disable();
if (cpu_has_mipsmt) {
unsigned int vpflags = dvpe();
flags = read_c0_status();
@@ -138,11 +139,11 @@ int ptrace_getfpregs (struct task_struct
__asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
write_c0_status(flags);
}
- preempt_enable();
- __put_user (tmp, data + 65);
} else {
- __put_user ((__u32) 0, data + 65);
+ tmp = 0;
}
+ preempt_enable();
+ __put_user (tmp, data + 65);
return 0;
}
@@ -245,16 +246,17 @@ #ifdef CONFIG_MIPS_MT_SMTC
unsigned int mtflags;
#endif /* CONFIG_MIPS_MT_SMTC */
- if (!cpu_has_fpu)
+ preempt_disable();
+ if (!cpu_has_fpu) {
+ preempt_enable();
break;
+ }
#ifdef CONFIG_MIPS_MT_SMTC
/* Read-modify-write of Status must be atomic */
local_irq_save(irqflags);
mtflags = dmt();
#endif /* CONFIG_MIPS_MT_SMTC */
-
- preempt_disable();
if (cpu_has_mipsmt) {
unsigned int vpflags = dvpe();
flags = read_c0_status();
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index f40ecd8..d9a39c1 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -175,7 +175,9 @@ #ifdef CONFIG_MIPS_MT_SMTC
unsigned int mtflags;
#endif /* CONFIG_MIPS_MT_SMTC */
+ preempt_disable();
if (!cpu_has_fpu) {
+ preempt_enable();
tmp = 0;
break;
}
@@ -186,7 +188,6 @@ #ifdef CONFIG_MIPS_MT_SMTC
mtflags = dmt();
#endif /* CONFIG_MIPS_MT_SMTC */
- preempt_disable();
if (cpu_has_mipsmt) {
unsigned int vpflags = dvpe();
flags = read_c0_status();
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index b7292a5..cce8313 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -66,7 +66,7 @@ extern asmlinkage void handle_mcheck(voi
extern asmlinkage void handle_reserved(void);
extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
- struct mips_fpu_struct *ctx);
+ struct mips_fpu_struct *ctx, int has_fpu);
void (*board_be_init)(void);
int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
@@ -641,7 +641,7 @@ #endif
preempt_enable();
/* Run the emulator */
- sig = fpu_emulator_cop1Handler (regs, ¤t->thread.fpu);
+ sig = fpu_emulator_cop1Handler (regs, ¤t->thread.fpu, 1);
preempt_disable();
@@ -791,11 +791,13 @@ asmlinkage void do_cpu(struct pt_regs *r
set_used_math();
}
- preempt_enable();
-
- if (!cpu_has_fpu) {
- int sig = fpu_emulator_cop1Handler(regs,
- ¤t->thread.fpu);
+ if (cpu_has_fpu) {
+ preempt_enable();
+ } else {
+ int sig;
+ preempt_enable();
+ sig = fpu_emulator_cop1Handler(regs,
+ ¤t->thread.fpu, 0);
if (sig)
force_sig(sig, current);
#ifdef CONFIG_MIPS_MT_FPAFF
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index 3f0d5d2..80531b3 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -38,8 +38,6 @@ #include <linux/sched.h>
#include <asm/inst.h>
#include <asm/bootinfo.h>
-#include <asm/cpu.h>
-#include <asm/cpu-features.h>
#include <asm/processor.h>
#include <asm/ptrace.h>
#include <asm/signal.h>
@@ -1233,7 +1231,8 @@ #endif
return 0;
}
-int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
+int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ int has_fpu)
{
unsigned long oldepc, prevepc;
mips_instruction insn;
@@ -1263,7 +1262,7 @@ int fpu_emulator_cop1Handler(struct pt_r
ieee754_csr.rm = mips_rm[ieee754_csr.rm];
}
- if (cpu_has_fpu)
+ if (has_fpu)
break;
if (sig)
break;
diff --git a/include/asm-mips/fpu.h b/include/asm-mips/fpu.h
index 58c561a..efef843 100644
--- a/include/asm-mips/fpu.h
+++ b/include/asm-mips/fpu.h
@@ -134,9 +134,11 @@ static inline void restore_fp(struct tas
static inline fpureg_t *get_fpu_regs(struct task_struct *tsk)
{
- if (cpu_has_fpu) {
- if ((tsk == current) && __is_fpu_owner())
+ if (tsk == current) {
+ preempt_disable();
+ if (is_fpu_owner())
_save_fp(current);
+ preempt_enable();
}
return tsk->thread.fpu.fpr;
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] Make sure cpu_has_fpu is used only in atomic context
2006-10-08 15:10 ` [PATCH] Make sure cpu_has_fpu is used only in atomic context Atsushi Nemoto
@ 2006-10-09 16:02 ` Ralf Baechle
0 siblings, 0 replies; 2+ messages in thread
From: Ralf Baechle @ 2006-10-09 16:02 UTC (permalink / raw)
To: Atsushi Nemoto; +Cc: linux-mips, mlachwani
On Mon, Oct 09, 2006 at 12:10:01AM +0900, Atsushi Nemoto wrote:
> Make sure cpu_has_fpu (which uses smp_processor_id()) is used
> only in atomic context.
It's awfully ugly to have an increasing number of preemption kludgery
around but it's not so trivial to avoid unfortunately ...
Ralf
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2006-10-09 16:02 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <44F715F2.7050305@mvista.com>
[not found] ` <20060901.122527.63741495.nemoto@toshiba-tops.co.jp>
[not found] ` <20060901.170817.118968734.nemoto@toshiba-tops.co.jp>
2006-10-08 15:10 ` [PATCH] Make sure cpu_has_fpu is used only in atomic context Atsushi Nemoto
2006-10-09 16:02 ` Ralf Baechle
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox