aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorHiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>2009-02-27 13:28:48 -0500
committerIngo Molnar <mingo@elte.hu>2009-02-28 03:17:29 -0500
commit97286a2b64725aac2d584ddd1f94871f9991d5a1 (patch)
tree0fd7a0b776647d2619099e76f56c8ca4d76bc4e5 /arch
parent144b0712dd9dd9ebd4e80c4e5388c9f6afc2b497 (diff)
x86: signal: intrroduce get_sigframe() and replace get_sigstack()
Impact: cleanup Introduce get_sigframe() like 32-bit to replace get_sigstack(). Move the i387 stuff into get_sigframe(). Signed-off-by: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/signal.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index e89eaf417e55..82d37c77b0fb 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -392,10 +392,13 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
392 * Determine which stack to use.. 392 * Determine which stack to use..
393 */ 393 */
394static void __user * 394static void __user *
395get_stack(struct k_sigaction *ka, unsigned long sp, unsigned long size) 395get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
396 void __user **fpstate)
396{ 397{
397 /* Default to using normal stack - redzone*/ 398 unsigned long sp;
398 sp -= 128; 399
400 /* Default to using normal stack - redzone */
401 sp = regs->sp - 128;
399 402
400 /* This is the X/Open sanctioned signal stack switching. */ 403 /* This is the X/Open sanctioned signal stack switching. */
401 if (ka->sa.sa_flags & SA_ONSTACK) { 404 if (ka->sa.sa_flags & SA_ONSTACK) {
@@ -403,7 +406,18 @@ get_stack(struct k_sigaction *ka, unsigned long sp, unsigned long size)
403 sp = current->sas_ss_sp + current->sas_ss_size; 406 sp = current->sas_ss_sp + current->sas_ss_size;
404 } 407 }
405 408
406 return (void __user *)round_down(sp - size, 64); 409 if (used_math()) {
410 sp -= sig_xstate_size;
411 *fpstate = (void __user *)round_down(sp, 64);
412 if (save_i387_xstate(*fpstate) < 0)
413 return (void __user *) -1L;
414
415 sp -= frame_size;
416 return (void __user *)round_down(sp, 16) - 8;
417 }
418
419 sp -= frame_size;
420 return (void __user *)round_down(sp, 64) - 8;
407} 421}
408 422
409static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 423static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
@@ -414,15 +428,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
414 int err = 0; 428 int err = 0;
415 struct task_struct *me = current; 429 struct task_struct *me = current;
416 430
417 if (used_math()) { 431 frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe), &fp);
418 fp = get_stack(ka, regs->sp, sig_xstate_size);
419 frame = (void __user *)round_down(
420 (unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8;
421
422 if (save_i387_xstate(fp) < 0)
423 return -EFAULT;
424 } else
425 frame = get_stack(ka, regs->sp, sizeof(struct rt_sigframe)) - 8;
426 432
427 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 433 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
428 return -EFAULT; 434 return -EFAULT;