Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull signal handling cleanups from Al Viro: "This is the first pile; another one will come a bit later and will contain SYSCALL_DEFINE-related patches. - a bunch of signal-related syscalls (both native and compat) unified. - a bunch of compat syscalls switched to COMPAT_SYSCALL_DEFINE (fixing several potential problems with missing argument validation, while we are at it) - a lot of now-pointless wrappers killed - a couple of architectures (cris and hexagon) forgot to save altstack settings into sigframe, even though they used the (uninitialized) values in sigreturn; fixed. - microblaze fixes for delivery of multiple signals arriving at once - saner set of helpers for signal delivery introduced, several architectures switched to using those." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (143 commits) x86: convert to ksignal sparc: convert to ksignal arm: switch to struct ksignal * passing alpha: pass k_sigaction and siginfo_t using ksignal pointer burying unused conditionals make do_sigaltstack() static arm64: switch to generic old sigaction() (compat-only) arm64: switch to generic compat rt_sigaction() arm64: switch compat to generic old sigsuspend arm64: switch to generic compat rt_sigqueueinfo() arm64: switch to generic compat rt_sigpending() arm64: switch to generic compat rt_sigprocmask() arm64: switch to generic sigaltstack sparc: switch to generic old sigsuspend sparc: COMPAT_SYSCALL_DEFINE does all sign-extension as well as SYSCALL_DEFINE sparc: kill sign-extending wrappers for native syscalls kill sparc32_open() sparc: switch to use of generic old sigaction sparc: switch sys_compat_rt_sigaction() to COMPAT_SYSCALL_DEFINE mips: switch to generic sys_fork() and sys_clone() ...
This commit is contained in:
@@ -699,51 +699,6 @@ END(syscall_badsys)
|
||||
*/
|
||||
.popsection
|
||||
|
||||
/*
|
||||
* System calls that need a pt_regs pointer.
|
||||
*/
|
||||
#define PTREGSCALL0(name) \
|
||||
ENTRY(ptregs_##name) ; \
|
||||
leal 4(%esp),%eax; \
|
||||
jmp sys_##name; \
|
||||
ENDPROC(ptregs_##name)
|
||||
|
||||
#define PTREGSCALL1(name) \
|
||||
ENTRY(ptregs_##name) ; \
|
||||
leal 4(%esp),%edx; \
|
||||
movl (PT_EBX+4)(%esp),%eax; \
|
||||
jmp sys_##name; \
|
||||
ENDPROC(ptregs_##name)
|
||||
|
||||
#define PTREGSCALL2(name) \
|
||||
ENTRY(ptregs_##name) ; \
|
||||
leal 4(%esp),%ecx; \
|
||||
movl (PT_ECX+4)(%esp),%edx; \
|
||||
movl (PT_EBX+4)(%esp),%eax; \
|
||||
jmp sys_##name; \
|
||||
ENDPROC(ptregs_##name)
|
||||
|
||||
#define PTREGSCALL3(name) \
|
||||
ENTRY(ptregs_##name) ; \
|
||||
CFI_STARTPROC; \
|
||||
leal 4(%esp),%eax; \
|
||||
pushl_cfi %eax; \
|
||||
movl PT_EDX(%eax),%ecx; \
|
||||
movl PT_ECX(%eax),%edx; \
|
||||
movl PT_EBX(%eax),%eax; \
|
||||
call sys_##name; \
|
||||
addl $4,%esp; \
|
||||
CFI_ADJUST_CFA_OFFSET -4; \
|
||||
ret; \
|
||||
CFI_ENDPROC; \
|
||||
ENDPROC(ptregs_##name)
|
||||
|
||||
PTREGSCALL1(iopl)
|
||||
PTREGSCALL0(sigreturn)
|
||||
PTREGSCALL0(rt_sigreturn)
|
||||
PTREGSCALL2(vm86)
|
||||
PTREGSCALL1(vm86old)
|
||||
|
||||
.macro FIXUP_ESPFIX_STACK
|
||||
/*
|
||||
* Switch back for ESPFIX stack to the normal zerobased stack
|
||||
|
@@ -828,23 +828,6 @@ int_restore_rest:
|
||||
CFI_ENDPROC
|
||||
END(system_call)
|
||||
|
||||
/*
|
||||
* Certain special system calls that need to save a complete full stack frame.
|
||||
*/
|
||||
.macro PTREGSCALL label,func,arg
|
||||
ENTRY(\label)
|
||||
PARTIAL_FRAME 1 8 /* offset 8: return address */
|
||||
subq $REST_SKIP, %rsp
|
||||
CFI_ADJUST_CFA_OFFSET REST_SKIP
|
||||
call save_rest
|
||||
DEFAULT_FRAME 0 8 /* offset 8: return address */
|
||||
leaq 8(%rsp), \arg /* pt_regs pointer */
|
||||
call \func
|
||||
jmp ptregscall_common
|
||||
CFI_ENDPROC
|
||||
END(\label)
|
||||
.endm
|
||||
|
||||
.macro FORK_LIKE func
|
||||
ENTRY(stub_\func)
|
||||
CFI_STARTPROC
|
||||
@@ -861,10 +844,22 @@ ENTRY(stub_\func)
|
||||
END(stub_\func)
|
||||
.endm
|
||||
|
||||
.macro FIXED_FRAME label,func
|
||||
ENTRY(\label)
|
||||
CFI_STARTPROC
|
||||
PARTIAL_FRAME 0 8 /* offset 8: return address */
|
||||
FIXUP_TOP_OF_STACK %r11, 8-ARGOFFSET
|
||||
call \func
|
||||
RESTORE_TOP_OF_STACK %r11, 8-ARGOFFSET
|
||||
ret
|
||||
CFI_ENDPROC
|
||||
END(\label)
|
||||
.endm
|
||||
|
||||
FORK_LIKE clone
|
||||
FORK_LIKE fork
|
||||
FORK_LIKE vfork
|
||||
PTREGSCALL stub_iopl, sys_iopl, %rsi
|
||||
FIXED_FRAME stub_iopl, sys_iopl
|
||||
|
||||
ENTRY(ptregscall_common)
|
||||
DEFAULT_FRAME 1 8 /* offset 8: return address */
|
||||
@@ -886,7 +881,6 @@ ENTRY(stub_execve)
|
||||
SAVE_REST
|
||||
FIXUP_TOP_OF_STACK %r11
|
||||
call sys_execve
|
||||
RESTORE_TOP_OF_STACK %r11
|
||||
movq %rax,RAX(%rsp)
|
||||
RESTORE_REST
|
||||
jmp int_ret_from_sys_call
|
||||
@@ -902,7 +896,6 @@ ENTRY(stub_rt_sigreturn)
|
||||
addq $8, %rsp
|
||||
PARTIAL_FRAME 0
|
||||
SAVE_REST
|
||||
movq %rsp,%rdi
|
||||
FIXUP_TOP_OF_STACK %r11
|
||||
call sys_rt_sigreturn
|
||||
movq %rax,RAX(%rsp) # fixme, this could be done at the higher layer
|
||||
@@ -917,7 +910,6 @@ ENTRY(stub_x32_rt_sigreturn)
|
||||
addq $8, %rsp
|
||||
PARTIAL_FRAME 0
|
||||
SAVE_REST
|
||||
movq %rsp,%rdi
|
||||
FIXUP_TOP_OF_STACK %r11
|
||||
call sys32_x32_rt_sigreturn
|
||||
movq %rax,RAX(%rsp) # fixme, this could be done at the higher layer
|
||||
|
@@ -93,8 +93,9 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
|
||||
* on system-call entry - see also fork() and the signal handling
|
||||
* code.
|
||||
*/
|
||||
long sys_iopl(unsigned int level, struct pt_regs *regs)
|
||||
SYSCALL_DEFINE1(iopl, unsigned int, level)
|
||||
{
|
||||
struct pt_regs *regs = current_pt_regs();
|
||||
unsigned int old = (regs->flags >> 12) & 3;
|
||||
struct thread_struct *t = ¤t->thread;
|
||||
|
||||
|
@@ -278,7 +278,7 @@ static const struct {
|
||||
};
|
||||
|
||||
static int
|
||||
__setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
|
||||
__setup_frame(int sig, struct ksignal *ksig, sigset_t *set,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
struct sigframe __user *frame;
|
||||
@@ -286,7 +286,7 @@ __setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
|
||||
int err = 0;
|
||||
void __user *fpstate = NULL;
|
||||
|
||||
frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
|
||||
frame = get_sigframe(&ksig->ka, regs, sizeof(*frame), &fpstate);
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
|
||||
return -EFAULT;
|
||||
@@ -307,8 +307,8 @@ __setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
|
||||
restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
|
||||
else
|
||||
restorer = &frame->retcode;
|
||||
if (ka->sa.sa_flags & SA_RESTORER)
|
||||
restorer = ka->sa.sa_restorer;
|
||||
if (ksig->ka.sa.sa_flags & SA_RESTORER)
|
||||
restorer = ksig->ka.sa.sa_restorer;
|
||||
|
||||
/* Set up to return from userspace. */
|
||||
err |= __put_user(restorer, &frame->pretcode);
|
||||
@@ -327,7 +327,7 @@ __setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
|
||||
|
||||
/* Set up registers for signal handler */
|
||||
regs->sp = (unsigned long)frame;
|
||||
regs->ip = (unsigned long)ka->sa.sa_handler;
|
||||
regs->ip = (unsigned long)ksig->ka.sa.sa_handler;
|
||||
regs->ax = (unsigned long)sig;
|
||||
regs->dx = 0;
|
||||
regs->cx = 0;
|
||||
@@ -340,7 +340,7 @@ __setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
static int __setup_rt_frame(int sig, struct ksignal *ksig,
|
||||
sigset_t *set, struct pt_regs *regs)
|
||||
{
|
||||
struct rt_sigframe __user *frame;
|
||||
@@ -348,7 +348,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
int err = 0;
|
||||
void __user *fpstate = NULL;
|
||||
|
||||
frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
|
||||
frame = get_sigframe(&ksig->ka, regs, sizeof(*frame), &fpstate);
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
|
||||
return -EFAULT;
|
||||
@@ -368,8 +368,8 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
|
||||
/* Set up to return from userspace. */
|
||||
restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
|
||||
if (ka->sa.sa_flags & SA_RESTORER)
|
||||
restorer = ka->sa.sa_restorer;
|
||||
if (ksig->ka.sa.sa_flags & SA_RESTORER)
|
||||
restorer = ksig->ka.sa.sa_restorer;
|
||||
put_user_ex(restorer, &frame->pretcode);
|
||||
|
||||
/*
|
||||
@@ -382,7 +382,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
put_user_ex(*((u64 *)&rt_retcode), (u64 *)frame->retcode);
|
||||
} put_user_catch(err);
|
||||
|
||||
err |= copy_siginfo_to_user(&frame->info, info);
|
||||
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
|
||||
err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
|
||||
regs, set->sig[0]);
|
||||
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
|
||||
@@ -392,7 +392,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
|
||||
/* Set up registers for signal handler */
|
||||
regs->sp = (unsigned long)frame;
|
||||
regs->ip = (unsigned long)ka->sa.sa_handler;
|
||||
regs->ip = (unsigned long)ksig->ka.sa.sa_handler;
|
||||
regs->ax = (unsigned long)sig;
|
||||
regs->dx = (unsigned long)&frame->info;
|
||||
regs->cx = (unsigned long)&frame->uc;
|
||||
@@ -405,20 +405,20 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
return 0;
|
||||
}
|
||||
#else /* !CONFIG_X86_32 */
|
||||
static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
static int __setup_rt_frame(int sig, struct ksignal *ksig,
|
||||
sigset_t *set, struct pt_regs *regs)
|
||||
{
|
||||
struct rt_sigframe __user *frame;
|
||||
void __user *fp = NULL;
|
||||
int err = 0;
|
||||
|
||||
frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe), &fp);
|
||||
frame = get_sigframe(&ksig->ka, regs, sizeof(struct rt_sigframe), &fp);
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
|
||||
return -EFAULT;
|
||||
|
||||
if (ka->sa.sa_flags & SA_SIGINFO) {
|
||||
if (copy_siginfo_to_user(&frame->info, info))
|
||||
if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
|
||||
if (copy_siginfo_to_user(&frame->info, &ksig->info))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
@@ -434,8 +434,8 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
/* Set up to return from userspace. If provided, use a stub
|
||||
already in userspace. */
|
||||
/* x86-64 should always use SA_RESTORER. */
|
||||
if (ka->sa.sa_flags & SA_RESTORER) {
|
||||
put_user_ex(ka->sa.sa_restorer, &frame->pretcode);
|
||||
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
|
||||
put_user_ex(ksig->ka.sa.sa_restorer, &frame->pretcode);
|
||||
} else {
|
||||
/* could use a vstub here */
|
||||
err |= -EFAULT;
|
||||
@@ -457,7 +457,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
next argument after the signal number on the stack. */
|
||||
regs->si = (unsigned long)&frame->info;
|
||||
regs->dx = (unsigned long)&frame->uc;
|
||||
regs->ip = (unsigned long) ka->sa.sa_handler;
|
||||
regs->ip = (unsigned long) ksig->ka.sa.sa_handler;
|
||||
|
||||
regs->sp = (unsigned long)frame;
|
||||
|
||||
@@ -469,8 +469,8 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
}
|
||||
#endif /* CONFIG_X86_32 */
|
||||
|
||||
static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
|
||||
siginfo_t *info, compat_sigset_t *set,
|
||||
static int x32_setup_rt_frame(struct ksignal *ksig,
|
||||
compat_sigset_t *set,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
#ifdef CONFIG_X86_X32_ABI
|
||||
@@ -479,13 +479,13 @@ static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
|
||||
int err = 0;
|
||||
void __user *fpstate = NULL;
|
||||
|
||||
frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
|
||||
frame = get_sigframe(&ksig->ka, regs, sizeof(*frame), &fpstate);
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
|
||||
return -EFAULT;
|
||||
|
||||
if (ka->sa.sa_flags & SA_SIGINFO) {
|
||||
if (copy_siginfo_to_user32(&frame->info, info))
|
||||
if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
|
||||
if (copy_siginfo_to_user32(&frame->info, &ksig->info))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
@@ -499,8 +499,8 @@ static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
|
||||
err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
|
||||
put_user_ex(0, &frame->uc.uc__pad0);
|
||||
|
||||
if (ka->sa.sa_flags & SA_RESTORER) {
|
||||
restorer = ka->sa.sa_restorer;
|
||||
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
|
||||
restorer = ksig->ka.sa.sa_restorer;
|
||||
} else {
|
||||
/* could use a vstub here */
|
||||
restorer = NULL;
|
||||
@@ -518,10 +518,10 @@ static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
|
||||
|
||||
/* Set up registers for signal handler */
|
||||
regs->sp = (unsigned long) frame;
|
||||
regs->ip = (unsigned long) ka->sa.sa_handler;
|
||||
regs->ip = (unsigned long) ksig->ka.sa.sa_handler;
|
||||
|
||||
/* We use the x32 calling convention here... */
|
||||
regs->di = sig;
|
||||
regs->di = ksig->sig;
|
||||
regs->si = (unsigned long) &frame->info;
|
||||
regs->dx = (unsigned long) &frame->uc;
|
||||
|
||||
@@ -535,70 +535,13 @@ static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
/*
|
||||
* Atomically swap in the new signal mask, and wait for a signal.
|
||||
*/
|
||||
asmlinkage int
|
||||
sys_sigsuspend(int history0, int history1, old_sigset_t mask)
|
||||
{
|
||||
sigset_t blocked;
|
||||
siginitset(&blocked, mask);
|
||||
return sigsuspend(&blocked);
|
||||
}
|
||||
|
||||
asmlinkage int
|
||||
sys_sigaction(int sig, const struct old_sigaction __user *act,
|
||||
struct old_sigaction __user *oact)
|
||||
{
|
||||
struct k_sigaction new_ka, old_ka;
|
||||
int ret = 0;
|
||||
|
||||
if (act) {
|
||||
old_sigset_t mask;
|
||||
|
||||
if (!access_ok(VERIFY_READ, act, sizeof(*act)))
|
||||
return -EFAULT;
|
||||
|
||||
get_user_try {
|
||||
get_user_ex(new_ka.sa.sa_handler, &act->sa_handler);
|
||||
get_user_ex(new_ka.sa.sa_flags, &act->sa_flags);
|
||||
get_user_ex(mask, &act->sa_mask);
|
||||
get_user_ex(new_ka.sa.sa_restorer, &act->sa_restorer);
|
||||
} get_user_catch(ret);
|
||||
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
siginitset(&new_ka.sa.sa_mask, mask);
|
||||
}
|
||||
|
||||
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
|
||||
|
||||
if (!ret && oact) {
|
||||
if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
|
||||
return -EFAULT;
|
||||
|
||||
put_user_try {
|
||||
put_user_ex(old_ka.sa.sa_handler, &oact->sa_handler);
|
||||
put_user_ex(old_ka.sa.sa_flags, &oact->sa_flags);
|
||||
put_user_ex(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
|
||||
put_user_ex(old_ka.sa.sa_restorer, &oact->sa_restorer);
|
||||
} put_user_catch(ret);
|
||||
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_X86_32 */
|
||||
|
||||
/*
|
||||
* Do a signal return; undo the signal stack.
|
||||
*/
|
||||
#ifdef CONFIG_X86_32
|
||||
unsigned long sys_sigreturn(struct pt_regs *regs)
|
||||
unsigned long sys_sigreturn(void)
|
||||
{
|
||||
struct pt_regs *regs = current_pt_regs();
|
||||
struct sigframe __user *frame;
|
||||
unsigned long ax;
|
||||
sigset_t set;
|
||||
@@ -625,8 +568,9 @@ badframe:
|
||||
}
|
||||
#endif /* CONFIG_X86_32 */
|
||||
|
||||
long sys_rt_sigreturn(struct pt_regs *regs)
|
||||
long sys_rt_sigreturn(void)
|
||||
{
|
||||
struct pt_regs *regs = current_pt_regs();
|
||||
struct rt_sigframe __user *frame;
|
||||
unsigned long ax;
|
||||
sigset_t set;
|
||||
@@ -667,30 +611,29 @@ static int signr_convert(int sig)
|
||||
}
|
||||
|
||||
static int
|
||||
setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
struct pt_regs *regs)
|
||||
setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
|
||||
{
|
||||
int usig = signr_convert(sig);
|
||||
int usig = signr_convert(ksig->sig);
|
||||
sigset_t *set = sigmask_to_save();
|
||||
compat_sigset_t *cset = (compat_sigset_t *) set;
|
||||
|
||||
/* Set up the stack frame */
|
||||
if (is_ia32_frame()) {
|
||||
if (ka->sa.sa_flags & SA_SIGINFO)
|
||||
return ia32_setup_rt_frame(usig, ka, info, cset, regs);
|
||||
if (ksig->ka.sa.sa_flags & SA_SIGINFO)
|
||||
return ia32_setup_rt_frame(usig, ksig, cset, regs);
|
||||
else
|
||||
return ia32_setup_frame(usig, ka, cset, regs);
|
||||
return ia32_setup_frame(usig, ksig, cset, regs);
|
||||
} else if (is_x32_frame()) {
|
||||
return x32_setup_rt_frame(usig, ka, info, cset, regs);
|
||||
return x32_setup_rt_frame(ksig, cset, regs);
|
||||
} else {
|
||||
return __setup_rt_frame(sig, ka, info, set, regs);
|
||||
return __setup_rt_frame(ksig->sig, ksig, set, regs);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
|
||||
struct pt_regs *regs)
|
||||
handle_signal(struct ksignal *ksig, struct pt_regs *regs)
|
||||
{
|
||||
bool failed;
|
||||
/* Are we from a system call? */
|
||||
if (syscall_get_nr(current, regs) >= 0) {
|
||||
/* If so, check system call restarting.. */
|
||||
@@ -701,7 +644,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
|
||||
break;
|
||||
|
||||
case -ERESTARTSYS:
|
||||
if (!(ka->sa.sa_flags & SA_RESTART)) {
|
||||
if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
|
||||
regs->ax = -EINTR;
|
||||
break;
|
||||
}
|
||||
@@ -721,26 +664,21 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
|
||||
likely(test_and_clear_thread_flag(TIF_FORCED_TF)))
|
||||
regs->flags &= ~X86_EFLAGS_TF;
|
||||
|
||||
if (setup_rt_frame(sig, ka, info, regs) < 0) {
|
||||
force_sigsegv(sig, current);
|
||||
return;
|
||||
failed = (setup_rt_frame(ksig, regs) < 0);
|
||||
if (!failed) {
|
||||
/*
|
||||
* Clear the direction flag as per the ABI for function entry.
|
||||
*/
|
||||
regs->flags &= ~X86_EFLAGS_DF;
|
||||
/*
|
||||
* Clear TF when entering the signal handler, but
|
||||
* notify any tracer that was single-stepping it.
|
||||
* The tracer may want to single-step inside the
|
||||
* handler too.
|
||||
*/
|
||||
regs->flags &= ~X86_EFLAGS_TF;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the direction flag as per the ABI for function entry.
|
||||
*/
|
||||
regs->flags &= ~X86_EFLAGS_DF;
|
||||
|
||||
/*
|
||||
* Clear TF when entering the signal handler, but
|
||||
* notify any tracer that was single-stepping it.
|
||||
* The tracer may want to single-step inside the
|
||||
* handler too.
|
||||
*/
|
||||
regs->flags &= ~X86_EFLAGS_TF;
|
||||
|
||||
signal_delivered(sig, info, ka, regs,
|
||||
test_thread_flag(TIF_SINGLESTEP));
|
||||
signal_setup_done(failed, ksig, test_thread_flag(TIF_SINGLESTEP));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
@@ -757,14 +695,11 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
|
||||
*/
|
||||
static void do_signal(struct pt_regs *regs)
|
||||
{
|
||||
struct k_sigaction ka;
|
||||
siginfo_t info;
|
||||
int signr;
|
||||
struct ksignal ksig;
|
||||
|
||||
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
|
||||
if (signr > 0) {
|
||||
if (get_signal(&ksig)) {
|
||||
/* Whee! Actually deliver the signal. */
|
||||
handle_signal(signr, &info, &ka, regs);
|
||||
handle_signal(&ksig, regs);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -843,8 +778,9 @@ void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_X32_ABI
|
||||
asmlinkage long sys32_x32_rt_sigreturn(struct pt_regs *regs)
|
||||
asmlinkage long sys32_x32_rt_sigreturn(void)
|
||||
{
|
||||
struct pt_regs *regs = current_pt_regs();
|
||||
struct rt_sigframe_x32 __user *frame;
|
||||
sigset_t set;
|
||||
unsigned long ax;
|
||||
|
@@ -202,7 +202,7 @@ out:
|
||||
static int do_vm86_irq_handling(int subfunction, int irqnumber);
|
||||
static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk);
|
||||
|
||||
int sys_vm86old(struct vm86_struct __user *v86, struct pt_regs *regs)
|
||||
int sys_vm86old(struct vm86_struct __user *v86)
|
||||
{
|
||||
struct kernel_vm86_struct info; /* declare this _on top_,
|
||||
* this avoids wasting of stack space.
|
||||
@@ -222,7 +222,7 @@ int sys_vm86old(struct vm86_struct __user *v86, struct pt_regs *regs)
|
||||
if (tmp)
|
||||
goto out;
|
||||
memset(&info.vm86plus, 0, (int)&info.regs32 - (int)&info.vm86plus);
|
||||
info.regs32 = regs;
|
||||
info.regs32 = current_pt_regs();
|
||||
tsk->thread.vm86_info = v86;
|
||||
do_sys_vm86(&info, tsk);
|
||||
ret = 0; /* we never return here */
|
||||
@@ -231,7 +231,7 @@ out:
|
||||
}
|
||||
|
||||
|
||||
int sys_vm86(unsigned long cmd, unsigned long arg, struct pt_regs *regs)
|
||||
int sys_vm86(unsigned long cmd, unsigned long arg)
|
||||
{
|
||||
struct kernel_vm86_struct info; /* declare this _on top_,
|
||||
* this avoids wasting of stack space.
|
||||
@@ -272,7 +272,7 @@ int sys_vm86(unsigned long cmd, unsigned long arg, struct pt_regs *regs)
|
||||
ret = -EFAULT;
|
||||
if (tmp)
|
||||
goto out;
|
||||
info.regs32 = regs;
|
||||
info.regs32 = current_pt_regs();
|
||||
info.vm86plus.is_vm86pus = 1;
|
||||
tsk->thread.vm86_info = (struct vm86_struct __user *)v86;
|
||||
do_sys_vm86(&info, tsk);
|
||||
|
Reference in New Issue
Block a user