aboutsummaryrefslogtreecommitdiff
path: root/arch/x86/um/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/um/signal.c')
-rw-r--r--arch/x86/um/signal.c66
1 files changed, 22 insertions, 44 deletions
diff --git a/arch/x86/um/signal.c b/arch/x86/um/signal.c
index 4883b954601..5e04a1c899f 100644
--- a/arch/x86/um/signal.c
+++ b/arch/x86/um/signal.c
@@ -11,8 +11,8 @@
#include <asm/unistd.h>
#include <asm/uaccess.h>
#include <asm/ucontext.h>
-#include "frame_kern.h"
-#include "skas.h"
+#include <frame_kern.h>
+#include <skas.h>
#ifdef CONFIG_X86_32
@@ -156,6 +156,9 @@ static int copy_sc_from_user(struct pt_regs *regs,
struct sigcontext sc;
int err, pid;
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
err = copy_from_user(&sc, from, sizeof(sc));
if (err)
return err;
@@ -339,9 +342,7 @@ static int copy_ucontext_to_user(struct ucontext __user *uc,
{
int err = 0;
- err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp);
- err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
- err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
+ err |= __save_altstack(&uc->uc_stack, sp);
err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs, 0);
err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
return err;
@@ -410,12 +411,9 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
PT_REGS_SP(regs) = (unsigned long) frame;
PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
- PT_REGS_EAX(regs) = (unsigned long) sig;
- PT_REGS_EDX(regs) = (unsigned long) 0;
- PT_REGS_ECX(regs) = (unsigned long) 0;
-
- if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
- ptrace_notify(SIGTRAP);
+ PT_REGS_AX(regs) = (unsigned long) sig;
+ PT_REGS_DX(regs) = (unsigned long) 0;
+ PT_REGS_CX(regs) = (unsigned long) 0;
return 0;
}
@@ -460,16 +458,13 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
PT_REGS_SP(regs) = (unsigned long) frame;
PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
- PT_REGS_EAX(regs) = (unsigned long) sig;
- PT_REGS_EDX(regs) = (unsigned long) &frame->info;
- PT_REGS_ECX(regs) = (unsigned long) &frame->uc;
-
- if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
- ptrace_notify(SIGTRAP);
+ PT_REGS_AX(regs) = (unsigned long) sig;
+ PT_REGS_DX(regs) = (unsigned long) &frame->info;
+ PT_REGS_CX(regs) = (unsigned long) &frame->uc;
return 0;
}
-long sys_sigreturn(struct pt_regs *regs)
+long sys_sigreturn(void)
{
unsigned long sp = PT_REGS_SP(&current->thread.regs);
struct sigframe __user *frame = (struct sigframe __user *)(sp - 8);
@@ -483,7 +478,6 @@ long sys_sigreturn(struct pt_regs *regs)
copy_from_user(&set.sig[1], extramask, sig_size))
goto segfault;
- sigdelsetmask(&set, ~_BLOCKABLE);
set_current_blocked(&set);
if (copy_sc_from_user(&current->thread.regs, sc))
@@ -514,7 +508,6 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
{
struct rt_sigframe __user *frame;
int err = 0;
- struct task_struct *me = current;
frame = (struct rt_sigframe __user *)
round_down(stack_top - sizeof(struct rt_sigframe), 16);
@@ -533,16 +526,13 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
err |= __put_user(0, &frame->uc.uc_link);
- err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
- err |= __put_user(sas_ss_flags(PT_REGS_SP(regs)),
- &frame->uc.uc_stack.ss_flags);
- err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
+ err |= __save_altstack(&frame->uc.uc_stack, PT_REGS_SP(regs));
err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs,
set->sig[0]);
err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate);
if (sizeof(*set) == 16) {
- __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
- __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
+ err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
+ err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
}
else
err |= __copy_to_user(&frame->uc.uc_sigmask, set,
@@ -570,23 +560,23 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
}
PT_REGS_SP(regs) = (unsigned long) frame;
- PT_REGS_RDI(regs) = sig;
+ PT_REGS_DI(regs) = sig;
/* In case the signal handler was declared without prototypes */
- PT_REGS_RAX(regs) = 0;
+ PT_REGS_AX(regs) = 0;
/*
* This also works for non SA_SIGINFO handlers because they expect the
* next argument after the signal number on the stack.
*/
- PT_REGS_RSI(regs) = (unsigned long) &frame->info;
- PT_REGS_RDX(regs) = (unsigned long) &frame->uc;
- PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler;
+ PT_REGS_SI(regs) = (unsigned long) &frame->info;
+ PT_REGS_DX(regs) = (unsigned long) &frame->uc;
+ PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
out:
return err;
}
#endif
-long sys_rt_sigreturn(struct pt_regs *regs)
+long sys_rt_sigreturn(void)
{
unsigned long sp = PT_REGS_SP(&current->thread.regs);
struct rt_sigframe __user *frame =
@@ -597,7 +587,6 @@ long sys_rt_sigreturn(struct pt_regs *regs)
if (copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
goto segfault;
- sigdelsetmask(&set, ~_BLOCKABLE);
set_current_blocked(&set);
if (copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext))
@@ -611,14 +600,3 @@ long sys_rt_sigreturn(struct pt_regs *regs)
force_sig(SIGSEGV, current);
return 0;
}
-
-#ifdef CONFIG_X86_32
-long ptregs_sigreturn(void)
-{
- return sys_sigreturn(NULL);
-}
-long ptregs_rt_sigreturn(void)
-{
- return sys_rt_sigreturn(NULL);
-}
-#endif