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(unlikely(!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(to: regs, from: &sc->sc_regs, n: 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(cal_all: 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(to: &set, from: &frame->uc.uc_sigmask, n: sizeof(set))) |
248 | goto badframe; |
249 | |
250 | set_current_blocked(&set); |
251 | |
252 | if (restore_sigcontext(regs, sc: &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(to: &sc->sc_regs, from: regs, n: 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(cal_all: false); |
328 | |
329 | frame = get_sigframe(ksig, regs, framesize: frame_size); |
330 | if (!access_ok(frame, frame_size)) |
331 | return -EFAULT; |
332 | |
333 | err |= copy_siginfo_to_user(to: &frame->info, from: &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(to: &frame->uc.uc_sigmask, from: set, n: 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, set: oldset, regs); |
398 | |
399 | signal_setup_done(failed: ret, ksig, stepping: 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: &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: &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(cal_all: 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(cal_all: false); |
488 | } |
489 | #endif /* CONFIG_DYNAMIC_SIGFRAME */ |
490 | |