pull clearing RESTORE_SIGMASK into block_sigmask()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2012-05-21 23:42:15 -04:00
Родитель 5754f412a3
Коммит a610d6e672
34 изменённых файлов: 130 добавлений и 387 удалений

Просмотреть файл

@ -481,11 +481,6 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
return; return;
} }
block_sigmask(ka, sig); block_sigmask(ka, sig);
/* A signal was successfully delivered, and the
saved sigmask was stored on the signal frame,
and will be restored by sigreturn. So we can
simply clear the restore sigmask flag. */
clear_thread_flag(TIF_RESTORE_SIGMASK);
} }
static inline void static inline void

Просмотреть файл

@ -528,7 +528,7 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
/* /*
* OK, we're invoking a handler * OK, we're invoking a handler
*/ */
static int static void
handle_signal(unsigned long sig, struct k_sigaction *ka, handle_signal(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, struct pt_regs *regs) siginfo_t *info, struct pt_regs *regs)
{ {
@ -559,17 +559,14 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
if (ret != 0) { if (ret != 0) {
force_sigsegv(sig, tsk); force_sigsegv(sig, tsk);
return ret; return;
} }
/* /*
* Block the signal if we were successful. * Block the signal if we were successful.
*/ */
block_sigmask(ka, sig); block_sigmask(ka, sig);
tracehook_signal_handler(sig, info, ka, regs, 0); tracehook_signal_handler(sig, info, ka, regs, 0);
return 0;
} }
/* /*
@ -633,16 +630,7 @@ static void do_signal(struct pt_regs *regs, int syscall)
clear_thread_flag(TIF_SYSCALL_RESTARTSYS); clear_thread_flag(TIF_SYSCALL_RESTARTSYS);
} }
if (handle_signal(signr, &ka, &info, regs) == 0) { handle_signal(signr, &ka, &info, regs);
/*
* A signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag.
*/
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
}
return; return;
} }

Просмотреть файл

@ -238,16 +238,13 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
*/ */
ret |= !valid_user_regs(regs); ret |= !valid_user_regs(regs);
if (ret != 0) {
force_sigsegv(sig, current);
return;
}
/* /*
* Block the signal if we were successful. * Block the signal if we were successful.
*/ */
block_sigmask(ka, sig); if (ret != 0)
clear_thread_flag(TIF_RESTORE_SIGMASK); force_sigsegv(sig, current);
else
block_sigmask(ka, sig);
} }
/* /*

Просмотреть файл

@ -247,7 +247,7 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
/* /*
* OK, we're invoking a handler * OK, we're invoking a handler
*/ */
static int static void
handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
struct pt_regs *regs) struct pt_regs *regs)
{ {
@ -260,11 +260,12 @@ handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
/* set up the stack frame */ /* set up the stack frame */
ret = setup_rt_frame(sig, ka, info, sigmask_to_save(), regs); ret = setup_rt_frame(sig, ka, info, sigmask_to_save(), regs);
if (ret)
return;
if (ret == 0) block_sigmask(ka, sig);
block_sigmask(ka, sig); tracehook_signal_handler(sig, info, ka, regs,
test_thread_flag(TIF_SINGLESTEP));
return ret;
} }
/* /*
@ -290,18 +291,7 @@ asmlinkage void do_signal(struct pt_regs *regs)
signr = get_signal_to_deliver(&info, &ka, regs, NULL); signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) { if (signr > 0) {
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
if (handle_signal(signr, &info, &ka, regs) == 0) { handle_signal(signr, &info, &ka, regs);
/* a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag */
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
tracehook_signal_handler(signr, &info, &ka, regs,
test_thread_flag(TIF_SINGLESTEP));
}
return; return;
} }

Просмотреть файл

@ -248,7 +248,7 @@ do_restart:
/* /*
* handle the actual delivery of a signal to userspace * handle the actual delivery of a signal to userspace
*/ */
static int handle_signal(int sig, static void handle_signal(int sig,
siginfo_t *info, struct k_sigaction *ka, siginfo_t *info, struct k_sigaction *ka,
struct pt_regs *regs, int syscall) struct pt_regs *regs, int syscall)
{ {
@ -277,11 +277,10 @@ static int handle_signal(int sig,
} }
/* Set up the stack frame */ /* Set up the stack frame */
ret = setup_rt_frame(sig, ka, info, sigmask_to_save(), regs); if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0)
if (ret == 0) return;
block_sigmask(ka, sig); block_sigmask(ka, sig);
tracehook_signal_handler(sig, info, ka, regs, 0);
return ret;
} }
/* /*
@ -300,17 +299,7 @@ static void do_signal(struct pt_regs *regs, int syscall)
signr = get_signal_to_deliver(&info, &ka, regs, NULL); signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) { if (signr > 0) {
if (handle_signal(signr, &info, &ka, regs, syscall) == 0) { handle_signal(signr, &info, &ka, regs, syscall);
/* a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag */
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
tracehook_signal_handler(signr, &info, &ka, regs, 0);
}
return; return;
} }

Просмотреть файл

@ -415,7 +415,7 @@ give_sigsegv:
* OK, we're invoking a handler * OK, we're invoking a handler
*/ */
static inline int handle_signal(int canrestart, unsigned long sig, static inline void handle_signal(int canrestart, unsigned long sig,
siginfo_t *info, struct k_sigaction *ka, siginfo_t *info, struct k_sigaction *ka,
struct pt_regs *regs) struct pt_regs *regs)
{ {
@ -458,8 +458,6 @@ static inline int handle_signal(int canrestart, unsigned long sig,
if (ret == 0) if (ret == 0)
block_sigmask(ka, sig); block_sigmask(ka, sig);
return ret;
} }
/* /*
@ -492,15 +490,7 @@ void do_signal(int canrestart, struct pt_regs *regs)
signr = get_signal_to_deliver(&info, &ka, regs, NULL); signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) { if (signr > 0) {
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
if (handle_signal(canrestart, signr, &info, &ka, handle_signal(canrestart, signr, &info, &ka, regs);
regs)) {
/* a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag */
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
}
return; return;
} }

Просмотреть файл

@ -434,7 +434,7 @@ give_sigsegv:
} }
/* Invoke a signal handler to, well, handle the signal. */ /* Invoke a signal handler to, well, handle the signal. */
static inline int static inline void
handle_signal(int canrestart, unsigned long sig, handle_signal(int canrestart, unsigned long sig,
siginfo_t *info, struct k_sigaction *ka, siginfo_t *info, struct k_sigaction *ka,
struct pt_regs * regs) struct pt_regs * regs)
@ -491,8 +491,6 @@ handle_signal(int canrestart, unsigned long sig,
if (ret == 0) if (ret == 0)
block_sigmask(ka, sig); block_sigmask(ka, sig);
return ret;
} }
/* /*
@ -525,16 +523,7 @@ do_signal(int canrestart, struct pt_regs *regs)
if (signr > 0) { if (signr > 0) {
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
if (handle_signal(canrestart, signr, &info, &ka, handle_signal(canrestart, signr, &info, &ka, regs);
regs)) {
/* a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag */
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
}
return; return;
} }

Просмотреть файл

@ -426,7 +426,7 @@ give_sigsegv:
/* /*
* OK, we're invoking a handler * OK, we're invoking a handler
*/ */
static int handle_signal(unsigned long sig, siginfo_t *info, static void handle_signal(unsigned long sig, siginfo_t *info,
struct k_sigaction *ka) struct k_sigaction *ka)
{ {
sigset_t *oldset = sigmask_to_save(); sigset_t *oldset = sigmask_to_save();
@ -461,11 +461,12 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
else else
ret = setup_frame(sig, ka, oldset); ret = setup_frame(sig, ka, oldset);
if (ret == 0) if (ret)
block_sigmask(ka, sig); return;
return ret;
block_sigmask(ka, sig);
tracehook_signal_handler(sig, info, ka, __frame,
test_thread_flag(TIF_SINGLESTEP));
} /* end handle_signal() */ } /* end handle_signal() */
/*****************************************************************************/ /*****************************************************************************/
@ -495,18 +496,7 @@ static void do_signal(void)
signr = get_signal_to_deliver(&info, &ka, __frame, NULL); signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
if (signr > 0) { if (signr > 0) {
if (handle_signal(signr, &info, &ka) == 0) { handle_signal(signr, &info, &ka);
/* a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag */
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
tracehook_signal_handler(signr, &info, &ka, __frame,
test_thread_flag(TIF_SINGLESTEP));
}
return; return;
} }

Просмотреть файл

@ -442,10 +442,8 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
else else
ret = setup_frame(sig, ka, oldset, regs); ret = setup_frame(sig, ka, oldset, regs);
if (!ret) { if (!ret)
block_sigmask(ka, sig); block_sigmask(ka, sig);
clear_thread_flag(TIF_RESTORE_SIGMASK);
}
} }
/* /*

Просмотреть файл

@ -149,11 +149,9 @@ sigsegv:
/* /*
* Setup invocation of signal handler * Setup invocation of signal handler
*/ */
static int handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
struct pt_regs *regs) struct pt_regs *regs)
{ {
int rc;
/* /*
* If we're handling a signal that aborted a system call, * If we're handling a signal that aborted a system call,
* set up the error return value before adding the signal * set up the error return value before adding the signal
@ -186,15 +184,13 @@ static int handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
* Set up the stack frame; not doing the SA_SIGINFO thing. We * Set up the stack frame; not doing the SA_SIGINFO thing. We
* only set up the rt_frame flavor. * only set up the rt_frame flavor.
*/ */
rc = setup_rt_frame(sig, ka, info, sigmask_to_save(), regs);
/* If there was an error on setup, no signal was delivered. */ /* If there was an error on setup, no signal was delivered. */
if (rc) if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0)
return rc; return;
block_sigmask(ka, sig); block_sigmask(ka, sig);
tracehook_signal_handler(sig, info, ka, regs,
return 0; test_thread_flag(TIF_SINGLESTEP));
} }
/* /*
@ -215,17 +211,7 @@ static void do_signal(struct pt_regs *regs)
signo = get_signal_to_deliver(&info, &sigact, regs, NULL); signo = get_signal_to_deliver(&info, &sigact, regs, NULL);
if (signo > 0) { if (signo > 0) {
if (handle_signal(signo, &info, &sigact, regs) == 0) { handle_signal(signo, &info, &sigact, regs);
/*
* Successful delivery case. The saved sigmask is
* stored in the signal frame, and will be restored
* by sigreturn. We can clear the TIF flag.
*/
clear_thread_flag(TIF_RESTORE_SIGMASK);
tracehook_signal_handler(signo, &info, &sigact, regs,
test_thread_flag(TIF_SINGLESTEP));
}
return; return;
} }

Просмотреть файл

@ -501,16 +501,8 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
* Whee! Actually deliver the signal. If the delivery failed, we need to * Whee! Actually deliver the signal. If the delivery failed, we need to
* continue to iterate in this loop so we can deliver the SIGSEGV... * continue to iterate in this loop so we can deliver the SIGSEGV...
*/ */
if (handle_signal(signr, &ka, &info, scr)) { if (handle_signal(signr, &ka, &info, scr))
/*
* A signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TS_RESTORE_SIGMASK flag.
*/
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
return; return;
}
} }
/* Did we come from a system call? */ /* Did we come from a system call? */

Просмотреть файл

@ -267,7 +267,7 @@ static int prev_insn(struct pt_regs *regs)
* OK, we're invoking a handler * OK, we're invoking a handler
*/ */
static int static void
handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
struct pt_regs *regs) struct pt_regs *regs)
{ {
@ -295,10 +295,9 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
/* Set up the stack frame */ /* Set up the stack frame */
if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs)) if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs))
return -EFAULT; return;
block_sigmask(ka, sig); block_sigmask(ka, sig);
return 0;
} }
/* /*
@ -333,8 +332,7 @@ static void do_signal(struct pt_regs *regs)
*/ */
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
if (handle_signal(signr, &ka, &info, regs) == 0) handle_signal(signr, &ka, &info, regs);
clear_thread_flag(TIF_RESTORE_SIGMASK);
return; return;
} }

Просмотреть файл

@ -1147,8 +1147,6 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->sr &= ~0x8000; regs->sr &= ~0x8000;
send_sig(SIGTRAP, current, 1); send_sig(SIGTRAP, current, 1);
} }
clear_thread_flag(TIF_RESTORE_SIGMASK);
} }
/* /*

Просмотреть файл

@ -310,7 +310,7 @@ do_restart:
* OK, we're invoking a handler * OK, we're invoking a handler
*/ */
static int static void
handle_signal(unsigned long sig, struct k_sigaction *ka, handle_signal(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, struct pt_regs *regs) siginfo_t *info, struct pt_regs *regs)
{ {
@ -324,11 +324,9 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
ret = setup_rt_frame(sig, ka, NULL, oldset, regs); ret = setup_rt_frame(sig, ka, NULL, oldset, regs);
if (ret) if (ret)
return ret; return;
block_sigmask(ka, sig); block_sigmask(ka, sig);
return 0;
} }
/* /*
@ -356,16 +354,7 @@ static void do_signal(struct pt_regs *regs, int in_syscall)
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
if (in_syscall) if (in_syscall)
handle_restart(regs, &ka, 1); handle_restart(regs, &ka, 1);
if (!handle_signal(signr, &ka, &info, oldset, regs)) { handle_signal(signr, &ka, &info, regs);
/*
* A signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TS_RESTORE_SIGMASK flag.
*/
current_thread_info()->status &=
~TS_RESTORE_SIGMASK;
}
return; return;
} }

Просмотреть файл

@ -514,7 +514,7 @@ struct mips_abi mips_abi = {
.restart = __NR_restart_syscall .restart = __NR_restart_syscall
}; };
static int handle_signal(unsigned long sig, siginfo_t *info, static void handle_signal(unsigned long sig, siginfo_t *info,
struct k_sigaction *ka, struct pt_regs *regs) struct k_sigaction *ka, struct pt_regs *regs)
{ {
sigset_t *oldset = sigmask_to_save(); sigset_t *oldset = sigmask_to_save();
@ -551,11 +551,9 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
ka, regs, sig, oldset); ka, regs, sig, oldset);
if (ret) if (ret)
return ret; return;
block_sigmask(ka, sig); block_sigmask(ka, sig);
return ret;
} }
static void do_signal(struct pt_regs *regs) static void do_signal(struct pt_regs *regs)
@ -575,17 +573,7 @@ static void do_signal(struct pt_regs *regs)
signr = get_signal_to_deliver(&info, &ka, regs, NULL); signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) { if (signr > 0) {
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
if (handle_signal(signr, &info, &ka, regs) == 0) { handle_signal(signr, &info, &ka, regs);
/*
* A signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag.
*/
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
}
return; return;
} }

Просмотреть файл

@ -462,11 +462,12 @@ static int handle_signal(int sig,
ret = setup_rt_frame(sig, ka, info, oldset, regs); ret = setup_rt_frame(sig, ka, info, oldset, regs);
else else
ret = setup_frame(sig, ka, oldset, regs); ret = setup_frame(sig, ka, oldset, regs);
if (ret)
return;
if (ret == 0) block_sigmask(ka, sig);
block_sigmask(ka, sig); tracehook_signal_handler(sig, info, ka, regs,
test_thread_flag(TIF_SINGLESTEP));
return ret;
} }
/* /*
@ -486,15 +487,6 @@ static void do_signal(struct pt_regs *regs)
signr = get_signal_to_deliver(&info, &ka, regs, NULL); signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) { if (signr > 0) {
if (handle_signal(signr, &info, &ka, regs) == 0) { if (handle_signal(signr, &info, &ka, regs) == 0) {
/* a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag */
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
tracehook_signal_handler(signr, &info, &ka, regs,
test_thread_flag(TIF_SINGLESTEP));
} }
return; return;

Просмотреть файл

@ -263,8 +263,6 @@ handle_signal(unsigned long sig,
return; return;
block_sigmask(ka, sig); block_sigmask(ka, sig);
clear_thread_flag(TIF_RESTORE_SIGMASK);
tracehook_signal_handler(sig, info, ka, regs, tracehook_signal_handler(sig, info, ka, regs,
test_thread_flag(TIF_SINGLESTEP)); test_thread_flag(TIF_SINGLESTEP));
} }

Просмотреть файл

@ -459,6 +459,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
test_thread_flag(TIF_SINGLESTEP) || test_thread_flag(TIF_SINGLESTEP) ||
test_thread_flag(TIF_BLOCKSTEP)); test_thread_flag(TIF_BLOCKSTEP));
DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
regs->gr[28]);
return 1; return 1;
} }
@ -593,13 +596,8 @@ do_signal(struct pt_regs *regs, long in_syscall)
/* Whee! Actually deliver the signal. If the /* Whee! Actually deliver the signal. If the
delivery failed, we need to continue to iterate in delivery failed, we need to continue to iterate in
this loop so we can deliver the SIGSEGV... */ this loop so we can deliver the SIGSEGV... */
if (handle_signal(signr, &info, &ka, regs, in_syscall)) { if (handle_signal(signr, &info, &ka, regs, in_syscall))
DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
regs->gr[28]);
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
return; return;
}
} }
/* end of while(1) looping forever if we can't force a signal */ /* end of while(1) looping forever if we can't force a signal */

Просмотреть файл

@ -159,13 +159,6 @@ static int do_signal(struct pt_regs *regs)
regs->trap = 0; regs->trap = 0;
if (ret) { if (ret) {
block_sigmask(&ka, signr); block_sigmask(&ka, signr);
/*
* A signal was successfully delivered; the saved sigmask is in
* its frame, and we can clear the TLF_RESTORE_SIGMASK flag.
*/
current_thread_info()->local_flags &= ~_TLF_RESTORE_SIGMASK;
/* /*
* Let tracing know that we've done the handler setup. * Let tracing know that we've done the handler setup.
*/ */

Просмотреть файл

@ -572,7 +572,7 @@ give_sigsegv:
* OK, we're invoking a handler * OK, we're invoking a handler
*/ */
int handle_signal32(unsigned long sig, struct k_sigaction *ka, void handle_signal32(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
{ {
int ret; int ret;
@ -583,8 +583,12 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
else else
ret = setup_frame32(sig, ka, oldset, regs); ret = setup_frame32(sig, ka, oldset, regs);
if (ret) if (ret)
return ret; return;
block_sigmask(ka, sig); block_sigmask(ka, sig);
return 0; /*
* Let tracing know that we've done the handler setup.
*/
tracehook_signal_handler(sig, info, ka, regs,
test_thread_flag(TIF_SINGLE_STEP));
} }

Просмотреть файл

@ -31,7 +31,7 @@ void do_per_trap(struct pt_regs *regs);
void syscall_trace(struct pt_regs *regs, int entryexit); void syscall_trace(struct pt_regs *regs, int entryexit);
void kernel_stack_overflow(struct pt_regs * regs); void kernel_stack_overflow(struct pt_regs * regs);
void do_signal(struct pt_regs *regs); void do_signal(struct pt_regs *regs);
int handle_signal32(unsigned long sig, struct k_sigaction *ka, void handle_signal32(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset, struct pt_regs *regs); siginfo_t *info, sigset_t *oldset, struct pt_regs *regs);
void do_notify_resume(struct pt_regs *regs); void do_notify_resume(struct pt_regs *regs);

Просмотреть файл

@ -367,7 +367,7 @@ give_sigsegv:
return -EFAULT; return -EFAULT;
} }
static int handle_signal(unsigned long sig, struct k_sigaction *ka, static void handle_signal(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset, siginfo_t *info, sigset_t *oldset,
struct pt_regs *regs) struct pt_regs *regs)
{ {
@ -379,9 +379,13 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
else else
ret = setup_frame(sig, ka, oldset, regs); ret = setup_frame(sig, ka, oldset, regs);
if (ret) if (ret)
return ret; return;
block_sigmask(ka, sig); block_sigmask(ka, sig);
return 0; /*
* Let tracing know that we've done the handler setup.
*/
tracehook_signal_handler(sig, info, ka, regs,
test_thread_flag(TIF_SINGLE_STEP));
} }
/* /*
@ -436,24 +440,10 @@ void do_signal(struct pt_regs *regs)
/* No longer in a system call */ /* No longer in a system call */
clear_thread_flag(TIF_SYSCALL); clear_thread_flag(TIF_SYSCALL);
if ((is_compat_task() ? if (is_compat_task())
handle_signal32(signr, &ka, &info, oldset, regs) : handle_signal32(signr, &ka, &info, oldset, regs);
handle_signal(signr, &ka, &info, oldset, regs)) == 0) { else
/* handle_signal(signr, &ka, &info, oldset, regs);
* A signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag.
*/
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
/*
* Let tracing know that we've done the handler setup.
*/
tracehook_signal_handler(signr, &info, &ka, regs,
test_thread_flag(TIF_SINGLE_STEP));
}
return; return;
} }

Просмотреть файл

@ -241,11 +241,9 @@ give_sigsegv:
return -EFAULT; return -EFAULT;
} }
static int handle_signal(unsigned long sig, siginfo_t *info, static void handle_signal(unsigned long sig, siginfo_t *info,
struct k_sigaction *ka, struct pt_regs *regs) struct k_sigaction *ka, struct pt_regs *regs)
{ {
int ret;
if (regs->is_syscall) { if (regs->is_syscall) {
switch (regs->regs[4]) { switch (regs->regs[4]) {
case ERESTART_RESTARTBLOCK: case ERESTART_RESTARTBLOCK:
@ -269,12 +267,10 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
/* /*
* Set up the stack frame * Set up the stack frame
*/ */
ret = setup_rt_frame(ka, regs, sig, sigmask_to_save(), info); if (setup_rt_frame(ka, regs, sig, sigmask_to_save(), info) < 0)
return;
if (ret == 0) block_sigmask(ka, sig);
block_sigmask(ka, sig);
return ret;
} }
static void do_signal(struct pt_regs *regs) static void do_signal(struct pt_regs *regs)
@ -294,17 +290,7 @@ static void do_signal(struct pt_regs *regs)
signr = get_signal_to_deliver(&info, &ka, regs, NULL); signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) { if (signr > 0) {
/* Actually deliver the signal. */ /* Actually deliver the signal. */
if (handle_signal(signr, &info, &ka, regs) == 0) { handle_signal(signr, &info, &ka, regs);
/*
* A signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag.
*/
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
}
return; return;
} }

Просмотреть файл

@ -522,7 +522,7 @@ handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs,
/* /*
* OK, we're invoking a handler * OK, we're invoking a handler
*/ */
static int static void
handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
struct pt_regs *regs, unsigned int save_r0) struct pt_regs *regs, unsigned int save_r0)
{ {
@ -535,10 +535,11 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
else else
ret = setup_frame(sig, ka, oldset, regs); ret = setup_frame(sig, ka, oldset, regs);
if (ret == 0) if (ret)
block_sigmask(ka, sig); return;
block_sigmask(ka, sig);
return ret; tracehook_signal_handler(sig, info, ka, regs,
test_thread_flag(TIF_SINGLESTEP));
} }
/* /*
@ -570,20 +571,7 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
handle_syscall_restart(save_r0, regs, &ka.sa); handle_syscall_restart(save_r0, regs, &ka.sa);
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
if (handle_signal(signr, &ka, &info, handle_signal(signr, &ka, &info, regs, save_r0);
regs, save_r0) == 0) {
/*
* A signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TS_RESTORE_SIGMASK flag
*/
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
tracehook_signal_handler(signr, &info, &ka, regs,
test_thread_flag(TIF_SINGLESTEP));
}
return; return;
} }

Просмотреть файл

@ -43,7 +43,7 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
static int static void
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
struct pt_regs * regs); struct pt_regs * regs);
@ -103,17 +103,7 @@ static void do_signal(struct pt_regs *regs)
handle_syscall_restart(regs, &ka.sa); handle_syscall_restart(regs, &ka.sa);
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
if (handle_signal(signr, &info, &ka, regs) == 0) { handle_signal(signr, &info, &ka, regs);
/*
* If a signal was successfully delivered, the
* saved sigmask is in its frame, and we can
* clear the TS_RESTORE_SIGMASK flag.
*/
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
tracehook_signal_handler(signr, &info, &ka, regs,
test_thread_flag(TIF_SINGLESTEP));
}
return; return;
} }
@ -648,7 +638,7 @@ give_sigsegv:
/* /*
* OK, we're invoking a handler * OK, we're invoking a handler
*/ */
static int static void
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
struct pt_regs * regs) struct pt_regs * regs)
{ {
@ -661,10 +651,12 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
else else
ret = setup_frame(sig, ka, oldset, regs); ret = setup_frame(sig, ka, oldset, regs);
if (ret == 0) if (ret)
block_sigmask(ka, sig); return;
return ret; block_sigmask(ka, sig);
tracehook_signal_handler(sig, info, ka, regs,
test_thread_flag(TIF_SINGLESTEP));
} }
asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)

Просмотреть файл

@ -775,7 +775,7 @@ sigsegv:
return -EFAULT; return -EFAULT;
} }
static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka, static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
siginfo_t *info, siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs) sigset_t *oldset, struct pt_regs *regs)
{ {
@ -787,12 +787,10 @@ static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka,
err = setup_frame32(ka, regs, signr, oldset); err = setup_frame32(ka, regs, signr, oldset);
if (err) if (err)
return err; return;
block_sigmask(ka, signr); block_sigmask(ka, signr);
tracehook_signal_handler(signr, info, ka, regs, 0); tracehook_signal_handler(signr, info, ka, regs, 0);
return 0;
} }
static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
@ -841,14 +839,7 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs)
if (signr > 0) { if (signr > 0) {
if (restart_syscall) if (restart_syscall)
syscall_restart32(orig_i0, regs, &ka.sa); syscall_restart32(orig_i0, regs, &ka.sa);
if (handle_signal32(signr, &ka, &info, oldset, regs) == 0) { handle_signal32(signr, &ka, &info, oldset, regs);
/* A signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TS_RESTORE_SIGMASK flag.
*/
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
}
return; return;
} }
if (restart_syscall && if (restart_syscall &&

Просмотреть файл

@ -449,7 +449,7 @@ sigsegv:
return -EFAULT; return -EFAULT;
} }
static inline int static inline void
handle_signal(unsigned long signr, struct k_sigaction *ka, handle_signal(unsigned long signr, struct k_sigaction *ka,
siginfo_t *info, struct pt_regs *regs) siginfo_t *info, struct pt_regs *regs)
{ {
@ -462,12 +462,10 @@ handle_signal(unsigned long signr, struct k_sigaction *ka,
err = setup_frame(ka, regs, signr, oldset); err = setup_frame(ka, regs, signr, oldset);
if (err) if (err)
return err; return;
block_sigmask(ka, signr); block_sigmask(ka, signr);
tracehook_signal_handler(signr, info, ka, regs, 0); tracehook_signal_handler(signr, info, ka, regs, 0);
return 0;
} }
static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
@ -539,15 +537,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
if (signr > 0) { if (signr > 0) {
if (restart_syscall) if (restart_syscall)
syscall_restart(orig_i0, regs, &ka.sa); syscall_restart(orig_i0, regs, &ka.sa);
if (handle_signal(signr, &ka, &info, regs) == 0) { handle_signal(signr, &ka, &info, regs);
/* a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag.
*/
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
}
return; return;
} }
if (restart_syscall && if (restart_syscall &&

Просмотреть файл

@ -466,7 +466,7 @@ sigsegv:
return -EFAULT; return -EFAULT;
} }
static inline int handle_signal(unsigned long signr, struct k_sigaction *ka, static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
siginfo_t *info, siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs) sigset_t *oldset, struct pt_regs *regs)
{ {
@ -475,12 +475,10 @@ static inline int handle_signal(unsigned long signr, struct k_sigaction *ka,
err = setup_rt_frame(ka, regs, signr, oldset, err = setup_rt_frame(ka, regs, signr, oldset,
(ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
if (err) if (err)
return err; return;
block_sigmask(ka, signr); block_sigmask(ka, signr);
tracehook_signal_handler(signr, info, ka, regs, 0); tracehook_signal_handler(signr, info, ka, regs, 0);
return 0;
} }
static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
@ -558,14 +556,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
if (signr > 0) { if (signr > 0) {
if (restart_syscall) if (restart_syscall)
syscall_restart(orig_i0, regs, &ka.sa); syscall_restart(orig_i0, regs, &ka.sa);
if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { handle_signal(signr, &ka, &info, oldset, regs);
/* A signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TS_RESTORE_SIGMASK flag.
*/
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
}
return; return;
} }
if (restart_syscall && if (restart_syscall &&

Просмотреть файл

@ -242,7 +242,7 @@ give_sigsegv:
* OK, we're invoking a handler * OK, we're invoking a handler
*/ */
static int handle_signal(unsigned long sig, siginfo_t *info, static void handle_signal(unsigned long sig, siginfo_t *info,
struct k_sigaction *ka, struct k_sigaction *ka,
struct pt_regs *regs) struct pt_regs *regs)
{ {
@ -279,15 +279,9 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
else else
#endif #endif
ret = setup_rt_frame(sig, ka, info, oldset, regs); ret = setup_rt_frame(sig, ka, info, oldset, regs);
if (ret == 0) { if (ret)
/* This code is only called from system calls or from return;
* the work_pending path in the return-to-user code, and block_sigmask(ka, sig);
* either way we can re-enable interrupts unconditionally.
*/
block_sigmask(ka, sig);
}
return ret;
} }
/* /*
@ -311,16 +305,7 @@ void do_signal(struct pt_regs *regs)
signr = get_signal_to_deliver(&info, &ka, regs, NULL); signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) { if (signr > 0) {
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
if (handle_signal(signr, &info, &ka, regs) == 0) { handle_signal(signr, &info, &ka, regs);
/*
* A signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TS_RESTORE_SIGMASK flag.
*/
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
}
goto done; goto done;
} }

Просмотреть файл

@ -22,7 +22,7 @@ EXPORT_SYMBOL(unblock_signals);
/* /*
* OK, we're invoking a handler * OK, we're invoking a handler
*/ */
static int handle_signal(struct pt_regs *regs, unsigned long signr, static void handle_signal(struct pt_regs *regs, unsigned long signr,
struct k_sigaction *ka, siginfo_t *info) struct k_sigaction *ka, siginfo_t *info)
{ {
sigset_t *oldset = sigmask_to_save(); sigset_t *oldset = sigmask_to_save();
@ -66,8 +66,6 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
force_sigsegv(signr, current); force_sigsegv(signr, current);
else else
block_sigmask(ka, signr); block_sigmask(ka, signr);
return err;
} }
static int kern_do_signal(struct pt_regs *regs) static int kern_do_signal(struct pt_regs *regs)
@ -79,17 +77,7 @@ static int kern_do_signal(struct pt_regs *regs)
while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) { while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) {
handled_sig = 1; handled_sig = 1;
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
if (!handle_signal(regs, sig, &ka_copy, &info)) { handle_signal(regs, sig, &ka_copy, &info);
/*
* a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag
*/
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
break;
}
} }
/* Did we come from a system call? */ /* Did we come from a system call? */

Просмотреть файл

@ -312,7 +312,7 @@ static inline void setup_syscall_restart(struct pt_regs *regs)
/* /*
* OK, we're invoking a handler * OK, we're invoking a handler
*/ */
static int handle_signal(unsigned long sig, struct k_sigaction *ka, static void handle_signal(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, struct pt_regs *regs, int syscall) siginfo_t *info, struct pt_regs *regs, int syscall)
{ {
struct thread_info *thread = current_thread_info(); struct thread_info *thread = current_thread_info();
@ -363,15 +363,13 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
if (ret != 0) { if (ret != 0) {
force_sigsegv(sig, tsk); force_sigsegv(sig, tsk);
return ret; return;
} }
/* /*
* Block the signal if we were successful. * Block the signal if we were successful.
*/ */
block_sigmask(ka, sig); block_sigmask(ka, sig);
return 0;
} }
/* /*
@ -403,17 +401,7 @@ static void do_signal(struct pt_regs *regs, int syscall)
signr = get_signal_to_deliver(&info, &ka, regs, NULL); signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) { if (signr > 0) {
if (handle_signal(signr, &ka, &info, regs, syscall) handle_signal(signr, &ka, &info, regs, syscall);
== 0) {
/*
* A signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag.
*/
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
}
return; return;
} }

Просмотреть файл

@ -648,38 +648,27 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
{ {
int usig = signr_convert(sig); int usig = signr_convert(sig);
sigset_t *set = sigmask_to_save(); sigset_t *set = sigmask_to_save();
int ret;
/* Set up the stack frame */ /* Set up the stack frame */
if (is_ia32) { if (is_ia32) {
if (ka->sa.sa_flags & SA_SIGINFO) if (ka->sa.sa_flags & SA_SIGINFO)
ret = ia32_setup_rt_frame(usig, ka, info, set, regs); return ia32_setup_rt_frame(usig, ka, info, set, regs);
else else
ret = ia32_setup_frame(usig, ka, set, regs); return ia32_setup_frame(usig, ka, set, regs);
#ifdef CONFIG_X86_X32_ABI #ifdef CONFIG_X86_X32_ABI
} else if (is_x32) { } else if (is_x32) {
ret = x32_setup_rt_frame(usig, ka, info, return x32_setup_rt_frame(usig, ka, info,
(compat_sigset_t *)set, regs); (compat_sigset_t *)set, regs);
#endif #endif
} else { } else {
ret = __setup_rt_frame(sig, ka, info, set, regs); return __setup_rt_frame(sig, ka, info, set, regs);
} }
if (ret) {
force_sigsegv(sig, current);
return -EFAULT;
}
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
return ret;
} }
static int static void
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
struct pt_regs *regs) struct pt_regs *regs)
{ {
int ret;
/* Are we from a system call? */ /* Are we from a system call? */
if (syscall_get_nr(current, regs) >= 0) { if (syscall_get_nr(current, regs) >= 0) {
/* If so, check system call restarting.. */ /* If so, check system call restarting.. */
@ -710,10 +699,10 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
likely(test_and_clear_thread_flag(TIF_FORCED_TF))) likely(test_and_clear_thread_flag(TIF_FORCED_TF)))
regs->flags &= ~X86_EFLAGS_TF; regs->flags &= ~X86_EFLAGS_TF;
ret = setup_rt_frame(sig, ka, info, regs); if (setup_rt_frame(sig, ka, info, regs) < 0) {
force_sigsegv(sig, current);
if (ret) return;
return ret; }
/* /*
* Clear the direction flag as per the ABI for function entry. * Clear the direction flag as per the ABI for function entry.
@ -732,8 +721,6 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
tracehook_signal_handler(sig, info, ka, regs, tracehook_signal_handler(sig, info, ka, regs,
test_thread_flag(TIF_SINGLESTEP)); test_thread_flag(TIF_SINGLESTEP));
return 0;
} }
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32

Просмотреть файл

@ -499,7 +499,6 @@ static void do_signal(struct pt_regs *regs)
if (ret) if (ret)
return; return;
clear_thread_flag(TIF_RESTORE_SIGMASK);
block_sigmask(&ka, signr); block_sigmask(&ka, signr);
if (current->ptrace & PT_SINGLESTEP) if (current->ptrace & PT_SINGLESTEP)
task_pt_regs(current)->icountlevel = 1; task_pt_regs(current)->icountlevel = 1;

Просмотреть файл

@ -2382,6 +2382,12 @@ void block_sigmask(struct k_sigaction *ka, int signr)
{ {
sigset_t blocked; sigset_t blocked;
/* A signal was successfully delivered, and the
saved sigmask was stored on the signal frame,
and will be restored by sigreturn. So we can
simply clear the restore sigmask flag. */
clear_restore_sigmask();
sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask); sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
if (!(ka->sa.sa_flags & SA_NODEFER)) if (!(ka->sa.sa_flags & SA_NODEFER))
sigaddset(&blocked, signr); sigaddset(&blocked, signr);