#include <linux/tty.h>
#include <linux/smp_lock.h>
#include <linux/binfmts.h>
+#include <linux/bitops.h>
#include <asm/uaccess.h>
-#include <asm/bitops.h>
#include <asm/ptrace.h>
#include <asm/svr4.h>
#include <asm/pgtable.h>
/* {set, get}context() needed for 64-bit SparcLinux userland. */
asmlinkage void sparc64_set_context(struct pt_regs *regs)
{
- struct ucontext *ucp = (struct ucontext __user *) regs->u_regs[UREG_I0];
+ struct ucontext __user *ucp = (struct ucontext __user *)
+ regs->u_regs[UREG_I0];
mc_gregset_t __user *grp;
unsigned long pc, npc, tstate;
unsigned long fp, i7;
regs->tnpc = npc;
err |= __get_user(regs->y, &((*grp)[MC_Y]));
err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
- regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC);
- regs->tstate |= (tstate & (TSTATE_ICC | TSTATE_XCC));
+ regs->tstate &= ~(TSTATE_ASI | TSTATE_ICC | TSTATE_XCC);
+ regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC));
err |= __get_user(regs->u_regs[UREG_G1], (&(*grp)[MC_G1]));
err |= __get_user(regs->u_regs[UREG_G2], (&(*grp)[MC_G2]));
err |= __get_user(regs->u_regs[UREG_G3], (&(*grp)[MC_G3]));
return;
do_sigsegv:
- do_exit(SIGSEGV);
+ force_sig(SIGSEGV, current);
}
asmlinkage void sparc64_get_context(struct pt_regs *regs)
{
- struct ucontext *ucp = (struct ucontext __user *) regs->u_regs[UREG_I0];
+ struct ucontext __user *ucp = (struct ucontext __user *)
+ regs->u_regs[UREG_I0];
mc_gregset_t __user *grp;
mcontext_t __user *mcp;
unsigned long fp, i7;
return;
do_sigsegv:
- do_exit(SIGSEGV);
+ force_sig(SIGSEGV, current);
}
struct rt_signal_frame {
err |= __get_user(tstate, &sf->regs.tstate);
err |= copy_from_user(regs->u_regs, sf->regs.u_regs, sizeof(regs->u_regs));
- /* User can only change condition codes in %tstate. */
- regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC);
- regs->tstate |= (tstate & (TSTATE_ICC | TSTATE_XCC));
+ /* User can only change condition codes and %asi in %tstate. */
+ regs->tstate &= ~(TSTATE_ASI | TSTATE_ICC | TSTATE_XCC);
+ regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC));
err |= __get_user(fpu_save, &sf->fpu_save);
if (fpu_save)
call it and ignore errors. */
old_fs = get_fs();
set_fs(KERNEL_DS);
- do_sigaltstack(&st, NULL, (unsigned long)sf);
+ do_sigaltstack((const stack_t __user *) &st, NULL, (unsigned long)sf);
set_fs(old_fs);
sigdelsetmask(&set, ~_BLOCKABLE);
spin_unlock_irq(¤t->sighand->siglock);
return;
segv:
- send_sig(SIGSEGV, current, 1);
+ force_sig(SIGSEGV, current);
}
/* Checks if the fp is valid */
regs->u_regs[UREG_I0] = signo;
regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
+ /* The sigcontext is passed in this way because of how it
+ * is defined in GLIBC's /usr/include/bits/sigcontext.h
+ * for sparc64. It includes the 128 bytes of siginfo_t.
+ */
+ regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
+
/* 5. signal handler */
regs->tpc = (unsigned long) ka->sa.sa_handler;
regs->tnpc = (regs->tpc + 4);
sigill:
do_exit(SIGILL);
sigsegv:
- do_exit(SIGSEGV);
+ force_sigsegv(signo, current);
}
static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
{
setup_rt_frame(ka, regs, signr, oldset,
(ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
- if (ka->sa.sa_flags & SA_ONESHOT)
- ka->sa.sa_handler = SIG_DFL;
if (!(ka->sa.sa_flags & SA_NOMASK)) {
spin_lock_irq(¤t->sighand->siglock);
sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
{
siginfo_t info;
struct signal_deliver_cookie cookie;
+ struct k_sigaction ka;
int signr;
cookie.restart_syscall = restart_syscall;
}
#endif
- signr = get_signal_to_deliver(&info, regs, &cookie);
+ signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
if (signr > 0) {
- struct k_sigaction *ka;
-
- ka = ¤t->sighand->action[signr-1];
-
if (cookie.restart_syscall)
- syscall_restart(orig_i0, regs, &ka->sa);
- handle_signal(signr, ka, &info, oldset, regs);
+ syscall_restart(orig_i0, regs, &ka.sa);
+ handle_signal(signr, &ka, &info, oldset, regs);
return 1;
}
if (cookie.restart_syscall &&