diff options
author | Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 2007-03-09 11:07:45 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2007-03-16 21:03:26 -0400 |
commit | 53dc80287da43b75df2fe2658651d3c5160dad8e (patch) | |
tree | 3c4c97534c379709cd2a1dae5b90df626349f21d /arch/mips/kernel/signal.c | |
parent | c6a2f4679331206ef5d353fc9a6cda2fa4aef8c6 (diff) |
[MIPS] FPU ownership management & preemption fixes
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/signal.c')
-rw-r--r-- | arch/mips/kernel/signal.c | 29 |
1 files changed, 12 insertions, 17 deletions
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index bf094fc4c7eb..8c3c5a5789b0 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c | |||
@@ -82,6 +82,7 @@ int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) | |||
82 | { | 82 | { |
83 | int err = 0; | 83 | int err = 0; |
84 | int i; | 84 | int i; |
85 | unsigned int used_math; | ||
85 | 86 | ||
86 | err |= __put_user(regs->cp0_epc, &sc->sc_pc); | 87 | err |= __put_user(regs->cp0_epc, &sc->sc_pc); |
87 | 88 | ||
@@ -104,22 +105,18 @@ int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) | |||
104 | err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp); | 105 | err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp); |
105 | } | 106 | } |
106 | 107 | ||
107 | err |= __put_user(!!used_math(), &sc->sc_used_math); | 108 | used_math = !!used_math(); |
109 | err |= __put_user(used_math, &sc->sc_used_math); | ||
108 | 110 | ||
109 | if (used_math()) { | 111 | if (used_math) { |
110 | /* | 112 | /* |
111 | * Save FPU state to signal context. Signal handler | 113 | * Save FPU state to signal context. Signal handler |
112 | * will "inherit" current FPU state. | 114 | * will "inherit" current FPU state. |
113 | */ | 115 | */ |
114 | preempt_disable(); | 116 | own_fpu(1); |
115 | 117 | enable_fp_in_kernel(); | |
116 | if (!is_fpu_owner()) { | ||
117 | own_fpu(); | ||
118 | restore_fp(current); | ||
119 | } | ||
120 | err |= save_fp_context(sc); | 118 | err |= save_fp_context(sc); |
121 | 119 | disable_fp_in_kernel(); | |
122 | preempt_enable(); | ||
123 | } | 120 | } |
124 | return err; | 121 | return err; |
125 | } | 122 | } |
@@ -188,20 +185,18 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) | |||
188 | err |= __get_user(used_math, &sc->sc_used_math); | 185 | err |= __get_user(used_math, &sc->sc_used_math); |
189 | conditional_used_math(used_math); | 186 | conditional_used_math(used_math); |
190 | 187 | ||
191 | preempt_disable(); | 188 | if (used_math) { |
192 | |||
193 | if (used_math()) { | ||
194 | /* restore fpu context if we have used it before */ | 189 | /* restore fpu context if we have used it before */ |
195 | own_fpu(); | 190 | own_fpu(0); |
191 | enable_fp_in_kernel(); | ||
196 | if (!err) | 192 | if (!err) |
197 | err = check_and_restore_fp_context(sc); | 193 | err = check_and_restore_fp_context(sc); |
194 | disable_fp_in_kernel(); | ||
198 | } else { | 195 | } else { |
199 | /* signal handler may have used FPU. Give it up. */ | 196 | /* signal handler may have used FPU. Give it up. */ |
200 | lose_fpu(); | 197 | lose_fpu(0); |
201 | } | 198 | } |
202 | 199 | ||
203 | preempt_enable(); | ||
204 | |||
205 | return err; | 200 | return err; |
206 | } | 201 | } |
207 | 202 | ||