X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=arch%2Fmips%2Fkernel%2Fsignal_n32.c;h=eb7e05926ebe359592d8fb0bc7d01e545efe76b5;hb=94b849aaf6e22ab7bf54b0d0377a882d4892396d;hp=7ca2a078841fb65253d5e9aeec70b8dfcebbd5c9;hpb=59b8175c771040afcd4ad67022b0cc80c216b866;p=pandora-kernel.git diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c index 7ca2a078841f..2c5df818c65a 100644 --- a/arch/mips/kernel/signal_n32.c +++ b/arch/mips/kernel/signal_n32.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -29,6 +28,7 @@ #include #include +#include #include #include #include @@ -39,13 +39,13 @@ #include #include #include +#include #include "signal-common.h" /* * Including would give use the 64-bit syscall numbers ... */ -#define __NR_N32_rt_sigreturn 6211 #define __NR_N32_restart_syscall 6214 extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *); @@ -67,28 +67,14 @@ struct ucontextn32 { compat_sigset_t uc_sigmask; /* mask last for extensibility */ }; -#if ICACHE_REFILLS_WORKAROUND_WAR == 0 - struct rt_sigframe_n32 { u32 rs_ass[4]; /* argument save space for o32 */ - u32 rs_code[2]; /* signal trampoline */ - struct siginfo rs_info; + u32 rs_pad[2]; /* Was: signal trampoline */ + struct compat_siginfo rs_info; struct ucontextn32 rs_uc; }; -#else /* ICACHE_REFILLS_WORKAROUND_WAR */ - -struct rt_sigframe_n32 { - u32 rs_ass[4]; /* argument save space for o32 */ - u32 rs_pad[2]; - struct siginfo rs_info; - struct ucontextn32 rs_uc; - u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */ -}; - -#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */ - -extern void sigset_from_compat (sigset_t *set, compat_sigset_t *compat); +extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat); asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) { @@ -105,7 +91,7 @@ asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) unewset = (compat_sigset_t __user *) regs.regs[4]; if (copy_from_user(&uset, unewset, sizeof(uset))) return -EFAULT; - sigset_from_compat (&newset, &uset); + sigset_from_compat(&newset, &uset); sigdelsetmask(&newset, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); @@ -126,6 +112,7 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) sigset_t set; stack_t st; s32 sp; + int sig; frame = (struct rt_sigframe_n32 __user *) regs.regs[29]; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) @@ -139,8 +126,11 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - if (restore_sigcontext(®s, &frame->rs_uc.uc_mcontext)) + sig = restore_sigcontext(®s, &frame->rs_uc.uc_mcontext); + if (sig < 0) goto badframe; + else if (sig) + force_sig(sig, current); /* The ucontext contains a stack32_t, so we must convert! */ if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) @@ -169,7 +159,7 @@ badframe: force_sig(SIGSEGV, current); } -int setup_rt_frame_n32(struct k_sigaction * ka, +static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka, struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) { struct rt_sigframe_n32 __user *frame; @@ -180,10 +170,8 @@ int setup_rt_frame_n32(struct k_sigaction * ka, if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto give_sigsegv; - install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn); - /* Create siginfo. */ - err |= copy_siginfo_to_user(&frame->rs_info, info); + err |= copy_siginfo_to_user32(&frame->rs_info, info); /* Create the ucontext. */ err |= __put_user(0, &frame->rs_uc.uc_flags); @@ -215,7 +203,7 @@ int setup_rt_frame_n32(struct k_sigaction * ka, regs->regs[ 5] = (unsigned long) &frame->rs_info; regs->regs[ 6] = (unsigned long) &frame->rs_uc; regs->regs[29] = (unsigned long) frame; - regs->regs[31] = (unsigned long) frame->rs_code; + regs->regs[31] = (unsigned long) sig_return; regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", @@ -228,3 +216,10 @@ give_sigsegv: force_sigsegv(signr, current); return -EFAULT; } + +struct mips_abi mips_abi_n32 = { + .setup_rt_frame = setup_rt_frame_n32, + .rt_signal_return_offset = + offsetof(struct mips_vdso, n32_rt_signal_trampoline), + .restart = __NR_N32_restart_syscall +};