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:
@@ -124,6 +124,7 @@ ret_from_intr:
|
||||
lwi r11, r1, PT_MODE
|
||||
bneid r11, no_intr_resched
|
||||
|
||||
3:
|
||||
lwi r6, r31, TS_THREAD_INFO /* get thread info */
|
||||
lwi r19, r6, TI_FLAGS /* get flags in thread info */
|
||||
/* do an extra work if any bits are set */
|
||||
@@ -132,11 +133,13 @@ ret_from_intr:
|
||||
beqi r11, 1f
|
||||
bralid r15, schedule
|
||||
nop
|
||||
bri 3b
|
||||
1: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME
|
||||
beqid r11, no_intr_resched
|
||||
addk r5, r1, r0
|
||||
bralid r15, do_notify_resume
|
||||
addk r6, r0, r0
|
||||
bri 3b
|
||||
|
||||
no_intr_resched:
|
||||
/* Disable interrupts, we are now committed to the state restore */
|
||||
@@ -280,6 +283,7 @@ ENTRY(_user_exception)
|
||||
/* Figure out which function to use for this system call. */
|
||||
/* Note Microblaze barrel shift is optional, so don't rely on it */
|
||||
add r12, r12, r12 /* convert num -> ptr */
|
||||
addik r30, r0, 1 /* restarts allowed */
|
||||
add r12, r12, r12
|
||||
lwi r12, r12, sys_call_table /* Get function pointer */
|
||||
addik r15, r0, ret_to_user-8 /* set return address */
|
||||
@@ -369,6 +373,7 @@ ENTRY(_debug_exception)
|
||||
bralid r15, send_sig
|
||||
add r7, r0, r0 /* 3rd param zero */
|
||||
|
||||
addik r30, r0, 1 /* restarts allowed ??? */
|
||||
/* Restore r3/r4 to work around how ret_to_user works */
|
||||
lwi r3, r1, PT_R3
|
||||
lwi r4, r1, PT_R4
|
||||
@@ -482,18 +487,26 @@ ENTRY(ret_from_kernel_thread)
|
||||
addk r3, r0, r0
|
||||
|
||||
work_pending:
|
||||
lwi r11, r1, PT_MODE
|
||||
bneid r11, 2f
|
||||
3:
|
||||
enable_irq
|
||||
|
||||
andi r11, r19, _TIF_NEED_RESCHED
|
||||
beqi r11, 1f
|
||||
bralid r15, schedule
|
||||
nop
|
||||
bri 4f
|
||||
1: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME
|
||||
beqi r11, no_work_pending
|
||||
addk r5, r1, r0
|
||||
addk r5, r30, r0
|
||||
bralid r15, do_notify_resume
|
||||
addik r6, r0, 1
|
||||
bri no_work_pending
|
||||
addk r30, r0, r0 /* no restarts from now on */
|
||||
4:
|
||||
disable_irq
|
||||
lwi r6, r31, TS_THREAD_INFO /* get thread info */
|
||||
lwi r19, r6, TI_FLAGS /* get flags in thread info */
|
||||
bri 3b
|
||||
|
||||
ENTRY(ret_to_user)
|
||||
disable_irq
|
||||
@@ -507,6 +520,7 @@ ENTRY(ret_to_user)
|
||||
no_work_pending:
|
||||
disable_irq
|
||||
|
||||
2:
|
||||
/* save r31 */
|
||||
swi r31, r0, PER_CPU(CURRENT_SAVE)
|
||||
/* save mode indicator */
|
||||
@@ -559,6 +573,7 @@ no_work_pending:
|
||||
nop
|
||||
|
||||
sys_rt_sigreturn_wrapper:
|
||||
addk r30, r0, r0 /* no restarts for this one */
|
||||
brid sys_rt_sigreturn
|
||||
addk r5, r1, r0
|
||||
|
||||
|
@@ -354,6 +354,7 @@ C_ENTRY(_user_exception):
|
||||
/* Note Microblaze barrel shift is optional, so don't rely on it */
|
||||
add r12, r12, r12; /* convert num -> ptr */
|
||||
add r12, r12, r12;
|
||||
addi r30, r0, 1 /* restarts allowed */
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Trac syscalls and stored them to syscall_debug_table */
|
||||
@@ -401,26 +402,27 @@ C_ENTRY(ret_from_trap):
|
||||
* trigger rescheduling. */
|
||||
/* get thread info from current task */
|
||||
lwi r11, CURRENT_TASK, TS_THREAD_INFO;
|
||||
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
|
||||
andi r11, r11, _TIF_NEED_RESCHED;
|
||||
lwi r19, r11, TI_FLAGS; /* get flags in thread info */
|
||||
andi r11, r19, _TIF_NEED_RESCHED;
|
||||
beqi r11, 5f;
|
||||
|
||||
bralid r15, schedule; /* Call scheduler */
|
||||
nop; /* delay slot */
|
||||
bri 1b
|
||||
|
||||
/* Maybe handle a signal */
|
||||
5: /* get thread info from current task*/
|
||||
lwi r11, CURRENT_TASK, TS_THREAD_INFO;
|
||||
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
|
||||
andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
|
||||
beqi r11, 1f; /* Signals to handle, handle them */
|
||||
5:
|
||||
andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
|
||||
beqi r11, 4f; /* Signals to handle, handle them */
|
||||
|
||||
addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
|
||||
bralid r15, do_notify_resume; /* Handle any signals */
|
||||
addi r6, r0, 1; /* Arg 2: int in_syscall */
|
||||
add r6, r30, r0; /* Arg 2: int in_syscall */
|
||||
add r30, r0, r0 /* no more restarts */
|
||||
bri 1b
|
||||
|
||||
/* Finally, return to user state. */
|
||||
1: set_bip; /* Ints masked for state restore */
|
||||
4: set_bip; /* Ints masked for state restore */
|
||||
swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
|
||||
VM_OFF;
|
||||
tophys(r1,r1);
|
||||
@@ -464,6 +466,7 @@ C_ENTRY(ret_from_kernel_thread):
|
||||
add r3, r0, r0
|
||||
|
||||
C_ENTRY(sys_rt_sigreturn_wrapper):
|
||||
addik r30, r0, 0 /* no restarts */
|
||||
brid sys_rt_sigreturn /* Do real work */
|
||||
addik r5, r1, 0; /* add user context as 1st arg */
|
||||
|
||||
@@ -571,20 +574,20 @@ C_ENTRY(ret_from_exc):
|
||||
|
||||
/* We're returning to user mode, so check for various conditions that
|
||||
trigger rescheduling. */
|
||||
1:
|
||||
lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
|
||||
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
|
||||
andi r11, r11, _TIF_NEED_RESCHED;
|
||||
lwi r19, r11, TI_FLAGS; /* get flags in thread info */
|
||||
andi r11, r19, _TIF_NEED_RESCHED;
|
||||
beqi r11, 5f;
|
||||
|
||||
/* Call the scheduler before returning from a syscall/trap. */
|
||||
bralid r15, schedule; /* Call scheduler */
|
||||
nop; /* delay slot */
|
||||
bri 1b
|
||||
|
||||
/* Maybe handle a signal */
|
||||
5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
|
||||
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
|
||||
andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
|
||||
beqi r11, 1f; /* Signals to handle, handle them */
|
||||
5: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
|
||||
beqi r11, 4f; /* Signals to handle, handle them */
|
||||
|
||||
/*
|
||||
* Handle a signal return; Pending signals should be in r18.
|
||||
@@ -600,9 +603,10 @@ C_ENTRY(ret_from_exc):
|
||||
addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
|
||||
bralid r15, do_notify_resume; /* Handle any signals */
|
||||
addi r6, r0, 0; /* Arg 2: int in_syscall */
|
||||
bri 1b
|
||||
|
||||
/* Finally, return to user state. */
|
||||
1: set_bip; /* Ints masked for state restore */
|
||||
4: set_bip; /* Ints masked for state restore */
|
||||
swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
|
||||
VM_OFF;
|
||||
tophys(r1,r1);
|
||||
@@ -682,22 +686,23 @@ ret_from_irq:
|
||||
lwi r11, r1, PT_MODE;
|
||||
bnei r11, 2f;
|
||||
|
||||
1:
|
||||
lwi r11, CURRENT_TASK, TS_THREAD_INFO;
|
||||
lwi r11, r11, TI_FLAGS; /* MS: get flags from thread info */
|
||||
andi r11, r11, _TIF_NEED_RESCHED;
|
||||
lwi r19, r11, TI_FLAGS; /* MS: get flags from thread info */
|
||||
andi r11, r19, _TIF_NEED_RESCHED;
|
||||
beqi r11, 5f
|
||||
bralid r15, schedule;
|
||||
nop; /* delay slot */
|
||||
bri 1b
|
||||
|
||||
/* Maybe handle a signal */
|
||||
5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* MS: get thread info */
|
||||
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
|
||||
andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
|
||||
5: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
|
||||
beqid r11, no_intr_resched
|
||||
/* Handle a signal return; Pending signals should be in r18. */
|
||||
addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
|
||||
bralid r15, do_notify_resume; /* Handle any signals */
|
||||
addi r6, r0, 0; /* Arg 2: int in_syscall */
|
||||
bri 1b
|
||||
|
||||
/* Finally, return to user state. */
|
||||
no_intr_resched:
|
||||
@@ -815,28 +820,29 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
|
||||
lwi r11, r1, PT_MODE;
|
||||
bnei r11, 2f;
|
||||
/* MS: Return to user space - gdb */
|
||||
1:
|
||||
/* Get current task ptr into r11 */
|
||||
lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
|
||||
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
|
||||
andi r11, r11, _TIF_NEED_RESCHED;
|
||||
lwi r19, r11, TI_FLAGS; /* get flags in thread info */
|
||||
andi r11, r19, _TIF_NEED_RESCHED;
|
||||
beqi r11, 5f;
|
||||
|
||||
/* Call the scheduler before returning from a syscall/trap. */
|
||||
bralid r15, schedule; /* Call scheduler */
|
||||
nop; /* delay slot */
|
||||
bri 1b
|
||||
|
||||
/* Maybe handle a signal */
|
||||
5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
|
||||
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
|
||||
andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
|
||||
beqi r11, 1f; /* Signals to handle, handle them */
|
||||
5: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
|
||||
beqi r11, 4f; /* Signals to handle, handle them */
|
||||
|
||||
addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
|
||||
bralid r15, do_notify_resume; /* Handle any signals */
|
||||
addi r6, r0, 0; /* Arg 2: int in_syscall */
|
||||
bri 1b
|
||||
|
||||
/* Finally, return to user state. */
|
||||
1: swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
|
||||
4: swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
|
||||
VM_OFF;
|
||||
tophys(r1,r1);
|
||||
/* MS: Restore all regs */
|
||||
|
@@ -164,29 +164,6 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
|
||||
tracehook_report_syscall_exit(regs, step);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static asmlinkage void syscall_trace(void)
|
||||
{
|
||||
if (!test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
return;
|
||||
if (!(current->ptrace & PT_PTRACED))
|
||||
return;
|
||||
/* The 0x80 provides a way for the tracing parent to distinguish
|
||||
between a syscall stop and SIGTRAP delivery */
|
||||
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
|
||||
? 0x80 : 0));
|
||||
/*
|
||||
* this isn't the same as continuing with a signal, but it will do
|
||||
* for normal use. strace only continues with a signal if the
|
||||
* stopping signal is not SIGTRAP. -brl
|
||||
*/
|
||||
if (current->exit_code) {
|
||||
send_sig(current->exit_code, current, 1);
|
||||
current->exit_code = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void ptrace_disable(struct task_struct *child)
|
||||
{
|
||||
/* nothing to do */
|
||||
|
@@ -41,13 +41,6 @@
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/syscalls.h>
|
||||
|
||||
asmlinkage long
|
||||
sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
return do_sigaltstack(uss, uoss, regs->r1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do a signal return; undo the signal stack.
|
||||
*/
|
||||
@@ -109,9 +102,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval))
|
||||
goto badframe;
|
||||
|
||||
/* It is more difficult to avoid calling this function than to
|
||||
call it and ignore errors. */
|
||||
if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1) == -EFAULT)
|
||||
if (restore_altstack(&frame->uc.uc_stack))
|
||||
goto badframe;
|
||||
|
||||
return rval;
|
||||
@@ -194,11 +185,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
/* Create the ucontext. */
|
||||
err |= __put_user(0, &frame->uc.uc_flags);
|
||||
err |= __put_user(NULL, &frame->uc.uc_link);
|
||||
err |= __put_user((void __user *)current->sas_ss_sp,
|
||||
&frame->uc.uc_stack.ss_sp);
|
||||
err |= __put_user(sas_ss_flags(regs->r1),
|
||||
&frame->uc.uc_stack.ss_flags);
|
||||
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
|
||||
err |= __save_altstack(&frame->uc.uc_stack, regs->r1);
|
||||
err |= setup_sigcontext(&frame->uc.uc_mcontext,
|
||||
regs, set->sig[0]);
|
||||
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
|
||||
@@ -356,15 +343,6 @@ static void do_signal(struct pt_regs *regs, int in_syscall)
|
||||
|
||||
asmlinkage void do_notify_resume(struct pt_regs *regs, int in_syscall)
|
||||
{
|
||||
/*
|
||||
* We want the common case to go fast, which
|
||||
* is why we may in certain cases get here from
|
||||
* kernel mode. Just return without doing anything
|
||||
* if so.
|
||||
*/
|
||||
if (kernel_mode(regs))
|
||||
return;
|
||||
|
||||
if (test_thread_flag(TIF_SIGPENDING))
|
||||
do_signal(regs, in_syscall);
|
||||
|
||||
|
Reference in New Issue
Block a user