diff options
author | Suresh Siddha <suresh.b.siddha@intel.com> | 2008-07-29 13:29:22 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-30 13:49:26 -0400 |
commit | ab5137015fed9b948fe835a2d99a4cfbd50a0c40 (patch) | |
tree | 229771c4f5606d56945941c8ada9ae6cf08d1c80 /arch/x86/kernel/signal_32.c | |
parent | 3c1c7f101426cb2ecc79d817a8a65928965fc860 (diff) |
x86, xsave: reorganization of signal save/restore fpstate code layout
move 64bit routines that saves/restores fpstate in/from user stack from
signal_64.c to xsave.c
restore_i387_xstate() now handles the condition when user passes
NULL fpstate.
Other misc changes for prepartion of xsave/xrstor sigcontext support.
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/signal_32.c')
-rw-r--r-- | arch/x86/kernel/signal_32.c | 28 |
1 files changed, 7 insertions, 21 deletions
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c index 19a7a5669b5b..690cc616ac07 100644 --- a/arch/x86/kernel/signal_32.c +++ b/arch/x86/kernel/signal_32.c | |||
@@ -159,28 +159,14 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, | |||
159 | } | 159 | } |
160 | 160 | ||
161 | { | 161 | { |
162 | struct _fpstate __user *buf; | 162 | void __user *buf; |
163 | 163 | ||
164 | err |= __get_user(buf, &sc->fpstate); | 164 | err |= __get_user(buf, &sc->fpstate); |
165 | if (buf) { | 165 | err |= restore_i387_xstate(buf); |
166 | if (!access_ok(VERIFY_READ, buf, sizeof(*buf))) | ||
167 | goto badframe; | ||
168 | err |= restore_i387(buf); | ||
169 | } else { | ||
170 | struct task_struct *me = current; | ||
171 | |||
172 | if (used_math()) { | ||
173 | clear_fpu(me); | ||
174 | clear_used_math(); | ||
175 | } | ||
176 | } | ||
177 | } | 166 | } |
178 | 167 | ||
179 | err |= __get_user(*pax, &sc->ax); | 168 | err |= __get_user(*pax, &sc->ax); |
180 | return err; | 169 | return err; |
181 | |||
182 | badframe: | ||
183 | return 1; | ||
184 | } | 170 | } |
185 | 171 | ||
186 | asmlinkage unsigned long sys_sigreturn(unsigned long __unused) | 172 | asmlinkage unsigned long sys_sigreturn(unsigned long __unused) |
@@ -262,7 +248,7 @@ badframe: | |||
262 | * Set up a signal frame. | 248 | * Set up a signal frame. |
263 | */ | 249 | */ |
264 | static int | 250 | static int |
265 | setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate, | 251 | setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate, |
266 | struct pt_regs *regs, unsigned long mask) | 252 | struct pt_regs *regs, unsigned long mask) |
267 | { | 253 | { |
268 | int tmp, err = 0; | 254 | int tmp, err = 0; |
@@ -289,7 +275,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate, | |||
289 | err |= __put_user(regs->sp, &sc->sp_at_signal); | 275 | err |= __put_user(regs->sp, &sc->sp_at_signal); |
290 | err |= __put_user(regs->ss, (unsigned int __user *)&sc->ss); | 276 | err |= __put_user(regs->ss, (unsigned int __user *)&sc->ss); |
291 | 277 | ||
292 | tmp = save_i387(fpstate); | 278 | tmp = save_i387_xstate(fpstate); |
293 | if (tmp < 0) | 279 | if (tmp < 0) |
294 | err = 1; | 280 | err = 1; |
295 | else | 281 | else |
@@ -307,7 +293,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate, | |||
307 | */ | 293 | */ |
308 | static inline void __user * | 294 | static inline void __user * |
309 | get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, | 295 | get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, |
310 | struct _fpstate **fpstate) | 296 | void **fpstate) |
311 | { | 297 | { |
312 | unsigned long sp; | 298 | unsigned long sp; |
313 | 299 | ||
@@ -356,7 +342,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
356 | void __user *restorer; | 342 | void __user *restorer; |
357 | int err = 0; | 343 | int err = 0; |
358 | int usig; | 344 | int usig; |
359 | struct _fpstate __user *fpstate = NULL; | 345 | void __user *fpstate = NULL; |
360 | 346 | ||
361 | frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); | 347 | frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); |
362 | 348 | ||
@@ -434,7 +420,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
434 | void __user *restorer; | 420 | void __user *restorer; |
435 | int err = 0; | 421 | int err = 0; |
436 | int usig; | 422 | int usig; |
437 | struct _fpstate __user *fpstate = NULL; | 423 | void __user *fpstate = NULL; |
438 | 424 | ||
439 | frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); | 425 | frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); |
440 | 426 | ||