root/arch/unicore32/kernel/signal.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. restore_sigframe
  2. __sys_rt_sigreturn
  3. setup_sigframe
  4. get_sigframe
  5. setup_return
  6. setup_frame
  7. setup_rt_frame
  8. setup_syscall_restart
  9. handle_signal
  10. do_signal
  11. do_notify_resume
  12. early_signal_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * linux/arch/unicore32/kernel/signal.c
   4  *
   5  * Code specific to PKUnity SoC and UniCore ISA
   6  *
   7  * Copyright (C) 2001-2010 GUAN Xue-tao
   8  */
   9 #include <linux/errno.h>
  10 #include <linux/signal.h>
  11 #include <linux/personality.h>
  12 #include <linux/uaccess.h>
  13 #include <linux/tracehook.h>
  14 #include <linux/elf.h>
  15 #include <linux/unistd.h>
  16 
  17 #include <asm/cacheflush.h>
  18 #include <asm/ucontext.h>
  19 
  20 /*
  21  * For UniCore syscalls, we encode the syscall number into the instruction.
  22  */
  23 #define SWI_SYS_SIGRETURN       (0xff000000) /* error number for new abi */
  24 #define SWI_SYS_RT_SIGRETURN    (0xff000000 | (__NR_rt_sigreturn))
  25 #define SWI_SYS_RESTART         (0xff000000 | (__NR_restart_syscall))
  26 
  27 #define KERN_SIGRETURN_CODE     (KUSER_VECPAGE_BASE + 0x00000500)
  28 #define KERN_RESTART_CODE       (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes))
  29 
  30 const unsigned long sigreturn_codes[3] = {
  31         SWI_SYS_SIGRETURN, SWI_SYS_RT_SIGRETURN,
  32 };
  33 
  34 const unsigned long syscall_restart_code[2] = {
  35         SWI_SYS_RESTART,        /* swi  __NR_restart_syscall */
  36         0x69efc004,             /* ldr  pc, [sp], #4 */
  37 };
  38 
  39 /*
  40  * Do a signal return; undo the signal stack.  These are aligned to 64-bit.
  41  */
  42 struct sigframe {
  43         struct ucontext uc;
  44         unsigned long retcode[2];
  45 };
  46 
  47 struct rt_sigframe {
  48         struct siginfo info;
  49         struct sigframe sig;
  50 };
  51 
  52 static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
  53 {
  54         sigset_t set;
  55         int err;
  56 
  57         err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
  58         if (err == 0)
  59                 set_current_blocked(&set);
  60 
  61         err |= __get_user(regs->UCreg_00, &sf->uc.uc_mcontext.regs.UCreg_00);
  62         err |= __get_user(regs->UCreg_01, &sf->uc.uc_mcontext.regs.UCreg_01);
  63         err |= __get_user(regs->UCreg_02, &sf->uc.uc_mcontext.regs.UCreg_02);
  64         err |= __get_user(regs->UCreg_03, &sf->uc.uc_mcontext.regs.UCreg_03);
  65         err |= __get_user(regs->UCreg_04, &sf->uc.uc_mcontext.regs.UCreg_04);
  66         err |= __get_user(regs->UCreg_05, &sf->uc.uc_mcontext.regs.UCreg_05);
  67         err |= __get_user(regs->UCreg_06, &sf->uc.uc_mcontext.regs.UCreg_06);
  68         err |= __get_user(regs->UCreg_07, &sf->uc.uc_mcontext.regs.UCreg_07);
  69         err |= __get_user(regs->UCreg_08, &sf->uc.uc_mcontext.regs.UCreg_08);
  70         err |= __get_user(regs->UCreg_09, &sf->uc.uc_mcontext.regs.UCreg_09);
  71         err |= __get_user(regs->UCreg_10, &sf->uc.uc_mcontext.regs.UCreg_10);
  72         err |= __get_user(regs->UCreg_11, &sf->uc.uc_mcontext.regs.UCreg_11);
  73         err |= __get_user(regs->UCreg_12, &sf->uc.uc_mcontext.regs.UCreg_12);
  74         err |= __get_user(regs->UCreg_13, &sf->uc.uc_mcontext.regs.UCreg_13);
  75         err |= __get_user(regs->UCreg_14, &sf->uc.uc_mcontext.regs.UCreg_14);
  76         err |= __get_user(regs->UCreg_15, &sf->uc.uc_mcontext.regs.UCreg_15);
  77         err |= __get_user(regs->UCreg_16, &sf->uc.uc_mcontext.regs.UCreg_16);
  78         err |= __get_user(regs->UCreg_17, &sf->uc.uc_mcontext.regs.UCreg_17);
  79         err |= __get_user(regs->UCreg_18, &sf->uc.uc_mcontext.regs.UCreg_18);
  80         err |= __get_user(regs->UCreg_19, &sf->uc.uc_mcontext.regs.UCreg_19);
  81         err |= __get_user(regs->UCreg_20, &sf->uc.uc_mcontext.regs.UCreg_20);
  82         err |= __get_user(regs->UCreg_21, &sf->uc.uc_mcontext.regs.UCreg_21);
  83         err |= __get_user(regs->UCreg_22, &sf->uc.uc_mcontext.regs.UCreg_22);
  84         err |= __get_user(regs->UCreg_23, &sf->uc.uc_mcontext.regs.UCreg_23);
  85         err |= __get_user(regs->UCreg_24, &sf->uc.uc_mcontext.regs.UCreg_24);
  86         err |= __get_user(regs->UCreg_25, &sf->uc.uc_mcontext.regs.UCreg_25);
  87         err |= __get_user(regs->UCreg_26, &sf->uc.uc_mcontext.regs.UCreg_26);
  88         err |= __get_user(regs->UCreg_fp, &sf->uc.uc_mcontext.regs.UCreg_fp);
  89         err |= __get_user(regs->UCreg_ip, &sf->uc.uc_mcontext.regs.UCreg_ip);
  90         err |= __get_user(regs->UCreg_sp, &sf->uc.uc_mcontext.regs.UCreg_sp);
  91         err |= __get_user(regs->UCreg_lr, &sf->uc.uc_mcontext.regs.UCreg_lr);
  92         err |= __get_user(regs->UCreg_pc, &sf->uc.uc_mcontext.regs.UCreg_pc);
  93         err |= __get_user(regs->UCreg_asr, &sf->uc.uc_mcontext.regs.UCreg_asr);
  94 
  95         err |= !valid_user_regs(regs);
  96 
  97         return err;
  98 }
  99 
 100 asmlinkage int __sys_rt_sigreturn(struct pt_regs *regs)
 101 {
 102         struct rt_sigframe __user *frame;
 103 
 104         /* Always make any pending restarted system calls return -EINTR */
 105         current->restart_block.fn = do_no_restart_syscall;
 106 
 107         /*
 108          * Since we stacked the signal on a 64-bit boundary,
 109          * then 'sp' should be word aligned here.  If it's
 110          * not, then the user is trying to mess with us.
 111          */
 112         if (regs->UCreg_sp & 7)
 113                 goto badframe;
 114 
 115         frame = (struct rt_sigframe __user *)regs->UCreg_sp;
 116 
 117         if (!access_ok(frame, sizeof(*frame)))
 118                 goto badframe;
 119 
 120         if (restore_sigframe(regs, &frame->sig))
 121                 goto badframe;
 122 
 123         if (restore_altstack(&frame->sig.uc.uc_stack))
 124                 goto badframe;
 125 
 126         return regs->UCreg_00;
 127 
 128 badframe:
 129         force_sig(SIGSEGV);
 130         return 0;
 131 }
 132 
 133 static int setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs,
 134                 sigset_t *set)
 135 {
 136         int err = 0;
 137 
 138         err |= __put_user(regs->UCreg_00, &sf->uc.uc_mcontext.regs.UCreg_00);
 139         err |= __put_user(regs->UCreg_01, &sf->uc.uc_mcontext.regs.UCreg_01);
 140         err |= __put_user(regs->UCreg_02, &sf->uc.uc_mcontext.regs.UCreg_02);
 141         err |= __put_user(regs->UCreg_03, &sf->uc.uc_mcontext.regs.UCreg_03);
 142         err |= __put_user(regs->UCreg_04, &sf->uc.uc_mcontext.regs.UCreg_04);
 143         err |= __put_user(regs->UCreg_05, &sf->uc.uc_mcontext.regs.UCreg_05);
 144         err |= __put_user(regs->UCreg_06, &sf->uc.uc_mcontext.regs.UCreg_06);
 145         err |= __put_user(regs->UCreg_07, &sf->uc.uc_mcontext.regs.UCreg_07);
 146         err |= __put_user(regs->UCreg_08, &sf->uc.uc_mcontext.regs.UCreg_08);
 147         err |= __put_user(regs->UCreg_09, &sf->uc.uc_mcontext.regs.UCreg_09);
 148         err |= __put_user(regs->UCreg_10, &sf->uc.uc_mcontext.regs.UCreg_10);
 149         err |= __put_user(regs->UCreg_11, &sf->uc.uc_mcontext.regs.UCreg_11);
 150         err |= __put_user(regs->UCreg_12, &sf->uc.uc_mcontext.regs.UCreg_12);
 151         err |= __put_user(regs->UCreg_13, &sf->uc.uc_mcontext.regs.UCreg_13);
 152         err |= __put_user(regs->UCreg_14, &sf->uc.uc_mcontext.regs.UCreg_14);
 153         err |= __put_user(regs->UCreg_15, &sf->uc.uc_mcontext.regs.UCreg_15);
 154         err |= __put_user(regs->UCreg_16, &sf->uc.uc_mcontext.regs.UCreg_16);
 155         err |= __put_user(regs->UCreg_17, &sf->uc.uc_mcontext.regs.UCreg_17);
 156         err |= __put_user(regs->UCreg_18, &sf->uc.uc_mcontext.regs.UCreg_18);
 157         err |= __put_user(regs->UCreg_19, &sf->uc.uc_mcontext.regs.UCreg_19);
 158         err |= __put_user(regs->UCreg_20, &sf->uc.uc_mcontext.regs.UCreg_20);
 159         err |= __put_user(regs->UCreg_21, &sf->uc.uc_mcontext.regs.UCreg_21);
 160         err |= __put_user(regs->UCreg_22, &sf->uc.uc_mcontext.regs.UCreg_22);
 161         err |= __put_user(regs->UCreg_23, &sf->uc.uc_mcontext.regs.UCreg_23);
 162         err |= __put_user(regs->UCreg_24, &sf->uc.uc_mcontext.regs.UCreg_24);
 163         err |= __put_user(regs->UCreg_25, &sf->uc.uc_mcontext.regs.UCreg_25);
 164         err |= __put_user(regs->UCreg_26, &sf->uc.uc_mcontext.regs.UCreg_26);
 165         err |= __put_user(regs->UCreg_fp, &sf->uc.uc_mcontext.regs.UCreg_fp);
 166         err |= __put_user(regs->UCreg_ip, &sf->uc.uc_mcontext.regs.UCreg_ip);
 167         err |= __put_user(regs->UCreg_sp, &sf->uc.uc_mcontext.regs.UCreg_sp);
 168         err |= __put_user(regs->UCreg_lr, &sf->uc.uc_mcontext.regs.UCreg_lr);
 169         err |= __put_user(regs->UCreg_pc, &sf->uc.uc_mcontext.regs.UCreg_pc);
 170         err |= __put_user(regs->UCreg_asr, &sf->uc.uc_mcontext.regs.UCreg_asr);
 171 
 172         err |= __put_user(current->thread.trap_no,
 173                         &sf->uc.uc_mcontext.trap_no);
 174         err |= __put_user(current->thread.error_code,
 175                         &sf->uc.uc_mcontext.error_code);
 176         err |= __put_user(current->thread.address,
 177                         &sf->uc.uc_mcontext.fault_address);
 178         err |= __put_user(set->sig[0], &sf->uc.uc_mcontext.oldmask);
 179 
 180         err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
 181 
 182         return err;
 183 }
 184 
 185 static inline void __user *get_sigframe(struct k_sigaction *ka,
 186                 struct pt_regs *regs, int framesize)
 187 {
 188         unsigned long sp = regs->UCreg_sp;
 189         void __user *frame;
 190 
 191         /*
 192          * This is the X/Open sanctioned signal stack switching.
 193          */
 194         if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
 195                 sp = current->sas_ss_sp + current->sas_ss_size;
 196 
 197         /*
 198          * ATPCS B01 mandates 8-byte alignment
 199          */
 200         frame = (void __user *)((sp - framesize) & ~7);
 201 
 202         /*
 203          * Check that we can actually write to the signal frame.
 204          */
 205         if (!access_ok(frame, framesize))
 206                 frame = NULL;
 207 
 208         return frame;
 209 }
 210 
 211 static int setup_return(struct pt_regs *regs, struct k_sigaction *ka,
 212              unsigned long __user *rc, void __user *frame, int usig)
 213 {
 214         unsigned long handler = (unsigned long)ka->sa.sa_handler;
 215         unsigned long retcode;
 216         unsigned long asr = regs->UCreg_asr & ~PSR_f;
 217 
 218         unsigned int idx = 0;
 219 
 220         if (ka->sa.sa_flags & SA_SIGINFO)
 221                 idx += 1;
 222 
 223         if (__put_user(sigreturn_codes[idx],   rc) ||
 224             __put_user(sigreturn_codes[idx+1], rc+1))
 225                 return 1;
 226 
 227         retcode = KERN_SIGRETURN_CODE + (idx << 2);
 228 
 229         regs->UCreg_00 = usig;
 230         regs->UCreg_sp = (unsigned long)frame;
 231         regs->UCreg_lr = retcode;
 232         regs->UCreg_pc = handler;
 233         regs->UCreg_asr = asr;
 234 
 235         return 0;
 236 }
 237 
 238 static int setup_frame(struct ksignal *ksig, sigset_t *set,
 239                        struct pt_regs *regs)
 240 {
 241         struct sigframe __user *frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
 242         int err = 0;
 243 
 244         if (!frame)
 245                 return 1;
 246 
 247         /*
 248          * Set uc.uc_flags to a value which sc.trap_no would never have.
 249          */
 250         err |= __put_user(0x5ac3c35a, &frame->uc.uc_flags);
 251 
 252         err |= setup_sigframe(frame, regs, set);
 253         if (err == 0)
 254                 err |= setup_return(regs, &ksig->ka, frame->retcode, frame,
 255                                     ksig->sig);
 256 
 257         return err;
 258 }
 259 
 260 static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 261                           struct pt_regs *regs)
 262 {
 263         struct rt_sigframe __user *frame =
 264                         get_sigframe(&ksig->ka, regs, sizeof(*frame));
 265         int err = 0;
 266 
 267         if (!frame)
 268                 return 1;
 269 
 270         err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 271 
 272         err |= __put_user(0, &frame->sig.uc.uc_flags);
 273         err |= __put_user(NULL, &frame->sig.uc.uc_link);
 274         err |= __save_altstack(&frame->sig.uc.uc_stack, regs->UCreg_sp);
 275         err |= setup_sigframe(&frame->sig, regs, set);
 276         if (err == 0)
 277                 err |= setup_return(regs, &ksig->ka, frame->sig.retcode, frame,
 278                                     ksig->sig);
 279 
 280         if (err == 0) {
 281                 /*
 282                  * For realtime signals we must also set the second and third
 283                  * arguments for the signal handler.
 284                  */
 285                 regs->UCreg_01 = (unsigned long)&frame->info;
 286                 regs->UCreg_02 = (unsigned long)&frame->sig.uc;
 287         }
 288 
 289         return err;
 290 }
 291 
 292 static inline void setup_syscall_restart(struct pt_regs *regs)
 293 {
 294         regs->UCreg_00 = regs->UCreg_ORIG_00;
 295         regs->UCreg_pc -= 4;
 296 }
 297 
 298 /*
 299  * OK, we're invoking a handler
 300  */
 301 static void handle_signal(struct ksignal *ksig, struct pt_regs *regs,
 302                           int syscall)
 303 {
 304         struct thread_info *thread = current_thread_info();
 305         sigset_t *oldset = sigmask_to_save();
 306         int usig = ksig->sig;
 307         int ret;
 308 
 309         /*
 310          * If we were from a system call, check for system call restarting...
 311          */
 312         if (syscall) {
 313                 switch (regs->UCreg_00) {
 314                 case -ERESTART_RESTARTBLOCK:
 315                 case -ERESTARTNOHAND:
 316                         regs->UCreg_00 = -EINTR;
 317                         break;
 318                 case -ERESTARTSYS:
 319                         if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
 320                                 regs->UCreg_00 = -EINTR;
 321                                 break;
 322                         }
 323                         /* fallthrough */
 324                 case -ERESTARTNOINTR:
 325                         setup_syscall_restart(regs);
 326                 }
 327         }
 328 
 329         /*
 330          * Set up the stack frame
 331          */
 332         if (ksig->ka.sa.sa_flags & SA_SIGINFO)
 333                 ret = setup_rt_frame(ksig, oldset, regs);
 334         else
 335                 ret = setup_frame(ksig, oldset, regs);
 336 
 337         /*
 338          * Check that the resulting registers are actually sane.
 339          */
 340         ret |= !valid_user_regs(regs);
 341 
 342         signal_setup_done(ret, ksig, 0);
 343 }
 344 
 345 /*
 346  * Note that 'init' is a special process: it doesn't get signals it doesn't
 347  * want to handle. Thus you cannot kill init even with a SIGKILL even by
 348  * mistake.
 349  *
 350  * Note that we go through the signals twice: once to check the signals that
 351  * the kernel can handle, and then we build all the user-level signal handling
 352  * stack-frames in one go after that.
 353  */
 354 static void do_signal(struct pt_regs *regs, int syscall)
 355 {
 356         struct ksignal ksig;
 357 
 358         /*
 359          * We want the common case to go fast, which
 360          * is why we may in certain cases get here from
 361          * kernel mode. Just return without doing anything
 362          * if so.
 363          */
 364         if (!user_mode(regs))
 365                 return;
 366 
 367         if (get_signal(&ksig)) {
 368                 handle_signal(&ksig, regs, syscall);
 369                 return;
 370         }
 371 
 372         /*
 373          * No signal to deliver to the process - restart the syscall.
 374          */
 375         if (syscall) {
 376                 if (regs->UCreg_00 == -ERESTART_RESTARTBLOCK) {
 377                                 u32 __user *usp;
 378 
 379                                 regs->UCreg_sp -= 4;
 380                                 usp = (u32 __user *)regs->UCreg_sp;
 381 
 382                                 if (put_user(regs->UCreg_pc, usp) == 0) {
 383                                         regs->UCreg_pc = KERN_RESTART_CODE;
 384                                 } else {
 385                                         regs->UCreg_sp += 4;
 386                                         force_sigsegv(0);
 387                                 }
 388                 }
 389                 if (regs->UCreg_00 == -ERESTARTNOHAND ||
 390                     regs->UCreg_00 == -ERESTARTSYS ||
 391                     regs->UCreg_00 == -ERESTARTNOINTR) {
 392                         setup_syscall_restart(regs);
 393                 }
 394         }
 395         /* If there's no signal to deliver, we just put the saved
 396          * sigmask back.
 397          */
 398         restore_saved_sigmask();
 399 }
 400 
 401 asmlinkage void do_notify_resume(struct pt_regs *regs,
 402                 unsigned int thread_flags, int syscall)
 403 {
 404         if (thread_flags & _TIF_SIGPENDING)
 405                 do_signal(regs, syscall);
 406 
 407         if (thread_flags & _TIF_NOTIFY_RESUME) {
 408                 clear_thread_flag(TIF_NOTIFY_RESUME);
 409                 tracehook_notify_resume(regs);
 410         }
 411 }
 412 
 413 /*
 414  * Copy signal return handlers into the vector page, and
 415  * set sigreturn to be a pointer to these.
 416  */
 417 void __init early_signal_init(void)
 418 {
 419         memcpy((void *)kuser_vecpage_to_vectors(KERN_SIGRETURN_CODE),
 420                         sigreturn_codes, sizeof(sigreturn_codes));
 421         memcpy((void *)kuser_vecpage_to_vectors(KERN_RESTART_CODE),
 422                         syscall_restart_code, sizeof(syscall_restart_code));
 423         /* Need not to flush icache, since early_trap_init will do it last. */
 424 }

/* [<][>][^][v][top][bottom][index][help] */