1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd. 4 * Chen Liqin <liqin.chen@sunplusct.com> 5 * Lennox Wu <lennox.wu@sunplusct.com> 6 * Copyright (C) 2012 Regents of the University of California 7 */ 8 9 #include <linux/compat.h> 10 #include <linux/signal.h> 11 #include <linux/uaccess.h> 12 #include <linux/syscalls.h> 13 #include <linux/resume_user_mode.h> 14 #include <linux/linkage.h> 15 #include <linux/entry-common.h> 16 17 #include <asm/ucontext.h> 18 #include <asm/vdso.h> 19 #include <asm/signal.h> 20 #include <asm/signal32.h> 21 #include <asm/switch_to.h> 22 #include <asm/vector.h> 23 #include <asm/csr.h> 24 #include <asm/cacheflush.h> 25 26 unsigned long signal_minsigstksz __ro_after_init; 27 28 extern u32 __user_rt_sigreturn[2]; 29 static size_t riscv_v_sc_size __ro_after_init; 30 31 #define DEBUG_SIG 0 32 33 struct rt_sigframe { 34 struct siginfo info; 35 struct ucontext uc; 36 #ifndef CONFIG_MMU 37 u32 sigreturn_code[2]; 38 #endif 39 }; 40 41 #ifdef CONFIG_FPU 42 static long restore_fp_state(struct pt_regs *regs, 43 union __riscv_fp_state __user *sc_fpregs) 44 { 45 long err; 46 struct __riscv_d_ext_state __user *state = &sc_fpregs->d; 47 48 err = __copy_from_user(¤t->thread.fstate, state, sizeof(*state)); 49 if (unlikely(err)) 50 return err; 51 52 fstate_restore(current, regs); 53 return 0; 54 } 55 56 static long save_fp_state(struct pt_regs *regs, 57 union __riscv_fp_state __user *sc_fpregs) 58 { 59 long err; 60 struct __riscv_d_ext_state __user *state = &sc_fpregs->d; 61 62 fstate_save(current, regs); 63 err = __copy_to_user(state, ¤t->thread.fstate, sizeof(*state)); 64 return err; 65 } 66 #else 67 #define save_fp_state(task, regs) (0) 68 #define restore_fp_state(task, regs) (0) 69 #endif 70 71 #ifdef CONFIG_RISCV_ISA_V 72 73 static long save_v_state(struct pt_regs *regs, void __user **sc_vec) 74 { 75 struct __riscv_ctx_hdr __user *hdr; 76 struct __sc_riscv_v_state __user *state; 77 void __user *datap; 78 long err; 79 80 hdr = *sc_vec; 81 /* Place state to the user's signal context space after the hdr */ 82 state = (struct __sc_riscv_v_state __user *)(hdr + 1); 83 /* Point datap right after the end of __sc_riscv_v_state */ 84 datap = state + 1; 85 86 /* datap is designed to be 16 byte aligned for better performance */ 87 WARN_ON(!IS_ALIGNED((unsigned long)datap, 16)); 88 89 get_cpu_vector_context(); 90 riscv_v_vstate_save(¤t->thread.vstate, regs); 91 put_cpu_vector_context(); 92 93 /* Copy everything of vstate but datap. */ 94 err = __copy_to_user(&state->v_state, ¤t->thread.vstate, 95 offsetof(struct __riscv_v_ext_state, datap)); 96 /* Copy the pointer datap itself. */ 97 err |= __put_user((__force void *)datap, &state->v_state.datap); 98 /* Copy the whole vector content to user space datap. */ 99 err |= __copy_to_user(datap, current->thread.vstate.datap, riscv_v_vsize); 100 /* Copy magic to the user space after saving all vector conetext */ 101 err |= __put_user(RISCV_V_MAGIC, &hdr->magic); 102 err |= __put_user(riscv_v_sc_size, &hdr->size); 103 if (unlikely(err)) 104 return err; 105 106 /* Only progress the sv_vec if everything has done successfully */ 107 *sc_vec += riscv_v_sc_size; 108 return 0; 109 } 110 111 /* 112 * Restore Vector extension context from the user's signal frame. This function 113 * assumes a valid extension header. So magic and size checking must be done by 114 * the caller. 115 */ 116 static long __restore_v_state(struct pt_regs *regs, void __user *sc_vec) 117 { 118 long err; 119 struct __sc_riscv_v_state __user *state = sc_vec; 120 void __user *datap; 121 122 /* 123 * Mark the vstate as clean prior performing the actual copy, 124 * to avoid getting the vstate incorrectly clobbered by the 125 * discarded vector state. 126 */ 127 riscv_v_vstate_set_restore(current, regs); 128 129 /* Copy everything of __sc_riscv_v_state except datap. */ 130 err = __copy_from_user(¤t->thread.vstate, &state->v_state, 131 offsetof(struct __riscv_v_ext_state, datap)); 132 if (unlikely(err)) 133 return err; 134 135 /* Copy the pointer datap itself. */ 136 err = __get_user(datap, &state->v_state.datap); 137 if (unlikely(err)) 138 return err; 139 /* 140 * Copy the whole vector content from user space datap. Use 141 * copy_from_user to prevent information leak. 142 */ 143 return copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize); 144 } 145 #else 146 #define save_v_state(task, regs) (0) 147 #define __restore_v_state(task, regs) (0) 148 #endif 149 150 static long restore_sigcontext(struct pt_regs *regs, 151 struct sigcontext __user *sc) 152 { 153 void __user *sc_ext_ptr = &sc->sc_extdesc.hdr; 154 __u32 rsvd; 155 long err; 156 /* sc_regs is structured the same as the start of pt_regs */ 157 err = __copy_from_user(regs, &sc->sc_regs, sizeof(sc->sc_regs)); 158 if (unlikely(err)) 159 return err; 160 161 /* Restore the floating-point state. */ 162 if (has_fpu()) { 163 err = restore_fp_state(regs, &sc->sc_fpregs); 164 if (unlikely(err)) 165 return err; 166 } 167 168 /* Check the reserved word before extensions parsing */ 169 err = __get_user(rsvd, &sc->sc_extdesc.reserved); 170 if (unlikely(err)) 171 return err; 172 if (unlikely(rsvd)) 173 return -EINVAL; 174 175 while (!err) { 176 __u32 magic, size; 177 struct __riscv_ctx_hdr __user *head = sc_ext_ptr; 178 179 err |= __get_user(magic, &head->magic); 180 err |= __get_user(size, &head->size); 181 if (unlikely(err)) 182 return err; 183 184 sc_ext_ptr += sizeof(*head); 185 switch (magic) { 186 case END_MAGIC: 187 if (size != END_HDR_SIZE) 188 return -EINVAL; 189 190 return 0; 191 case RISCV_V_MAGIC: 192 if (!has_vector() || !riscv_v_vstate_query(regs) || 193 size != riscv_v_sc_size) 194 return -EINVAL; 195 196 err = __restore_v_state(regs, sc_ext_ptr); 197 break; 198 default: 199 return -EINVAL; 200 } 201 sc_ext_ptr = (void __user *)head + size; 202 } 203 return err; 204 } 205 206 static size_t get_rt_frame_size(bool cal_all) 207 { 208 struct rt_sigframe __user *frame; 209 size_t frame_size; 210 size_t total_context_size = 0; 211 212 frame_size = sizeof(*frame); 213 214 if (has_vector()) { 215 if (cal_all || riscv_v_vstate_query(task_pt_regs(current))) 216 total_context_size += riscv_v_sc_size; 217 } 218 /* 219 * Preserved a __riscv_ctx_hdr for END signal context header if an 220 * extension uses __riscv_extra_ext_header 221 */ 222 if (total_context_size) 223 total_context_size += sizeof(struct __riscv_ctx_hdr); 224 225 frame_size += total_context_size; 226 227 frame_size = round_up(frame_size, 16); 228 return frame_size; 229 } 230 231 SYSCALL_DEFINE0(rt_sigreturn) 232 { 233 struct pt_regs *regs = current_pt_regs(); 234 struct rt_sigframe __user *frame; 235 struct task_struct *task; 236 sigset_t set; 237 size_t frame_size = get_rt_frame_size(false); 238 239 /* Always make any pending restarted system calls return -EINTR */ 240 current->restart_block.fn = do_no_restart_syscall; 241 242 frame = (struct rt_sigframe __user *)regs->sp; 243 244 if (!access_ok(frame, frame_size)) 245 goto badframe; 246 247 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 248 goto badframe; 249 250 set_current_blocked(&set); 251 252 if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 253 goto badframe; 254 255 if (restore_altstack(&frame->uc.uc_stack)) 256 goto badframe; 257 258 regs->cause = -1UL; 259 260 return regs->a0; 261 262 badframe: 263 task = current; 264 if (show_unhandled_signals) { 265 pr_info_ratelimited( 266 "%s[%d]: bad frame in %s: frame=%p pc=%p sp=%p\n", 267 task->comm, task_pid_nr(task), __func__, 268 frame, (void *)regs->epc, (void *)regs->sp); 269 } 270 force_sig(SIGSEGV); 271 return 0; 272 } 273 274 static long setup_sigcontext(struct rt_sigframe __user *frame, 275 struct pt_regs *regs) 276 { 277 struct sigcontext __user *sc = &frame->uc.uc_mcontext; 278 struct __riscv_ctx_hdr __user *sc_ext_ptr = &sc->sc_extdesc.hdr; 279 long err; 280 281 /* sc_regs is structured the same as the start of pt_regs */ 282 err = __copy_to_user(&sc->sc_regs, regs, sizeof(sc->sc_regs)); 283 /* Save the floating-point state. */ 284 if (has_fpu()) 285 err |= save_fp_state(regs, &sc->sc_fpregs); 286 /* Save the vector state. */ 287 if (has_vector() && riscv_v_vstate_query(regs)) 288 err |= save_v_state(regs, (void __user **)&sc_ext_ptr); 289 /* Write zero to fp-reserved space and check it on restore_sigcontext */ 290 err |= __put_user(0, &sc->sc_extdesc.reserved); 291 /* And put END __riscv_ctx_hdr at the end. */ 292 err |= __put_user(END_MAGIC, &sc_ext_ptr->magic); 293 err |= __put_user(END_HDR_SIZE, &sc_ext_ptr->size); 294 295 return err; 296 } 297 298 static inline void __user *get_sigframe(struct ksignal *ksig, 299 struct pt_regs *regs, size_t framesize) 300 { 301 unsigned long sp; 302 /* Default to using normal stack */ 303 sp = regs->sp; 304 305 /* 306 * If we are on the alternate signal stack and would overflow it, don't. 307 * Return an always-bogus address instead so we will die with SIGSEGV. 308 */ 309 if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) 310 return (void __user __force *)(-1UL); 311 312 /* This is the X/Open sanctioned signal stack switching. */ 313 sp = sigsp(sp, ksig) - framesize; 314 315 /* Align the stack frame. */ 316 sp &= ~0xfUL; 317 318 return (void __user *)sp; 319 } 320 321 static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, 322 struct pt_regs *regs) 323 { 324 struct rt_sigframe __user *frame; 325 long err = 0; 326 unsigned long __maybe_unused addr; 327 size_t frame_size = get_rt_frame_size(false); 328 329 frame = get_sigframe(ksig, regs, frame_size); 330 if (!access_ok(frame, frame_size)) 331 return -EFAULT; 332 333 err |= copy_siginfo_to_user(&frame->info, &ksig->info); 334 335 /* Create the ucontext. */ 336 err |= __put_user(0, &frame->uc.uc_flags); 337 err |= __put_user(NULL, &frame->uc.uc_link); 338 err |= __save_altstack(&frame->uc.uc_stack, regs->sp); 339 err |= setup_sigcontext(frame, regs); 340 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 341 if (err) 342 return -EFAULT; 343 344 /* Set up to return from userspace. */ 345 #ifdef CONFIG_MMU 346 regs->ra = (unsigned long)VDSO_SYMBOL( 347 current->mm->context.vdso, rt_sigreturn); 348 #else 349 /* 350 * For the nommu case we don't have a VDSO. Instead we push two 351 * instructions to call the rt_sigreturn syscall onto the user stack. 352 */ 353 if (copy_to_user(&frame->sigreturn_code, __user_rt_sigreturn, 354 sizeof(frame->sigreturn_code))) 355 return -EFAULT; 356 357 addr = (unsigned long)&frame->sigreturn_code; 358 /* Make sure the two instructions are pushed to icache. */ 359 flush_icache_range(addr, addr + sizeof(frame->sigreturn_code)); 360 361 regs->ra = addr; 362 #endif /* CONFIG_MMU */ 363 364 /* 365 * Set up registers for signal handler. 366 * Registers that we don't modify keep the value they had from 367 * user-space at the time we took the signal. 368 * We always pass siginfo and mcontext, regardless of SA_SIGINFO, 369 * since some things rely on this (e.g. glibc's debug/segfault.c). 370 */ 371 regs->epc = (unsigned long)ksig->ka.sa.sa_handler; 372 regs->sp = (unsigned long)frame; 373 regs->a0 = ksig->sig; /* a0: signal number */ 374 regs->a1 = (unsigned long)(&frame->info); /* a1: siginfo pointer */ 375 regs->a2 = (unsigned long)(&frame->uc); /* a2: ucontext pointer */ 376 377 #if DEBUG_SIG 378 pr_info("SIG deliver (%s:%d): sig=%d pc=%p ra=%p sp=%p\n", 379 current->comm, task_pid_nr(current), ksig->sig, 380 (void *)regs->epc, (void *)regs->ra, frame); 381 #endif 382 383 return 0; 384 } 385 386 static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) 387 { 388 sigset_t *oldset = sigmask_to_save(); 389 int ret; 390 391 rseq_signal_deliver(ksig, regs); 392 393 /* Set up the stack frame */ 394 if (is_compat_task()) 395 ret = compat_setup_rt_frame(ksig, oldset, regs); 396 else 397 ret = setup_rt_frame(ksig, oldset, regs); 398 399 signal_setup_done(ret, ksig, 0); 400 } 401 402 void arch_do_signal_or_restart(struct pt_regs *regs) 403 { 404 unsigned long continue_addr = 0, restart_addr = 0; 405 int retval = 0; 406 struct ksignal ksig; 407 bool syscall = (regs->cause == EXC_SYSCALL); 408 409 /* If we were from a system call, check for system call restarting */ 410 if (syscall) { 411 continue_addr = regs->epc; 412 restart_addr = continue_addr - 4; 413 retval = regs->a0; 414 415 /* Avoid additional syscall restarting via ret_from_exception */ 416 regs->cause = -1UL; 417 418 /* 419 * Prepare for system call restart. We do this here so that a 420 * debugger will see the already changed PC. 421 */ 422 switch (retval) { 423 case -ERESTARTNOHAND: 424 case -ERESTARTSYS: 425 case -ERESTARTNOINTR: 426 case -ERESTART_RESTARTBLOCK: 427 regs->a0 = regs->orig_a0; 428 regs->epc = restart_addr; 429 break; 430 } 431 } 432 433 /* 434 * Get the signal to deliver. When running under ptrace, at this point 435 * the debugger may change all of our registers. 436 */ 437 if (get_signal(&ksig)) { 438 /* 439 * Depending on the signal settings, we may need to revert the 440 * decision to restart the system call, but skip this if a 441 * debugger has chosen to restart at a different PC. 442 */ 443 if (regs->epc == restart_addr && 444 (retval == -ERESTARTNOHAND || 445 retval == -ERESTART_RESTARTBLOCK || 446 (retval == -ERESTARTSYS && 447 !(ksig.ka.sa.sa_flags & SA_RESTART)))) { 448 regs->a0 = -EINTR; 449 regs->epc = continue_addr; 450 } 451 452 /* Actually deliver the signal */ 453 handle_signal(&ksig, regs); 454 return; 455 } 456 457 /* 458 * Handle restarting a different system call. As above, if a debugger 459 * has chosen to restart at a different PC, ignore the restart. 460 */ 461 if (syscall && regs->epc == restart_addr && retval == -ERESTART_RESTARTBLOCK) 462 regs->a7 = __NR_restart_syscall; 463 464 /* 465 * If there is no signal to deliver, we just put the saved 466 * sigmask back. 467 */ 468 restore_saved_sigmask(); 469 } 470 471 void init_rt_signal_env(void); 472 void __init init_rt_signal_env(void) 473 { 474 riscv_v_sc_size = sizeof(struct __riscv_ctx_hdr) + 475 sizeof(struct __sc_riscv_v_state) + riscv_v_vsize; 476 /* 477 * Determine the stack space required for guaranteed signal delivery. 478 * The signal_minsigstksz will be populated into the AT_MINSIGSTKSZ entry 479 * in the auxiliary array at process startup. 480 */ 481 signal_minsigstksz = get_rt_frame_size(true); 482 } 483 484 #ifdef CONFIG_DYNAMIC_SIGFRAME 485 bool sigaltstack_size_valid(size_t ss_size) 486 { 487 return ss_size > get_rt_frame_size(false); 488 } 489 #endif /* CONFIG_DYNAMIC_SIGFRAME */ 490
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.