aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorHiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>2008-11-24 21:23:12 -0500
committerIngo Molnar <mingo@elte.hu>2008-11-25 23:11:53 -0500
commitbfeb91a9435889ef4fe7bfbb4b673f625e69e790 (patch)
tree904f16d0eba56b7812b1462de6bc28df6c70371f /arch
parent2601657d223d82053d4e1fe1063091401e6b860a (diff)
x86: signal: cosmetic unification of __setup_sigframe() and __setup_rt_sigframe()
Impact: cleanup Add #ifdef directive to unify __setup_sigframe() and __setup_rt_sigframe(). Move them after {setup|restore}_sigcontext() declaration. 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_32.c469
-rw-r--r--arch/x86/kernel/signal_64.c309
2 files changed, 536 insertions, 242 deletions
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
index b3f30d2a2178..e9f71298e746 100644
--- a/arch/x86/kernel/signal_32.c
+++ b/arch/x86/kernel/signal_32.c
@@ -48,28 +48,6 @@
48# define FIX_EFLAGS __FIX_EFLAGS 48# define FIX_EFLAGS __FIX_EFLAGS
49#endif 49#endif
50 50
51static const struct {
52 u16 poplmovl;
53 u32 val;
54 u16 int80;
55} __attribute__((packed)) retcode = {
56 0xb858, /* popl %eax; movl $..., %eax */
57 __NR_sigreturn,
58 0x80cd, /* int $0x80 */
59};
60
61static const struct {
62 u8 movl;
63 u32 val;
64 u16 int80;
65 u8 pad;
66} __attribute__((packed)) rt_retcode = {
67 0xb8, /* movl $..., %eax */
68 __NR_rt_sigreturn,
69 0x80cd, /* int $0x80 */
70 0
71};
72
73#define COPY(x) { \ 51#define COPY(x) { \
74 err |= __get_user(regs->x, &sc->x); \ 52 err |= __get_user(regs->x, &sc->x); \
75} 53}
@@ -207,176 +185,30 @@ setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
207} 185}
208 186
209/* 187/*
210 * Atomically swap in the new signal mask, and wait for a signal. 188 * Set up a signal frame.
211 */ 189 */
212asmlinkage int
213sys_sigsuspend(int history0, int history1, old_sigset_t mask)
214{
215 mask &= _BLOCKABLE;
216 spin_lock_irq(&current->sighand->siglock);
217 current->saved_sigmask = current->blocked;
218 siginitset(&current->blocked, mask);
219 recalc_sigpending();
220 spin_unlock_irq(&current->sighand->siglock);
221
222 current->state = TASK_INTERRUPTIBLE;
223 schedule();
224 set_restore_sigmask();
225
226 return -ERESTARTNOHAND;
227}
228
229asmlinkage int
230sys_sigaction(int sig, const struct old_sigaction __user *act,
231 struct old_sigaction __user *oact)
232{
233 struct k_sigaction new_ka, old_ka;
234 int ret;
235
236 if (act) {
237 old_sigset_t mask;
238
239 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
240 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
241 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
242 return -EFAULT;
243
244 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
245 __get_user(mask, &act->sa_mask);
246 siginitset(&new_ka.sa.sa_mask, mask);
247 }
248
249 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
250
251 if (!ret && oact) {
252 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
253 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
254 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
255 return -EFAULT;
256
257 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
258 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
259 }
260
261 return ret;
262}
263
264#ifdef CONFIG_X86_32 190#ifdef CONFIG_X86_32
265asmlinkage int sys_sigaltstack(unsigned long bx) 191static const struct {
266{ 192 u16 poplmovl;
267 /* 193 u32 val;
268 * This is needed to make gcc realize it doesn't own the 194 u16 int80;
269 * "struct pt_regs" 195} __attribute__((packed)) retcode = {
270 */ 196 0xb858, /* popl %eax; movl $..., %eax */
271 struct pt_regs *regs = (struct pt_regs *)&bx; 197 __NR_sigreturn,
272 const stack_t __user *uss = (const stack_t __user *)bx; 198 0x80cd, /* int $0x80 */
273 stack_t __user *uoss = (stack_t __user *)regs->cx; 199};
274
275 return do_sigaltstack(uss, uoss, regs->sp);
276}
277#else /* !CONFIG_X86_32 */
278asmlinkage long
279sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
280 struct pt_regs *regs)
281{
282 return do_sigaltstack(uss, uoss, regs->sp);
283}
284#endif /* CONFIG_X86_32 */
285
286/*
287 * Do a signal return; undo the signal stack.
288 */
289asmlinkage unsigned long sys_sigreturn(unsigned long __unused)
290{
291 struct sigframe __user *frame;
292 struct pt_regs *regs;
293 unsigned long ax;
294 sigset_t set;
295
296 regs = (struct pt_regs *) &__unused;
297 frame = (struct sigframe __user *)(regs->sp - 8);
298
299 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
300 goto badframe;
301 if (__get_user(set.sig[0], &frame->sc.oldmask) || (_NSIG_WORDS > 1
302 && __copy_from_user(&set.sig[1], &frame->extramask,
303 sizeof(frame->extramask))))
304 goto badframe;
305
306 sigdelsetmask(&set, ~_BLOCKABLE);
307 spin_lock_irq(&current->sighand->siglock);
308 current->blocked = set;
309 recalc_sigpending();
310 spin_unlock_irq(&current->sighand->siglock);
311
312 if (restore_sigcontext(regs, &frame->sc, &ax))
313 goto badframe;
314 return ax;
315
316badframe:
317 if (show_unhandled_signals && printk_ratelimit()) {
318 printk("%s%s[%d] bad frame in sigreturn frame:"
319 "%p ip:%lx sp:%lx oeax:%lx",
320 task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG,
321 current->comm, task_pid_nr(current), frame, regs->ip,
322 regs->sp, regs->orig_ax);
323 print_vma_addr(" in ", regs->ip);
324 printk(KERN_CONT "\n");
325 }
326
327 force_sig(SIGSEGV, current);
328
329 return 0;
330}
331
332static long do_rt_sigreturn(struct pt_regs *regs)
333{
334 struct rt_sigframe __user *frame;
335 unsigned long ax;
336 sigset_t set;
337
338 frame = (struct rt_sigframe __user *)(regs->sp - sizeof(long));
339 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
340 goto badframe;
341 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
342 goto badframe;
343
344 sigdelsetmask(&set, ~_BLOCKABLE);
345 spin_lock_irq(&current->sighand->siglock);
346 current->blocked = set;
347 recalc_sigpending();
348 spin_unlock_irq(&current->sighand->siglock);
349
350 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
351 goto badframe;
352
353 if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
354 goto badframe;
355
356 return ax;
357
358badframe:
359 signal_fault(regs, frame, "rt_sigreturn");
360 return 0;
361}
362
363#ifdef CONFIG_X86_32
364asmlinkage int sys_rt_sigreturn(unsigned long __unused)
365{
366 struct pt_regs *regs = (struct pt_regs *)&__unused;
367
368 return do_rt_sigreturn(regs);
369}
370#else /* !CONFIG_X86_32 */
371asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
372{
373 return do_rt_sigreturn(regs);
374}
375#endif /* CONFIG_X86_32 */
376 200
377/* 201static const struct {
378 * Set up a signal frame. 202 u8 movl;
379 */ 203 u32 val;
204 u16 int80;
205 u8 pad;
206} __attribute__((packed)) rt_retcode = {
207 0xb8, /* movl $..., %eax */
208 __NR_rt_sigreturn,
209 0x80cd, /* int $0x80 */
210 0
211};
380 212
381/* 213/*
382 * Determine which stack to use.. 214 * Determine which stack to use..
@@ -557,6 +389,265 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
557 389
558 return 0; 390 return 0;
559} 391}
392#else /* !CONFIG_X86_32 */
393/*
394 * Determine which stack to use..
395 */
396static void __user *
397get_stack(struct k_sigaction *ka, unsigned long sp, unsigned long size)
398{
399 /* Default to using normal stack - redzone*/
400 sp -= 128;
401
402 /* This is the X/Open sanctioned signal stack switching. */
403 if (ka->sa.sa_flags & SA_ONSTACK) {
404 if (sas_ss_flags(sp) == 0)
405 sp = current->sas_ss_sp + current->sas_ss_size;
406 }
407
408 return (void __user *)round_down(sp - size, 64);
409}
410
411static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
412 sigset_t *set, struct pt_regs *regs)
413{
414 struct rt_sigframe __user *frame;
415 void __user *fp = NULL;
416 int err = 0;
417 struct task_struct *me = current;
418
419 if (used_math()) {
420 fp = get_stack(ka, regs->sp, sig_xstate_size);
421 frame = (void __user *)round_down(
422 (unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8;
423
424 if (save_i387_xstate(fp) < 0)
425 return -EFAULT;
426 } else
427 frame = get_stack(ka, regs->sp, sizeof(struct rt_sigframe)) - 8;
428
429 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
430 return -EFAULT;
431
432 if (ka->sa.sa_flags & SA_SIGINFO) {
433 if (copy_siginfo_to_user(&frame->info, info))
434 return -EFAULT;
435 }
436
437 /* Create the ucontext. */
438 if (cpu_has_xsave)
439 err |= __put_user(UC_FP_XSTATE, &frame->uc.uc_flags);
440 else
441 err |= __put_user(0, &frame->uc.uc_flags);
442 err |= __put_user(0, &frame->uc.uc_link);
443 err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
444 err |= __put_user(sas_ss_flags(regs->sp),
445 &frame->uc.uc_stack.ss_flags);
446 err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
447 err |= setup_sigcontext(&frame->uc.uc_mcontext, fp, regs, set->sig[0]);
448 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
449
450 /* Set up to return from userspace. If provided, use a stub
451 already in userspace. */
452 /* x86-64 should always use SA_RESTORER. */
453 if (ka->sa.sa_flags & SA_RESTORER) {
454 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
455 } else {
456 /* could use a vstub here */
457 return -EFAULT;
458 }
459
460 if (err)
461 return -EFAULT;
462
463 /* Set up registers for signal handler */
464 regs->di = sig;
465 /* In case the signal handler was declared without prototypes */
466 regs->ax = 0;
467
468 /* This also works for non SA_SIGINFO handlers because they expect the
469 next argument after the signal number on the stack. */
470 regs->si = (unsigned long)&frame->info;
471 regs->dx = (unsigned long)&frame->uc;
472 regs->ip = (unsigned long) ka->sa.sa_handler;
473
474 regs->sp = (unsigned long)frame;
475
476 /* Set up the CS register to run signal handlers in 64-bit mode,
477 even if the handler happens to be interrupting 32-bit code. */
478 regs->cs = __USER_CS;
479
480 return 0;
481}
482#endif /* CONFIG_X86_32 */
483
484/*
485 * Atomically swap in the new signal mask, and wait for a signal.
486 */
487asmlinkage int
488sys_sigsuspend(int history0, int history1, old_sigset_t mask)
489{
490 mask &= _BLOCKABLE;
491 spin_lock_irq(&current->sighand->siglock);
492 current->saved_sigmask = current->blocked;
493 siginitset(&current->blocked, mask);
494 recalc_sigpending();
495 spin_unlock_irq(&current->sighand->siglock);
496
497 current->state = TASK_INTERRUPTIBLE;
498 schedule();
499 set_restore_sigmask();
500
501 return -ERESTARTNOHAND;
502}
503
504asmlinkage int
505sys_sigaction(int sig, const struct old_sigaction __user *act,
506 struct old_sigaction __user *oact)
507{
508 struct k_sigaction new_ka, old_ka;
509 int ret;
510
511 if (act) {
512 old_sigset_t mask;
513
514 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
515 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
516 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
517 return -EFAULT;
518
519 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
520 __get_user(mask, &act->sa_mask);
521 siginitset(&new_ka.sa.sa_mask, mask);
522 }
523
524 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
525
526 if (!ret && oact) {
527 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
528 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
529 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
530 return -EFAULT;
531
532 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
533 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
534 }
535
536 return ret;
537}
538
539#ifdef CONFIG_X86_32
540asmlinkage int sys_sigaltstack(unsigned long bx)
541{
542 /*
543 * This is needed to make gcc realize it doesn't own the
544 * "struct pt_regs"
545 */
546 struct pt_regs *regs = (struct pt_regs *)&bx;
547 const stack_t __user *uss = (const stack_t __user *)bx;
548 stack_t __user *uoss = (stack_t __user *)regs->cx;
549
550 return do_sigaltstack(uss, uoss, regs->sp);
551}
552#else /* !CONFIG_X86_32 */
553asmlinkage long
554sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
555 struct pt_regs *regs)
556{
557 return do_sigaltstack(uss, uoss, regs->sp);
558}
559#endif /* CONFIG_X86_32 */
560
561/*
562 * Do a signal return; undo the signal stack.
563 */
564asmlinkage unsigned long sys_sigreturn(unsigned long __unused)
565{
566 struct sigframe __user *frame;
567 struct pt_regs *regs;
568 unsigned long ax;
569 sigset_t set;
570
571 regs = (struct pt_regs *) &__unused;
572 frame = (struct sigframe __user *)(regs->sp - 8);
573
574 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
575 goto badframe;
576 if (__get_user(set.sig[0], &frame->sc.oldmask) || (_NSIG_WORDS > 1
577 && __copy_from_user(&set.sig[1], &frame->extramask,
578 sizeof(frame->extramask))))
579 goto badframe;
580
581 sigdelsetmask(&set, ~_BLOCKABLE);
582 spin_lock_irq(&current->sighand->siglock);
583 current->blocked = set;
584 recalc_sigpending();
585 spin_unlock_irq(&current->sighand->siglock);
586
587 if (restore_sigcontext(regs, &frame->sc, &ax))
588 goto badframe;
589 return ax;
590
591badframe:
592 if (show_unhandled_signals && printk_ratelimit()) {
593 printk("%s%s[%d] bad frame in sigreturn frame:"
594 "%p ip:%lx sp:%lx oeax:%lx",
595 task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG,
596 current->comm, task_pid_nr(current), frame, regs->ip,
597 regs->sp, regs->orig_ax);
598 print_vma_addr(" in ", regs->ip);
599 printk(KERN_CONT "\n");
600 }
601
602 force_sig(SIGSEGV, current);
603
604 return 0;
605}
606
607static long do_rt_sigreturn(struct pt_regs *regs)
608{
609 struct rt_sigframe __user *frame;
610 unsigned long ax;
611 sigset_t set;
612
613 frame = (struct rt_sigframe __user *)(regs->sp - sizeof(long));
614 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
615 goto badframe;
616 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
617 goto badframe;
618
619 sigdelsetmask(&set, ~_BLOCKABLE);
620 spin_lock_irq(&current->sighand->siglock);
621 current->blocked = set;
622 recalc_sigpending();
623 spin_unlock_irq(&current->sighand->siglock);
624
625 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
626 goto badframe;
627
628 if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
629 goto badframe;
630
631 return ax;
632
633badframe:
634 signal_fault(regs, frame, "rt_sigreturn");
635 return 0;
636}
637
638#ifdef CONFIG_X86_32
639asmlinkage int sys_rt_sigreturn(unsigned long __unused)
640{
641 struct pt_regs *regs = (struct pt_regs *)&__unused;
642
643 return do_rt_sigreturn(regs);
644}
645#else /* !CONFIG_X86_32 */
646asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
647{
648 return do_rt_sigreturn(regs);
649}
650#endif /* CONFIG_X86_32 */
560 651
561/* 652/*
562 * OK, we're invoking a handler: 653 * OK, we're invoking a handler:
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
index 771c8fcc8b0d..2da7e6e60807 100644
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@ -174,80 +174,212 @@ setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
174 return err; 174 return err;
175} 175}
176 176
177/*
178 * Set up a signal frame.
179 */
177#ifdef CONFIG_X86_32 180#ifdef CONFIG_X86_32
178asmlinkage int sys_sigaltstack(unsigned long bx) 181static const struct {
182 u16 poplmovl;
183 u32 val;
184 u16 int80;
185} __attribute__((packed)) retcode = {
186 0xb858, /* popl %eax; movl $..., %eax */
187 __NR_sigreturn,
188 0x80cd, /* int $0x80 */
189};
190
191static const struct {
192 u8 movl;
193 u32 val;
194 u16 int80;
195 u8 pad;
196} __attribute__((packed)) rt_retcode = {
197 0xb8, /* movl $..., %eax */
198 __NR_rt_sigreturn,
199 0x80cd, /* int $0x80 */
200 0
201};
202
203/*
204 * Determine which stack to use..
205 */
206static inline void __user *
207get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
208 void **fpstate)
179{ 209{
210 unsigned long sp;
211
212 /* Default to using normal stack */
213 sp = regs->sp;
214
180 /* 215 /*
181 * This is needed to make gcc realize it doesn't own the 216 * If we are on the alternate signal stack and would overflow it, don't.
182 * "struct pt_regs" 217 * Return an always-bogus address instead so we will die with SIGSEGV.
183 */ 218 */
184 struct pt_regs *regs = (struct pt_regs *)&bx; 219 if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
185 const stack_t __user *uss = (const stack_t __user *)bx; 220 return (void __user *) -1L;
186 stack_t __user *uoss = (stack_t __user *)regs->cx;
187 221
188 return do_sigaltstack(uss, uoss, regs->sp); 222 /* This is the X/Open sanctioned signal stack switching. */
189} 223 if (ka->sa.sa_flags & SA_ONSTACK) {
190#else /* !CONFIG_X86_32 */ 224 if (sas_ss_flags(sp) == 0)
191asmlinkage long 225 sp = current->sas_ss_sp + current->sas_ss_size;
192sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, 226 } else {
193 struct pt_regs *regs) 227 /* This is the legacy signal stack switching. */
194{ 228 if ((regs->ss & 0xffff) != __USER_DS &&
195 return do_sigaltstack(uss, uoss, regs->sp); 229 !(ka->sa.sa_flags & SA_RESTORER) &&
230 ka->sa.sa_restorer)
231 sp = (unsigned long) ka->sa.sa_restorer;
232 }
233
234 if (used_math()) {
235 sp = sp - sig_xstate_size;
236 *fpstate = (struct _fpstate *) sp;
237 if (save_i387_xstate(*fpstate) < 0)
238 return (void __user *)-1L;
239 }
240
241 sp -= frame_size;
242 /*
243 * Align the stack pointer according to the i386 ABI,
244 * i.e. so that on function entry ((sp + 4) & 15) == 0.
245 */
246 sp = ((sp + 4) & -16ul) - 4;
247
248 return (void __user *) sp;
196} 249}
197#endif /* CONFIG_X86_32 */
198 250
199/* 251static int
200 * Do a signal return; undo the signal stack. 252__setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
201 */ 253 struct pt_regs *regs)
202static long do_rt_sigreturn(struct pt_regs *regs)
203{ 254{
204 struct rt_sigframe __user *frame; 255 struct sigframe __user *frame;
205 unsigned long ax; 256 void __user *restorer;
206 sigset_t set; 257 int err = 0;
258 void __user *fpstate = NULL;
207 259
208 frame = (struct rt_sigframe __user *)(regs->sp - sizeof(long)); 260 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
209 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
210 goto badframe;
211 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
212 goto badframe;
213 261
214 sigdelsetmask(&set, ~_BLOCKABLE); 262 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
215 spin_lock_irq(&current->sighand->siglock); 263 return -EFAULT;
216 current->blocked = set;
217 recalc_sigpending();
218 spin_unlock_irq(&current->sighand->siglock);
219 264
220 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax)) 265 if (__put_user(sig, &frame->sig))
221 goto badframe; 266 return -EFAULT;
222 267
223 if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) 268 if (setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
224 goto badframe; 269 return -EFAULT;
225 270
226 return ax; 271 if (_NSIG_WORDS > 1) {
272 if (__copy_to_user(&frame->extramask, &set->sig[1],
273 sizeof(frame->extramask)))
274 return -EFAULT;
275 }
276
277 if (current->mm->context.vdso)
278 restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
279 else
280 restorer = &frame->retcode;
281 if (ka->sa.sa_flags & SA_RESTORER)
282 restorer = ka->sa.sa_restorer;
283
284 /* Set up to return from userspace. */
285 err |= __put_user(restorer, &frame->pretcode);
286
287 /*
288 * This is popl %eax ; movl $__NR_sigreturn, %eax ; int $0x80
289 *
290 * WE DO NOT USE IT ANY MORE! It's only left here for historical
291 * reasons and because gdb uses it as a signature to notice
292 * signal handler stack frames.
293 */
294 err |= __put_user(*((u64 *)&retcode), (u64 *)frame->retcode);
295
296 if (err)
297 return -EFAULT;
298
299 /* Set up registers for signal handler */
300 regs->sp = (unsigned long)frame;
301 regs->ip = (unsigned long)ka->sa.sa_handler;
302 regs->ax = (unsigned long)sig;
303 regs->dx = 0;
304 regs->cx = 0;
305
306 regs->ds = __USER_DS;
307 regs->es = __USER_DS;
308 regs->ss = __USER_DS;
309 regs->cs = __USER_CS;
227 310
228badframe:
229 signal_fault(regs, frame, "rt_sigreturn");
230 return 0; 311 return 0;
231} 312}
232 313
233#ifdef CONFIG_X86_32 314static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
234asmlinkage int sys_rt_sigreturn(unsigned long __unused) 315 sigset_t *set, struct pt_regs *regs)
235{ 316{
236 struct pt_regs *regs = (struct pt_regs *)&__unused; 317 struct rt_sigframe __user *frame;
318 void __user *restorer;
319 int err = 0;
320 void __user *fpstate = NULL;
237 321
238 return do_rt_sigreturn(regs); 322 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
239}
240#else /* !CONFIG_X86_32 */
241asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
242{
243 return do_rt_sigreturn(regs);
244}
245#endif /* CONFIG_X86_32 */
246 323
247/* 324 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
248 * Set up a signal frame. 325 return -EFAULT;
249 */ 326
327 err |= __put_user(sig, &frame->sig);
328 err |= __put_user(&frame->info, &frame->pinfo);
329 err |= __put_user(&frame->uc, &frame->puc);
330 err |= copy_siginfo_to_user(&frame->info, info);
331 if (err)
332 return -EFAULT;
333
334 /* Create the ucontext. */
335 if (cpu_has_xsave)
336 err |= __put_user(UC_FP_XSTATE, &frame->uc.uc_flags);
337 else
338 err |= __put_user(0, &frame->uc.uc_flags);
339 err |= __put_user(0, &frame->uc.uc_link);
340 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
341 err |= __put_user(sas_ss_flags(regs->sp),
342 &frame->uc.uc_stack.ss_flags);
343 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
344 err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
345 regs, set->sig[0]);
346 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
347 if (err)
348 return -EFAULT;
349
350 /* Set up to return from userspace. */
351 restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
352 if (ka->sa.sa_flags & SA_RESTORER)
353 restorer = ka->sa.sa_restorer;
354 err |= __put_user(restorer, &frame->pretcode);
355
356 /*
357 * This is movl $__NR_rt_sigreturn, %ax ; int $0x80
358 *
359 * WE DO NOT USE IT ANY MORE! It's only left here for historical
360 * reasons and because gdb uses it as a signature to notice
361 * signal handler stack frames.
362 */
363 err |= __put_user(*((u64 *)&rt_retcode), (u64 *)frame->retcode);
250 364
365 if (err)
366 return -EFAULT;
367
368 /* Set up registers for signal handler */
369 regs->sp = (unsigned long)frame;
370 regs->ip = (unsigned long)ka->sa.sa_handler;
371 regs->ax = (unsigned long)sig;
372 regs->dx = (unsigned long)&frame->info;
373 regs->cx = (unsigned long)&frame->uc;
374
375 regs->ds = __USER_DS;
376 regs->es = __USER_DS;
377 regs->ss = __USER_DS;
378 regs->cs = __USER_CS;
379
380 return 0;
381}
382#else /* !CONFIG_X86_32 */
251/* 383/*
252 * Determine which stack to use.. 384 * Determine which stack to use..
253 */ 385 */
@@ -337,6 +469,77 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
337 469
338 return 0; 470 return 0;
339} 471}
472#endif /* CONFIG_X86_32 */
473
474#ifdef CONFIG_X86_32
475asmlinkage int sys_sigaltstack(unsigned long bx)
476{
477 /*
478 * This is needed to make gcc realize it doesn't own the
479 * "struct pt_regs"
480 */
481 struct pt_regs *regs = (struct pt_regs *)&bx;
482 const stack_t __user *uss = (const stack_t __user *)bx;
483 stack_t __user *uoss = (stack_t __user *)regs->cx;
484
485 return do_sigaltstack(uss, uoss, regs->sp);
486}
487#else /* !CONFIG_X86_32 */
488asmlinkage long
489sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
490 struct pt_regs *regs)
491{
492 return do_sigaltstack(uss, uoss, regs->sp);
493}
494#endif /* CONFIG_X86_32 */
495
496/*
497 * Do a signal return; undo the signal stack.
498 */
499static long do_rt_sigreturn(struct pt_regs *regs)
500{
501 struct rt_sigframe __user *frame;
502 unsigned long ax;
503 sigset_t set;
504
505 frame = (struct rt_sigframe __user *)(regs->sp - sizeof(long));
506 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
507 goto badframe;
508 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
509 goto badframe;
510
511 sigdelsetmask(&set, ~_BLOCKABLE);
512 spin_lock_irq(&current->sighand->siglock);
513 current->blocked = set;
514 recalc_sigpending();
515 spin_unlock_irq(&current->sighand->siglock);
516
517 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
518 goto badframe;
519
520 if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
521 goto badframe;
522
523 return ax;
524
525badframe:
526 signal_fault(regs, frame, "rt_sigreturn");
527 return 0;
528}
529
530#ifdef CONFIG_X86_32
531asmlinkage int sys_rt_sigreturn(unsigned long __unused)
532{
533 struct pt_regs *regs = (struct pt_regs *)&__unused;
534
535 return do_rt_sigreturn(regs);
536}
537#else /* !CONFIG_X86_32 */
538asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
539{
540 return do_rt_sigreturn(regs);
541}
542#endif /* CONFIG_X86_32 */
340 543
341/* 544/*
342 * OK, we're invoking a handler 545 * OK, we're invoking a handler