Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 
0003 #include <linux/signal.h>
0004 #include <linux/uaccess.h>
0005 #include <linux/syscalls.h>
0006 #include <linux/resume_user_mode.h>
0007 
0008 #include <asm/traps.h>
0009 #include <asm/ucontext.h>
0010 #include <asm/vdso.h>
0011 
0012 #include <abi/regdef.h>
0013 
0014 #ifdef CONFIG_CPU_HAS_FPU
0015 #include <abi/fpu.h>
0016 static int restore_fpu_state(struct sigcontext __user *sc)
0017 {
0018     int err = 0;
0019     struct user_fp user_fp;
0020 
0021     err = __copy_from_user(&user_fp, &sc->sc_user_fp, sizeof(user_fp));
0022 
0023     restore_from_user_fp(&user_fp);
0024 
0025     return err;
0026 }
0027 
0028 static int save_fpu_state(struct sigcontext __user *sc)
0029 {
0030     struct user_fp user_fp;
0031 
0032     save_to_user_fp(&user_fp);
0033 
0034     return __copy_to_user(&sc->sc_user_fp, &user_fp, sizeof(user_fp));
0035 }
0036 #else
0037 #define restore_fpu_state(sigcontext)   (0)
0038 #define save_fpu_state(sigcontext)  (0)
0039 #endif
0040 
0041 struct rt_sigframe {
0042     /*
0043      * pad[3] is compatible with the same struct defined in
0044      * gcc/libgcc/config/csky/linux-unwind.h
0045      */
0046     int pad[3];
0047     struct siginfo info;
0048     struct ucontext uc;
0049 };
0050 
0051 static long restore_sigcontext(struct pt_regs *regs,
0052     struct sigcontext __user *sc)
0053 {
0054     int err = 0;
0055     unsigned long sr = regs->sr;
0056 
0057     /* sc_pt_regs is structured the same as the start of pt_regs */
0058     err |= __copy_from_user(regs, &sc->sc_pt_regs, sizeof(struct pt_regs));
0059 
0060     /* BIT(0) of regs->sr is Condition Code/Carry bit */
0061     regs->sr = (sr & ~1) | (regs->sr & 1);
0062 
0063     /* Restore the floating-point state. */
0064     err |= restore_fpu_state(sc);
0065 
0066     return err;
0067 }
0068 
0069 SYSCALL_DEFINE0(rt_sigreturn)
0070 {
0071     struct pt_regs *regs = current_pt_regs();
0072     struct rt_sigframe __user *frame;
0073     sigset_t set;
0074 
0075     /* Always make any pending restarted system calls return -EINTR */
0076     current->restart_block.fn = do_no_restart_syscall;
0077 
0078     frame = (struct rt_sigframe __user *)regs->usp;
0079 
0080     if (!access_ok(frame, sizeof(*frame)))
0081         goto badframe;
0082 
0083     if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
0084         goto badframe;
0085 
0086     set_current_blocked(&set);
0087 
0088     if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
0089         goto badframe;
0090 
0091     if (restore_altstack(&frame->uc.uc_stack))
0092         goto badframe;
0093 
0094     return regs->a0;
0095 
0096 badframe:
0097     force_sig(SIGSEGV);
0098     return 0;
0099 }
0100 
0101 static int setup_sigcontext(struct rt_sigframe __user *frame,
0102     struct pt_regs *regs)
0103 {
0104     struct sigcontext __user *sc = &frame->uc.uc_mcontext;
0105     int err = 0;
0106 
0107     err |= __copy_to_user(&sc->sc_pt_regs, regs, sizeof(struct pt_regs));
0108     err |= save_fpu_state(sc);
0109 
0110     return err;
0111 }
0112 
0113 static inline void __user *get_sigframe(struct ksignal *ksig,
0114     struct pt_regs *regs, size_t framesize)
0115 {
0116     unsigned long sp;
0117     /* Default to using normal stack */
0118     sp = regs->usp;
0119 
0120     /*
0121      * If we are on the alternate signal stack and would overflow it, don't.
0122      * Return an always-bogus address instead so we will die with SIGSEGV.
0123      */
0124     if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
0125         return (void __user __force *)(-1UL);
0126 
0127     /* This is the X/Open sanctioned signal stack switching. */
0128     sp = sigsp(sp, ksig) - framesize;
0129 
0130     /* Align the stack frame. */
0131     sp &= -8UL;
0132 
0133     return (void __user *)sp;
0134 }
0135 
0136 static int
0137 setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
0138 {
0139     struct rt_sigframe __user *frame;
0140     int err = 0;
0141 
0142     frame = get_sigframe(ksig, regs, sizeof(*frame));
0143     if (!access_ok(frame, sizeof(*frame)))
0144         return -EFAULT;
0145 
0146     err |= copy_siginfo_to_user(&frame->info, &ksig->info);
0147 
0148     /* Create the ucontext. */
0149     err |= __put_user(0, &frame->uc.uc_flags);
0150     err |= __put_user(NULL, &frame->uc.uc_link);
0151     err |= __save_altstack(&frame->uc.uc_stack, regs->usp);
0152     err |= setup_sigcontext(frame, regs);
0153     err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
0154     if (err)
0155         return -EFAULT;
0156 
0157     /* Set up to return from userspace. */
0158     regs->lr = (unsigned long)VDSO_SYMBOL(
0159         current->mm->context.vdso, rt_sigreturn);
0160 
0161     /*
0162      * Set up registers for signal handler.
0163      * Registers that we don't modify keep the value they had from
0164      * user-space at the time we took the signal.
0165      * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
0166      * since some things rely on this (e.g. glibc's debug/segfault.c).
0167      */
0168     regs->pc  = (unsigned long)ksig->ka.sa.sa_handler;
0169     regs->usp = (unsigned long)frame;
0170     regs->a0  = ksig->sig;              /* a0: signal number */
0171     regs->a1  = (unsigned long)(&(frame->info));    /* a1: siginfo pointer */
0172     regs->a2  = (unsigned long)(&(frame->uc));  /* a2: ucontext pointer */
0173 
0174     return 0;
0175 }
0176 
0177 static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
0178 {
0179     sigset_t *oldset = sigmask_to_save();
0180     int ret;
0181 
0182     rseq_signal_deliver(ksig, regs);
0183 
0184     /* Are we from a system call? */
0185     if (in_syscall(regs)) {
0186         /* Avoid additional syscall restarting via ret_from_exception */
0187         forget_syscall(regs);
0188 
0189         /* If so, check system call restarting.. */
0190         switch (regs->a0) {
0191         case -ERESTART_RESTARTBLOCK:
0192         case -ERESTARTNOHAND:
0193             regs->a0 = -EINTR;
0194             break;
0195 
0196         case -ERESTARTSYS:
0197             if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
0198                 regs->a0 = -EINTR;
0199                 break;
0200             }
0201             fallthrough;
0202         case -ERESTARTNOINTR:
0203             regs->a0 = regs->orig_a0;
0204             regs->pc -= TRAP0_SIZE;
0205             break;
0206         }
0207     }
0208 
0209     /* Set up the stack frame */
0210     ret = setup_rt_frame(ksig, oldset, regs);
0211 
0212     signal_setup_done(ret, ksig, 0);
0213 }
0214 
0215 static void do_signal(struct pt_regs *regs)
0216 {
0217     struct ksignal ksig;
0218 
0219     if (get_signal(&ksig)) {
0220         /* Actually deliver the signal */
0221         handle_signal(&ksig, regs);
0222         return;
0223     }
0224 
0225     /* Did we come from a system call? */
0226     if (in_syscall(regs)) {
0227         /* Avoid additional syscall restarting via ret_from_exception */
0228         forget_syscall(regs);
0229 
0230         /* Restart the system call - no handlers present */
0231         switch (regs->a0) {
0232         case -ERESTARTNOHAND:
0233         case -ERESTARTSYS:
0234         case -ERESTARTNOINTR:
0235             regs->a0 = regs->orig_a0;
0236             regs->pc -= TRAP0_SIZE;
0237             break;
0238         case -ERESTART_RESTARTBLOCK:
0239             regs->a0 = regs->orig_a0;
0240             regs_syscallid(regs) = __NR_restart_syscall;
0241             regs->pc -= TRAP0_SIZE;
0242             break;
0243         }
0244     }
0245 
0246     /*
0247      * If there is no signal to deliver, we just put the saved
0248      * sigmask back.
0249      */
0250     restore_saved_sigmask();
0251 }
0252 
0253 /*
0254  * notification of userspace execution resumption
0255  * - triggered by the _TIF_WORK_MASK flags
0256  */
0257 asmlinkage void do_notify_resume(struct pt_regs *regs,
0258     unsigned long thread_info_flags)
0259 {
0260     if (thread_info_flags & _TIF_UPROBE)
0261         uprobe_notify_resume(regs);
0262 
0263     /* Handle pending signal delivery */
0264     if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
0265         do_signal(regs);
0266 
0267     if (thread_info_flags & _TIF_NOTIFY_RESUME)
0268         resume_user_mode_work(regs);
0269 }