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/ia32 | |
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/ia32')
-rw-r--r-- | arch/x86/ia32/ia32_signal.c | 28 |
1 files changed, 7 insertions, 21 deletions
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index a05bf0fb7415..c596eabbe98b 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c | |||
@@ -216,7 +216,7 @@ static int ia32_restore_sigcontext(struct pt_regs *regs, | |||
216 | unsigned int *peax) | 216 | unsigned int *peax) |
217 | { | 217 | { |
218 | unsigned int tmpflags, gs, oldgs, err = 0; | 218 | unsigned int tmpflags, gs, oldgs, err = 0; |
219 | struct _fpstate_ia32 __user *buf; | 219 | void __user *buf; |
220 | u32 tmp; | 220 | u32 tmp; |
221 | 221 | ||
222 | /* Always make any pending restarted system calls return -EINTR */ | 222 | /* Always make any pending restarted system calls return -EINTR */ |
@@ -260,26 +260,12 @@ static int ia32_restore_sigcontext(struct pt_regs *regs, | |||
260 | 260 | ||
261 | err |= __get_user(tmp, &sc->fpstate); | 261 | err |= __get_user(tmp, &sc->fpstate); |
262 | buf = compat_ptr(tmp); | 262 | buf = compat_ptr(tmp); |
263 | if (buf) { | 263 | err |= restore_i387_xstate_ia32(buf); |
264 | if (!access_ok(VERIFY_READ, buf, sizeof(*buf))) | ||
265 | goto badframe; | ||
266 | err |= restore_i387_ia32(buf); | ||
267 | } else { | ||
268 | struct task_struct *me = current; | ||
269 | |||
270 | if (used_math()) { | ||
271 | clear_fpu(me); | ||
272 | clear_used_math(); | ||
273 | } | ||
274 | } | ||
275 | 264 | ||
276 | err |= __get_user(tmp, &sc->ax); | 265 | err |= __get_user(tmp, &sc->ax); |
277 | *peax = tmp; | 266 | *peax = tmp; |
278 | 267 | ||
279 | return err; | 268 | return err; |
280 | |||
281 | badframe: | ||
282 | return 1; | ||
283 | } | 269 | } |
284 | 270 | ||
285 | asmlinkage long sys32_sigreturn(struct pt_regs *regs) | 271 | asmlinkage long sys32_sigreturn(struct pt_regs *regs) |
@@ -351,7 +337,7 @@ badframe: | |||
351 | */ | 337 | */ |
352 | 338 | ||
353 | static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, | 339 | static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, |
354 | struct _fpstate_ia32 __user *fpstate, | 340 | void __user *fpstate, |
355 | struct pt_regs *regs, unsigned int mask) | 341 | struct pt_regs *regs, unsigned int mask) |
356 | { | 342 | { |
357 | int tmp, err = 0; | 343 | int tmp, err = 0; |
@@ -382,7 +368,7 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, | |||
382 | err |= __put_user((u32)regs->flags, &sc->flags); | 368 | err |= __put_user((u32)regs->flags, &sc->flags); |
383 | err |= __put_user((u32)regs->sp, &sc->sp_at_signal); | 369 | err |= __put_user((u32)regs->sp, &sc->sp_at_signal); |
384 | 370 | ||
385 | tmp = save_i387_ia32(fpstate); | 371 | tmp = save_i387_xstate_ia32(fpstate); |
386 | if (tmp < 0) | 372 | if (tmp < 0) |
387 | err = -EFAULT; | 373 | err = -EFAULT; |
388 | else { | 374 | else { |
@@ -404,7 +390,7 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, | |||
404 | */ | 390 | */ |
405 | static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, | 391 | static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, |
406 | size_t frame_size, | 392 | size_t frame_size, |
407 | struct _fpstate_ia32 **fpstate) | 393 | void **fpstate) |
408 | { | 394 | { |
409 | unsigned long sp; | 395 | unsigned long sp; |
410 | 396 | ||
@@ -441,7 +427,7 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, | |||
441 | struct sigframe __user *frame; | 427 | struct sigframe __user *frame; |
442 | void __user *restorer; | 428 | void __user *restorer; |
443 | int err = 0; | 429 | int err = 0; |
444 | struct _fpstate_ia32 __user *fpstate = NULL; | 430 | void __user *fpstate = NULL; |
445 | 431 | ||
446 | /* copy_to_user optimizes that into a single 8 byte store */ | 432 | /* copy_to_user optimizes that into a single 8 byte store */ |
447 | static const struct { | 433 | static const struct { |
@@ -529,7 +515,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
529 | struct rt_sigframe __user *frame; | 515 | struct rt_sigframe __user *frame; |
530 | void __user *restorer; | 516 | void __user *restorer; |
531 | int err = 0; | 517 | int err = 0; |
532 | struct _fpstate_ia32 __user *fpstate = NULL; | 518 | void __user *fpstate = NULL; |
533 | 519 | ||
534 | /* __copy_to_user optimizes that into a single 8 byte store */ | 520 | /* __copy_to_user optimizes that into a single 8 byte store */ |
535 | static const struct { | 521 | static const struct { |