aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/signal_32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/signal_32.c')
-rw-r--r--arch/x86/kernel/signal_32.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
index 6fb5bcdd8933..19a7a5669b5b 100644
--- a/arch/x86/kernel/signal_32.c
+++ b/arch/x86/kernel/signal_32.c
@@ -306,7 +306,8 @@ setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate,
306 * Determine which stack to use.. 306 * Determine which stack to use..
307 */ 307 */
308static inline void __user * 308static inline void __user *
309get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) 309get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
310 struct _fpstate **fpstate)
310{ 311{
311 unsigned long sp; 312 unsigned long sp;
312 313
@@ -332,6 +333,11 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
332 sp = (unsigned long) ka->sa.sa_restorer; 333 sp = (unsigned long) ka->sa.sa_restorer;
333 } 334 }
334 335
336 if (used_math()) {
337 sp = sp - sig_xstate_size;
338 *fpstate = (struct _fpstate *) sp;
339 }
340
335 sp -= frame_size; 341 sp -= frame_size;
336 /* 342 /*
337 * Align the stack pointer according to the i386 ABI, 343 * Align the stack pointer according to the i386 ABI,
@@ -350,8 +356,9 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
350 void __user *restorer; 356 void __user *restorer;
351 int err = 0; 357 int err = 0;
352 int usig; 358 int usig;
359 struct _fpstate __user *fpstate = NULL;
353 360
354 frame = get_sigframe(ka, regs, sizeof(*frame)); 361 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
355 362
356 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 363 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
357 goto give_sigsegv; 364 goto give_sigsegv;
@@ -366,7 +373,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
366 if (err) 373 if (err)
367 goto give_sigsegv; 374 goto give_sigsegv;
368 375
369 err = setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]); 376 err = setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]);
370 if (err) 377 if (err)
371 goto give_sigsegv; 378 goto give_sigsegv;
372 379
@@ -427,8 +434,9 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
427 void __user *restorer; 434 void __user *restorer;
428 int err = 0; 435 int err = 0;
429 int usig; 436 int usig;
437 struct _fpstate __user *fpstate = NULL;
430 438
431 frame = get_sigframe(ka, regs, sizeof(*frame)); 439 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
432 440
433 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 441 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
434 goto give_sigsegv; 442 goto give_sigsegv;
@@ -453,7 +461,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
453 err |= __put_user(sas_ss_flags(regs->sp), 461 err |= __put_user(sas_ss_flags(regs->sp),
454 &frame->uc.uc_stack.ss_flags); 462 &frame->uc.uc_stack.ss_flags);
455 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 463 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
456 err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate, 464 err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
457 regs, set->sig[0]); 465 regs, set->sig[0]);
458 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 466 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
459 if (err) 467 if (err)