0001
0002
0003
0004
0005 #include <linux/cache.h>
0006 #include <linux/sched.h>
0007 #include <linux/mm.h>
0008 #include <linux/smp.h>
0009 #include <linux/kernel.h>
0010 #include <linux/signal.h>
0011 #include <linux/errno.h>
0012 #include <linux/wait.h>
0013 #include <linux/ptrace.h>
0014 #include <linux/unistd.h>
0015 #include <linux/compat.h>
0016 #include <linux/bitops.h>
0017
0018 #include <asm/abi.h>
0019 #include <asm/asm.h>
0020 #include <asm/cacheflush.h>
0021 #include <asm/compat-signal.h>
0022 #include <asm/sim.h>
0023 #include <linux/uaccess.h>
0024 #include <asm/ucontext.h>
0025 #include <asm/fpu.h>
0026 #include <asm/cpu-features.h>
0027
0028 #include "signal-common.h"
0029
0030
0031
0032
0033 #define __NR_N32_restart_syscall 6214
0034
0035 extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
0036 extern int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
0037
0038 struct ucontextn32 {
0039 u32 uc_flags;
0040 s32 uc_link;
0041 compat_stack_t uc_stack;
0042 struct sigcontext uc_mcontext;
0043 compat_sigset_t uc_sigmask;
0044 };
0045
0046 struct rt_sigframe_n32 {
0047 u32 rs_ass[4];
0048 u32 rs_pad[2];
0049 struct compat_siginfo rs_info;
0050 struct ucontextn32 rs_uc;
0051 };
0052
0053 asmlinkage void sysn32_rt_sigreturn(void)
0054 {
0055 struct rt_sigframe_n32 __user *frame;
0056 struct pt_regs *regs;
0057 sigset_t set;
0058 int sig;
0059
0060 regs = current_pt_regs();
0061 frame = (struct rt_sigframe_n32 __user *)regs->regs[29];
0062 if (!access_ok(frame, sizeof(*frame)))
0063 goto badframe;
0064 if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
0065 goto badframe;
0066
0067 set_current_blocked(&set);
0068
0069 sig = restore_sigcontext(regs, &frame->rs_uc.uc_mcontext);
0070 if (sig < 0)
0071 goto badframe;
0072 else if (sig)
0073 force_sig(sig);
0074
0075 if (compat_restore_altstack(&frame->rs_uc.uc_stack))
0076 goto badframe;
0077
0078
0079
0080
0081 __asm__ __volatile__(
0082 "move\t$29, %0\n\t"
0083 "j\tsyscall_exit"
0084 :
0085 : "r" (regs));
0086
0087
0088 badframe:
0089 force_sig(SIGSEGV);
0090 }
0091
0092 static int setup_rt_frame_n32(void *sig_return, struct ksignal *ksig,
0093 struct pt_regs *regs, sigset_t *set)
0094 {
0095 struct rt_sigframe_n32 __user *frame;
0096 int err = 0;
0097
0098 frame = get_sigframe(ksig, regs, sizeof(*frame));
0099 if (!access_ok(frame, sizeof (*frame)))
0100 return -EFAULT;
0101
0102
0103 err |= copy_siginfo_to_user32(&frame->rs_info, &ksig->info);
0104
0105
0106 err |= __put_user(0, &frame->rs_uc.uc_flags);
0107 err |= __put_user(0, &frame->rs_uc.uc_link);
0108 err |= __compat_save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
0109 err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
0110 err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
0111
0112 if (err)
0113 return -EFAULT;
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125 regs->regs[ 4] = ksig->sig;
0126 regs->regs[ 5] = (unsigned long) &frame->rs_info;
0127 regs->regs[ 6] = (unsigned long) &frame->rs_uc;
0128 regs->regs[29] = (unsigned long) frame;
0129 regs->regs[31] = (unsigned long) sig_return;
0130 regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
0131
0132 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
0133 current->comm, current->pid,
0134 frame, regs->cp0_epc, regs->regs[31]);
0135
0136 return 0;
0137 }
0138
0139 struct mips_abi mips_abi_n32 = {
0140 .setup_rt_frame = setup_rt_frame_n32,
0141 .restart = __NR_N32_restart_syscall,
0142
0143 .off_sc_fpregs = offsetof(struct sigcontext, sc_fpregs),
0144 .off_sc_fpc_csr = offsetof(struct sigcontext, sc_fpc_csr),
0145 .off_sc_used_math = offsetof(struct sigcontext, sc_used_math),
0146
0147 .vdso = &vdso_image_n32,
0148 };