diff options
author | Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 2006-10-08 11:10:01 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2006-10-09 18:20:48 -0400 |
commit | e04582b7bc70b40c57287cdc24f81964ee88f565 (patch) | |
tree | a5127c2d4165e656a84612836f6326427843acca /arch | |
parent | f5c70dd7f384db4c524c35288d9be3ed61ac41a9 (diff) |
[MIPS] Make sure cpu_has_fpu is used only in atomic context
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>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips/kernel/proc.c | 2 | ||||
-rw-r--r-- | arch/mips/kernel/process.c | 2 | ||||
-rw-r--r-- | arch/mips/kernel/ptrace.c | 18 | ||||
-rw-r--r-- | arch/mips/kernel/ptrace32.c | 3 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 16 | ||||
-rw-r--r-- | arch/mips/math-emu/cp1emu.c | 7 |
6 files changed, 26 insertions, 22 deletions
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 46ee5a68ab13..4ed37ba19731 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c | |||
@@ -107,7 +107,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
107 | 107 | ||
108 | seq_printf(m, "processor\t\t: %ld\n", n); | 108 | seq_printf(m, "processor\t\t: %ld\n", n); |
109 | sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n", | 109 | sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n", |
110 | cpu_has_fpu ? " FPU V%d.%d" : ""); | 110 | cpu_data[n].options & MIPS_CPU_FPU ? " FPU V%d.%d" : ""); |
111 | seq_printf(m, fmt, cpu_name[cpu_data[n].cputype <= CPU_LAST ? | 111 | seq_printf(m, fmt, cpu_name[cpu_data[n].cputype <= CPU_LAST ? |
112 | cpu_data[n].cputype : CPU_UNKNOWN], | 112 | cpu_data[n].cputype : CPU_UNKNOWN], |
113 | (version >> 4) & 0x0f, version & 0x0f, | 113 | (version >> 4) & 0x0f, version & 0x0f, |
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 045d987bc683..9f307eb1a31e 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -115,7 +115,7 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) | |||
115 | status |= KU_USER; | 115 | status |= KU_USER; |
116 | regs->cp0_status = status; | 116 | regs->cp0_status = status; |
117 | clear_used_math(); | 117 | clear_used_math(); |
118 | lose_fpu(); | 118 | clear_fpu_owner(); |
119 | if (cpu_has_dsp) | 119 | if (cpu_has_dsp) |
120 | __init_dsp(); | 120 | __init_dsp(); |
121 | regs->cp0_epc = pc; | 121 | regs->cp0_epc = pc; |
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 362d1728e531..258d74fd0b63 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c | |||
@@ -106,6 +106,7 @@ int ptrace_setregs (struct task_struct *child, __s64 __user *data) | |||
106 | int ptrace_getfpregs (struct task_struct *child, __u32 __user *data) | 106 | int ptrace_getfpregs (struct task_struct *child, __u32 __user *data) |
107 | { | 107 | { |
108 | int i; | 108 | int i; |
109 | unsigned int tmp; | ||
109 | 110 | ||
110 | if (!access_ok(VERIFY_WRITE, data, 33 * 8)) | 111 | if (!access_ok(VERIFY_WRITE, data, 33 * 8)) |
111 | return -EIO; | 112 | return -EIO; |
@@ -121,10 +122,10 @@ int ptrace_getfpregs (struct task_struct *child, __u32 __user *data) | |||
121 | 122 | ||
122 | __put_user (child->thread.fpu.fcr31, data + 64); | 123 | __put_user (child->thread.fpu.fcr31, data + 64); |
123 | 124 | ||
125 | preempt_disable(); | ||
124 | if (cpu_has_fpu) { | 126 | if (cpu_has_fpu) { |
125 | unsigned int flags, tmp; | 127 | unsigned int flags; |
126 | 128 | ||
127 | preempt_disable(); | ||
128 | if (cpu_has_mipsmt) { | 129 | if (cpu_has_mipsmt) { |
129 | unsigned int vpflags = dvpe(); | 130 | unsigned int vpflags = dvpe(); |
130 | flags = read_c0_status(); | 131 | flags = read_c0_status(); |
@@ -138,11 +139,11 @@ int ptrace_getfpregs (struct task_struct *child, __u32 __user *data) | |||
138 | __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp)); | 139 | __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp)); |
139 | write_c0_status(flags); | 140 | write_c0_status(flags); |
140 | } | 141 | } |
141 | preempt_enable(); | ||
142 | __put_user (tmp, data + 65); | ||
143 | } else { | 142 | } else { |
144 | __put_user ((__u32) 0, data + 65); | 143 | tmp = 0; |
145 | } | 144 | } |
145 | preempt_enable(); | ||
146 | __put_user (tmp, data + 65); | ||
146 | 147 | ||
147 | return 0; | 148 | return 0; |
148 | } | 149 | } |
@@ -245,16 +246,17 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
245 | unsigned int mtflags; | 246 | unsigned int mtflags; |
246 | #endif /* CONFIG_MIPS_MT_SMTC */ | 247 | #endif /* CONFIG_MIPS_MT_SMTC */ |
247 | 248 | ||
248 | if (!cpu_has_fpu) | 249 | preempt_disable(); |
250 | if (!cpu_has_fpu) { | ||
251 | preempt_enable(); | ||
249 | break; | 252 | break; |
253 | } | ||
250 | 254 | ||
251 | #ifdef CONFIG_MIPS_MT_SMTC | 255 | #ifdef CONFIG_MIPS_MT_SMTC |
252 | /* Read-modify-write of Status must be atomic */ | 256 | /* Read-modify-write of Status must be atomic */ |
253 | local_irq_save(irqflags); | 257 | local_irq_save(irqflags); |
254 | mtflags = dmt(); | 258 | mtflags = dmt(); |
255 | #endif /* CONFIG_MIPS_MT_SMTC */ | 259 | #endif /* CONFIG_MIPS_MT_SMTC */ |
256 | |||
257 | preempt_disable(); | ||
258 | if (cpu_has_mipsmt) { | 260 | if (cpu_has_mipsmt) { |
259 | unsigned int vpflags = dvpe(); | 261 | unsigned int vpflags = dvpe(); |
260 | flags = read_c0_status(); | 262 | flags = read_c0_status(); |
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c index f40ecd8be05f..d9a39c169450 100644 --- a/arch/mips/kernel/ptrace32.c +++ b/arch/mips/kernel/ptrace32.c | |||
@@ -175,7 +175,9 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) | |||
175 | unsigned int mtflags; | 175 | unsigned int mtflags; |
176 | #endif /* CONFIG_MIPS_MT_SMTC */ | 176 | #endif /* CONFIG_MIPS_MT_SMTC */ |
177 | 177 | ||
178 | preempt_disable(); | ||
178 | if (!cpu_has_fpu) { | 179 | if (!cpu_has_fpu) { |
180 | preempt_enable(); | ||
179 | tmp = 0; | 181 | tmp = 0; |
180 | break; | 182 | break; |
181 | } | 183 | } |
@@ -186,7 +188,6 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) | |||
186 | mtflags = dmt(); | 188 | mtflags = dmt(); |
187 | #endif /* CONFIG_MIPS_MT_SMTC */ | 189 | #endif /* CONFIG_MIPS_MT_SMTC */ |
188 | 190 | ||
189 | preempt_disable(); | ||
190 | if (cpu_has_mipsmt) { | 191 | if (cpu_has_mipsmt) { |
191 | unsigned int vpflags = dvpe(); | 192 | unsigned int vpflags = dvpe(); |
192 | flags = read_c0_status(); | 193 | flags = read_c0_status(); |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index b7292a56d4cd..cce8313ec27d 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -66,7 +66,7 @@ extern asmlinkage void handle_mcheck(void); | |||
66 | extern asmlinkage void handle_reserved(void); | 66 | extern asmlinkage void handle_reserved(void); |
67 | 67 | ||
68 | extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, | 68 | extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, |
69 | struct mips_fpu_struct *ctx); | 69 | struct mips_fpu_struct *ctx, int has_fpu); |
70 | 70 | ||
71 | void (*board_be_init)(void); | 71 | void (*board_be_init)(void); |
72 | int (*board_be_handler)(struct pt_regs *regs, int is_fixup); | 72 | int (*board_be_handler)(struct pt_regs *regs, int is_fixup); |
@@ -641,7 +641,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) | |||
641 | preempt_enable(); | 641 | preempt_enable(); |
642 | 642 | ||
643 | /* Run the emulator */ | 643 | /* Run the emulator */ |
644 | sig = fpu_emulator_cop1Handler (regs, ¤t->thread.fpu); | 644 | sig = fpu_emulator_cop1Handler (regs, ¤t->thread.fpu, 1); |
645 | 645 | ||
646 | preempt_disable(); | 646 | preempt_disable(); |
647 | 647 | ||
@@ -791,11 +791,13 @@ asmlinkage void do_cpu(struct pt_regs *regs) | |||
791 | set_used_math(); | 791 | set_used_math(); |
792 | } | 792 | } |
793 | 793 | ||
794 | preempt_enable(); | 794 | if (cpu_has_fpu) { |
795 | 795 | preempt_enable(); | |
796 | if (!cpu_has_fpu) { | 796 | } else { |
797 | int sig = fpu_emulator_cop1Handler(regs, | 797 | int sig; |
798 | ¤t->thread.fpu); | 798 | preempt_enable(); |
799 | sig = fpu_emulator_cop1Handler(regs, | ||
800 | ¤t->thread.fpu, 0); | ||
799 | if (sig) | 801 | if (sig) |
800 | force_sig(sig, current); | 802 | force_sig(sig, current); |
801 | #ifdef CONFIG_MIPS_MT_FPAFF | 803 | #ifdef CONFIG_MIPS_MT_FPAFF |
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index 3f0d5d26d506..80531b35cd61 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c | |||
@@ -38,8 +38,6 @@ | |||
38 | 38 | ||
39 | #include <asm/inst.h> | 39 | #include <asm/inst.h> |
40 | #include <asm/bootinfo.h> | 40 | #include <asm/bootinfo.h> |
41 | #include <asm/cpu.h> | ||
42 | #include <asm/cpu-features.h> | ||
43 | #include <asm/processor.h> | 41 | #include <asm/processor.h> |
44 | #include <asm/ptrace.h> | 42 | #include <asm/ptrace.h> |
45 | #include <asm/signal.h> | 43 | #include <asm/signal.h> |
@@ -1233,7 +1231,8 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
1233 | return 0; | 1231 | return 0; |
1234 | } | 1232 | } |
1235 | 1233 | ||
1236 | int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | 1234 | int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, |
1235 | int has_fpu) | ||
1237 | { | 1236 | { |
1238 | unsigned long oldepc, prevepc; | 1237 | unsigned long oldepc, prevepc; |
1239 | mips_instruction insn; | 1238 | mips_instruction insn; |
@@ -1263,7 +1262,7 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
1263 | ieee754_csr.rm = mips_rm[ieee754_csr.rm]; | 1262 | ieee754_csr.rm = mips_rm[ieee754_csr.rm]; |
1264 | } | 1263 | } |
1265 | 1264 | ||
1266 | if (cpu_has_fpu) | 1265 | if (has_fpu) |
1267 | break; | 1266 | break; |
1268 | if (sig) | 1267 | if (sig) |
1269 | break; | 1268 | break; |