aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/ia32
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/ia32
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/ia32')
-rw-r--r--arch/x86/ia32/ia32_signal.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index 20af4c79579a..a05bf0fb7415 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -179,9 +179,10 @@ struct sigframe
179 u32 pretcode; 179 u32 pretcode;
180 int sig; 180 int sig;
181 struct sigcontext_ia32 sc; 181 struct sigcontext_ia32 sc;
182 struct _fpstate_ia32 fpstate; 182 struct _fpstate_ia32 fpstate_unused; /* look at kernel/sigframe.h */
183 unsigned int extramask[_COMPAT_NSIG_WORDS-1]; 183 unsigned int extramask[_COMPAT_NSIG_WORDS-1];
184 char retcode[8]; 184 char retcode[8];
185 /* fp state follows here */
185}; 186};
186 187
187struct rt_sigframe 188struct rt_sigframe
@@ -192,8 +193,8 @@ struct rt_sigframe
192 u32 puc; 193 u32 puc;
193 compat_siginfo_t info; 194 compat_siginfo_t info;
194 struct ucontext_ia32 uc; 195 struct ucontext_ia32 uc;
195 struct _fpstate_ia32 fpstate;
196 char retcode[8]; 196 char retcode[8];
197 /* fp state follows here */
197}; 198};
198 199
199#define COPY(x) { \ 200#define COPY(x) { \
@@ -402,7 +403,8 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
402 * Determine which stack to use.. 403 * Determine which stack to use..
403 */ 404 */
404static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, 405static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
405 size_t frame_size) 406 size_t frame_size,
407 struct _fpstate_ia32 **fpstate)
406{ 408{
407 unsigned long sp; 409 unsigned long sp;
408 410
@@ -421,6 +423,11 @@ static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
421 ka->sa.sa_restorer) 423 ka->sa.sa_restorer)
422 sp = (unsigned long) ka->sa.sa_restorer; 424 sp = (unsigned long) ka->sa.sa_restorer;
423 425
426 if (used_math()) {
427 sp = sp - sig_xstate_ia32_size;
428 *fpstate = (struct _fpstate_ia32 *) sp;
429 }
430
424 sp -= frame_size; 431 sp -= frame_size;
425 /* Align the stack pointer according to the i386 ABI, 432 /* Align the stack pointer according to the i386 ABI,
426 * i.e. so that on function entry ((sp + 4) & 15) == 0. */ 433 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
@@ -434,6 +441,7 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
434 struct sigframe __user *frame; 441 struct sigframe __user *frame;
435 void __user *restorer; 442 void __user *restorer;
436 int err = 0; 443 int err = 0;
444 struct _fpstate_ia32 __user *fpstate = NULL;
437 445
438 /* copy_to_user optimizes that into a single 8 byte store */ 446 /* copy_to_user optimizes that into a single 8 byte store */
439 static const struct { 447 static const struct {
@@ -448,7 +456,7 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
448 0, 456 0,
449 }; 457 };
450 458
451 frame = get_sigframe(ka, regs, sizeof(*frame)); 459 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
452 460
453 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 461 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
454 goto give_sigsegv; 462 goto give_sigsegv;
@@ -457,8 +465,7 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
457 if (err) 465 if (err)
458 goto give_sigsegv; 466 goto give_sigsegv;
459 467
460 err |= ia32_setup_sigcontext(&frame->sc, &frame->fpstate, regs, 468 err |= ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]);
461 set->sig[0]);
462 if (err) 469 if (err)
463 goto give_sigsegv; 470 goto give_sigsegv;
464 471
@@ -522,6 +529,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
522 struct rt_sigframe __user *frame; 529 struct rt_sigframe __user *frame;
523 void __user *restorer; 530 void __user *restorer;
524 int err = 0; 531 int err = 0;
532 struct _fpstate_ia32 __user *fpstate = NULL;
525 533
526 /* __copy_to_user optimizes that into a single 8 byte store */ 534 /* __copy_to_user optimizes that into a single 8 byte store */
527 static const struct { 535 static const struct {
@@ -537,7 +545,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
537 0, 545 0,
538 }; 546 };
539 547
540 frame = get_sigframe(ka, regs, sizeof(*frame)); 548 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
541 549
542 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 550 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
543 goto give_sigsegv; 551 goto give_sigsegv;
@@ -556,7 +564,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
556 err |= __put_user(sas_ss_flags(regs->sp), 564 err |= __put_user(sas_ss_flags(regs->sp),
557 &frame->uc.uc_stack.ss_flags); 565 &frame->uc.uc_stack.ss_flags);
558 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 566 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
559 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate, 567 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
560 regs, set->sig[0]); 568 regs, set->sig[0]);
561 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 569 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
562 if (err) 570 if (err)