Commit 98c20309 authored by Richard Weinberger's avatar Richard Weinberger Committed by Richard Weinberger

ia64: Use get_signal() signal_setup_done()

Use the more generic functions get_signal() signal_setup_done()
for signal delivery.
This inverts also the return codes of force_sigsegv_info()
and setup_frame() to follow the kernel convention.
Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
parent ac443624
...@@ -309,12 +309,11 @@ force_sigsegv_info (int sig, void __user *addr) ...@@ -309,12 +309,11 @@ force_sigsegv_info (int sig, void __user *addr)
si.si_uid = from_kuid_munged(current_user_ns(), current_uid()); si.si_uid = from_kuid_munged(current_user_ns(), current_uid());
si.si_addr = addr; si.si_addr = addr;
force_sig_info(SIGSEGV, &si, current); force_sig_info(SIGSEGV, &si, current);
return 0; return 1;
} }
static long static long
setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, setup_frame(struct ksignal *ksig, sigset_t *set, struct sigscratch *scr)
struct sigscratch *scr)
{ {
extern char __kernel_sigtramp[]; extern char __kernel_sigtramp[];
unsigned long tramp_addr, new_rbs = 0, new_sp; unsigned long tramp_addr, new_rbs = 0, new_sp;
...@@ -323,7 +322,7 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, ...@@ -323,7 +322,7 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
new_sp = scr->pt.r12; new_sp = scr->pt.r12;
tramp_addr = (unsigned long) __kernel_sigtramp; tramp_addr = (unsigned long) __kernel_sigtramp;
if (ka->sa.sa_flags & SA_ONSTACK) { if (ksig->ka.sa.sa_flags & SA_ONSTACK) {
int onstack = sas_ss_flags(new_sp); int onstack = sas_ss_flags(new_sp);
if (onstack == 0) { if (onstack == 0) {
...@@ -347,29 +346,29 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, ...@@ -347,29 +346,29 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
*/ */
check_sp = (new_sp - sizeof(*frame)) & -STACK_ALIGN; check_sp = (new_sp - sizeof(*frame)) & -STACK_ALIGN;
if (!likely(on_sig_stack(check_sp))) if (!likely(on_sig_stack(check_sp)))
return force_sigsegv_info(sig, (void __user *) return force_sigsegv_info(ksig->sig, (void __user *)
check_sp); check_sp);
} }
} }
frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN); frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN);
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
return force_sigsegv_info(sig, frame); return force_sigsegv_info(ksig->sig, frame);
err = __put_user(sig, &frame->arg0); err = __put_user(ksig->sig, &frame->arg0);
err |= __put_user(&frame->info, &frame->arg1); err |= __put_user(&frame->info, &frame->arg1);
err |= __put_user(&frame->sc, &frame->arg2); err |= __put_user(&frame->sc, &frame->arg2);
err |= __put_user(new_rbs, &frame->sc.sc_rbs_base); err |= __put_user(new_rbs, &frame->sc.sc_rbs_base);
err |= __put_user(0, &frame->sc.sc_loadrs); /* initialize to zero */ err |= __put_user(0, &frame->sc.sc_loadrs); /* initialize to zero */
err |= __put_user(ka->sa.sa_handler, &frame->handler); err |= __put_user(ksig->ka.sa.sa_handler, &frame->handler);
err |= copy_siginfo_to_user(&frame->info, info); err |= copy_siginfo_to_user(&frame->info, &ksig->info);
err |= __save_altstack(&frame->sc.sc_stack, scr->pt.r12); err |= __save_altstack(&frame->sc.sc_stack, scr->pt.r12);
err |= setup_sigcontext(&frame->sc, set, scr); err |= setup_sigcontext(&frame->sc, set, scr);
if (unlikely(err)) if (unlikely(err))
return force_sigsegv_info(sig, frame); return force_sigsegv_info(ksig->sig, frame);
scr->pt.r12 = (unsigned long) frame - 16; /* new stack pointer */ scr->pt.r12 = (unsigned long) frame - 16; /* new stack pointer */
scr->pt.ar_fpsr = FPSR_DEFAULT; /* reset fpsr for signal handler */ scr->pt.ar_fpsr = FPSR_DEFAULT; /* reset fpsr for signal handler */
...@@ -394,22 +393,20 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, ...@@ -394,22 +393,20 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
#if DEBUG_SIG #if DEBUG_SIG
printk("SIG deliver (%s:%d): sig=%d sp=%lx ip=%lx handler=%p\n", printk("SIG deliver (%s:%d): sig=%d sp=%lx ip=%lx handler=%p\n",
current->comm, current->pid, sig, scr->pt.r12, frame->sc.sc_ip, frame->handler); current->comm, current->pid, ksig->sig, scr->pt.r12, frame->sc.sc_ip, frame->handler);
#endif #endif
return 1; return 0;
} }
static long static long
handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, handle_signal (struct ksignal *ksig, struct sigscratch *scr)
struct sigscratch *scr)
{ {
if (!setup_frame(sig, ka, info, sigmask_to_save(), scr)) int ret = setup_frame(ksig, sigmask_to_save(), scr);
return 0;
signal_delivered(sig, info, ka, &scr->pt, if (!ret)
test_thread_flag(TIF_SINGLESTEP)); signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
return 1; return ret;
} }
/* /*
...@@ -419,17 +416,16 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -419,17 +416,16 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
void void
ia64_do_signal (struct sigscratch *scr, long in_syscall) ia64_do_signal (struct sigscratch *scr, long in_syscall)
{ {
struct k_sigaction ka;
siginfo_t info;
long restart = in_syscall; long restart = in_syscall;
long errno = scr->pt.r8; long errno = scr->pt.r8;
struct ksignal ksig;
/* /*
* This only loops in the rare cases of handle_signal() failing, in which case we * This only loops in the rare cases of handle_signal() failing, in which case we
* need to push through a forced SIGSEGV. * need to push through a forced SIGSEGV.
*/ */
while (1) { while (1) {
int signr = get_signal_to_deliver(&info, &ka, &scr->pt, NULL); get_signal(&ksig);
/* /*
* get_signal_to_deliver() may have run a debugger (via notify_parent()) * get_signal_to_deliver() may have run a debugger (via notify_parent())
...@@ -446,7 +442,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) ...@@ -446,7 +442,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
*/ */
restart = 0; restart = 0;
if (signr <= 0) if (ksig.sig <= 0)
break; break;
if (unlikely(restart)) { if (unlikely(restart)) {
...@@ -458,7 +454,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) ...@@ -458,7 +454,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
break; break;
case ERESTARTSYS: case ERESTARTSYS:
if ((ka.sa.sa_flags & SA_RESTART) == 0) { if ((ksig.ka.sa.sa_flags & SA_RESTART) == 0) {
scr->pt.r8 = EINTR; scr->pt.r8 = EINTR;
/* note: scr->pt.r10 is already -1 */ /* note: scr->pt.r10 is already -1 */
break; break;
...@@ -473,7 +469,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) ...@@ -473,7 +469,7 @@ 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(&ksig, scr))
return; return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment