10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12 #include <linux/sched.h>
15 #include <linux/kernel.h>
16 #include <linux/errno.h>
17 #include <linux/wait.h>
20 #include <linux/stddef.h>
21 #include <linux/personality.h>
26 #include <asm/processor.h>
27 #include <asm/ucontext.h>
40 #include <asm/syscall.h>
41 #include <asm/syscalls.h>
43 #include <asm/sigframe.h>
46 # define FIX_EFLAGS (__FIX_EFLAGS | X86_EFLAGS_RF)
48 # define FIX_EFLAGS __FIX_EFLAGS
51 #define COPY(x) do { \
52 get_user_ex(regs->x, &sc->x); \
55 #define GET_SEG(seg) ({ \
57 get_user_ex(tmp, &sc->seg); \
61 #define COPY_SEG(seg) do { \
62 regs->seg = GET_SEG(seg); \
65 #define COPY_SEG_CPL3(seg) do { \
66 regs->seg = GET_SEG(seg) | 3; \
73 unsigned int tmpflags;
191 static unsigned long align_sigframe(
unsigned long sp)
198 sp = ((sp + 4) & -16ul) - 4;
205 static inline void __user *
207 void __user **fpstate)
210 unsigned long math_size = 0;
211 unsigned long sp = regs->
sp;
212 unsigned long buf_fx = 0;
213 int onsigstack = on_sig_stack(sp);
227 ka->
sa.sa_restorer) {
229 sp = (
unsigned long) ka->
sa.sa_restorer;
235 &buf_fx, &math_size);
236 *fpstate = (
void __user *)sp;
239 sp = align_sigframe(sp - frame_size);
245 if (onsigstack && !
likely(on_sig_stack(sp)))
246 return (
void __user *)-1
L;
251 return (
void __user *)-1
L;
253 return (
void __user *)
sp;
257 static const struct {
267 static const struct {
288 frame =
get_sigframe(ka, regs,
sizeof(*frame), &fpstate);
306 restorer = VDSO32_SYMBOL(
current->mm->context.vdso, sigreturn);
310 restorer = ka->
sa.sa_restorer;
328 regs->
sp = (
unsigned long)frame;
329 regs->ip = (
unsigned long)ka->
sa.sa_handler;
330 regs->ax = (
unsigned long)
sig;
350 frame =
get_sigframe(ka, regs,
sizeof(*frame), &fpstate);
368 &frame->
uc.uc_stack.ss_flags);
372 restorer = VDSO32_SYMBOL(
current->mm->context.vdso, rt_sigreturn);
374 restorer = ka->
sa.sa_restorer;
396 regs->
sp = (
unsigned long)frame;
397 regs->ip = (
unsigned long)ka->
sa.sa_handler;
398 regs->ax = (
unsigned long)
sig;
399 regs->dx = (
unsigned long)&frame->
info;
400 regs->cx = (
unsigned long)&frame->
uc;
437 &frame->
uc.uc_stack.ss_flags);
464 regs->si = (
unsigned long)&frame->
info;
465 regs->dx = (
unsigned long)&frame->
uc;
466 regs->ip = (
unsigned long) ka->
sa.sa_handler;
468 regs->
sp = (
unsigned long)
frame;
478 static int x32_setup_rt_frame(
int sig,
struct k_sigaction *ka,
482 #ifdef CONFIG_X86_X32_ABI
488 frame =
get_sigframe(ka, regs,
sizeof(*frame), &fpstate);
507 &frame->uc.uc_stack.ss_flags);
512 restorer = ka->
sa.sa_restorer;
529 regs->
sp = (
unsigned long) frame;
530 regs->ip = (
unsigned long) ka->
sa.sa_handler;
534 regs->si = (
unsigned long) &frame->info;
535 regs->dx = (
unsigned long) &frame->uc;
555 siginitset(&blocked, mask);
573 get_user_ex(new_ka.sa.sa_handler, &act->sa_handler);
576 get_user_ex(new_ka.sa.sa_restorer, &act->sa_restorer);
581 siginitset(&new_ka.sa.sa_mask, mask);
591 put_user_ex(old_ka.sa.sa_handler, &oact->sa_handler);
593 put_user_ex(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
594 put_user_ex(old_ka.sa.sa_restorer, &oact->sa_restorer);
650 frame = (
struct rt_sigframe __user *)(regs->
sp -
sizeof(
long));
674 static int signr_convert(
int sig)
689 int usig = signr_convert(sig);
691 compat_sigset_t *cset = (compat_sigset_t *)
set;
694 if (is_ia32_frame()) {
699 }
else if (is_x32_frame()) {
700 return x32_setup_rt_frame(usig, ka, info, cset, regs);
702 return __setup_rt_frame(sig, ka, info,
set, regs);
726 regs->ax = regs->orig_ax;
740 if (setup_rt_frame(sig, ka, info, regs) < 0) {
763 #define NR_restart_syscall __NR_restart_syscall
765 #define NR_restart_syscall \
766 test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall : __NR_restart_syscall
783 handle_signal(signr, &info, &ka, regs);
794 regs->ax = regs->orig_ax;
809 restore_saved_sigmask();
821 #ifdef CONFIG_X86_MCE
836 tracehook_notify_resume(regs);
850 "%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx",
852 me->
comm, me->
pid, where, frame,
853 regs->ip, regs->
sp, regs->orig_ax);
861 #ifdef CONFIG_X86_X32_ABI
869 frame = (
struct rt_sigframe_x32
__user *)(regs->
sp - 8);