aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/signal_32.c
diff options
context:
space:
mode:
authorSuresh Siddha <suresh.b.siddha@intel.com>2008-07-29 13:29:21 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-30 13:49:25 -0400
commit3c1c7f101426cb2ecc79d817a8a65928965fc860 (patch)
tree55a2b7c5ccb28ea38bf82f7d799447980e2126c7 /arch/x86/kernel/signal_32.c
parentb359e8a434cc3d09847010fc4aeccf48d69740e4 (diff)
x86, xsave: dynamically allocate sigframes fpstate instead of static allocation
dynamically allocate fpstate on the stack, instead of static allocation in the current sigframe layout on the user stack. This will allow the fpstate structure to grow in the future, which includes extended state information supporting xsave/xrstor. signal handlers will be able to access the fpstate pointer from the sigcontext structure asusual, with no change. For the non RT sigframe's (which are supported only for 32bit apps), current static fpstate layout in the sigframe will be unused(so that we don't change the extramask[] offset in the sigframe and thus prevent breaking app's which modify extramask[]). 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.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)