]> Git Repo - linux.git/blob - arch/riscv/kernel/signal.c
x86/config: Fix warning for 'make ARCH=x86_64 tinyconfig'
[linux.git] / arch / riscv / kernel / signal.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
4  *  Chen Liqin <[email protected]>
5  *  Lennox Wu <[email protected]>
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(&current->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, &current->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(&current->thread.vstate, regs);
91         put_cpu_vector_context();
92
93         /* Copy everything of vstate but datap. */
94         err = __copy_to_user(&state->v_state, &current->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         /* Copy everything of __sc_riscv_v_state except datap. */
123         err = __copy_from_user(&current->thread.vstate, &state->v_state,
124                                offsetof(struct __riscv_v_ext_state, datap));
125         if (unlikely(err))
126                 return err;
127
128         /* Copy the pointer datap itself. */
129         err = __get_user(datap, &state->v_state.datap);
130         if (unlikely(err))
131                 return err;
132         /*
133          * Copy the whole vector content from user space datap. Use
134          * copy_from_user to prevent information leak.
135          */
136         err = copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize);
137         if (unlikely(err))
138                 return err;
139
140         riscv_v_vstate_set_restore(current, regs);
141
142         return err;
143 }
144 #else
145 #define save_v_state(task, regs) (0)
146 #define __restore_v_state(task, regs) (0)
147 #endif
148
149 static long restore_sigcontext(struct pt_regs *regs,
150         struct sigcontext __user *sc)
151 {
152         void __user *sc_ext_ptr = &sc->sc_extdesc.hdr;
153         __u32 rsvd;
154         long err;
155         /* sc_regs is structured the same as the start of pt_regs */
156         err = __copy_from_user(regs, &sc->sc_regs, sizeof(sc->sc_regs));
157         if (unlikely(err))
158                 return err;
159
160         /* Restore the floating-point state. */
161         if (has_fpu()) {
162                 err = restore_fp_state(regs, &sc->sc_fpregs);
163                 if (unlikely(err))
164                         return err;
165         }
166
167         /* Check the reserved word before extensions parsing */
168         err = __get_user(rsvd, &sc->sc_extdesc.reserved);
169         if (unlikely(err))
170                 return err;
171         if (unlikely(rsvd))
172                 return -EINVAL;
173
174         while (!err) {
175                 __u32 magic, size;
176                 struct __riscv_ctx_hdr __user *head = sc_ext_ptr;
177
178                 err |= __get_user(magic, &head->magic);
179                 err |= __get_user(size, &head->size);
180                 if (unlikely(err))
181                         return err;
182
183                 sc_ext_ptr += sizeof(*head);
184                 switch (magic) {
185                 case END_MAGIC:
186                         if (size != END_HDR_SIZE)
187                                 return -EINVAL;
188
189                         return 0;
190                 case RISCV_V_MAGIC:
191                         if (!has_vector() || !riscv_v_vstate_query(regs) ||
192                             size != riscv_v_sc_size)
193                                 return -EINVAL;
194
195                         err = __restore_v_state(regs, sc_ext_ptr);
196                         break;
197                 default:
198                         return -EINVAL;
199                 }
200                 sc_ext_ptr = (void __user *)head + size;
201         }
202         return err;
203 }
204
205 static size_t get_rt_frame_size(bool cal_all)
206 {
207         struct rt_sigframe __user *frame;
208         size_t frame_size;
209         size_t total_context_size = 0;
210
211         frame_size = sizeof(*frame);
212
213         if (has_vector()) {
214                 if (cal_all || riscv_v_vstate_query(task_pt_regs(current)))
215                         total_context_size += riscv_v_sc_size;
216         }
217         /*
218          * Preserved a __riscv_ctx_hdr for END signal context header if an
219          * extension uses __riscv_extra_ext_header
220          */
221         if (total_context_size)
222                 total_context_size += sizeof(struct __riscv_ctx_hdr);
223
224         frame_size += total_context_size;
225
226         frame_size = round_up(frame_size, 16);
227         return frame_size;
228 }
229
230 SYSCALL_DEFINE0(rt_sigreturn)
231 {
232         struct pt_regs *regs = current_pt_regs();
233         struct rt_sigframe __user *frame;
234         struct task_struct *task;
235         sigset_t set;
236         size_t frame_size = get_rt_frame_size(false);
237
238         /* Always make any pending restarted system calls return -EINTR */
239         current->restart_block.fn = do_no_restart_syscall;
240
241         frame = (struct rt_sigframe __user *)regs->sp;
242
243         if (!access_ok(frame, frame_size))
244                 goto badframe;
245
246         if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
247                 goto badframe;
248
249         set_current_blocked(&set);
250
251         if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
252                 goto badframe;
253
254         if (restore_altstack(&frame->uc.uc_stack))
255                 goto badframe;
256
257         regs->cause = -1UL;
258
259         return regs->a0;
260
261 badframe:
262         task = current;
263         if (show_unhandled_signals) {
264                 pr_info_ratelimited(
265                         "%s[%d]: bad frame in %s: frame=%p pc=%p sp=%p\n",
266                         task->comm, task_pid_nr(task), __func__,
267                         frame, (void *)regs->epc, (void *)regs->sp);
268         }
269         force_sig(SIGSEGV);
270         return 0;
271 }
272
273 static long setup_sigcontext(struct rt_sigframe __user *frame,
274         struct pt_regs *regs)
275 {
276         struct sigcontext __user *sc = &frame->uc.uc_mcontext;
277         struct __riscv_ctx_hdr __user *sc_ext_ptr = &sc->sc_extdesc.hdr;
278         long err;
279
280         /* sc_regs is structured the same as the start of pt_regs */
281         err = __copy_to_user(&sc->sc_regs, regs, sizeof(sc->sc_regs));
282         /* Save the floating-point state. */
283         if (has_fpu())
284                 err |= save_fp_state(regs, &sc->sc_fpregs);
285         /* Save the vector state. */
286         if (has_vector() && riscv_v_vstate_query(regs))
287                 err |= save_v_state(regs, (void __user **)&sc_ext_ptr);
288         /* Write zero to fp-reserved space and check it on restore_sigcontext */
289         err |= __put_user(0, &sc->sc_extdesc.reserved);
290         /* And put END __riscv_ctx_hdr at the end. */
291         err |= __put_user(END_MAGIC, &sc_ext_ptr->magic);
292         err |= __put_user(END_HDR_SIZE, &sc_ext_ptr->size);
293
294         return err;
295 }
296
297 static inline void __user *get_sigframe(struct ksignal *ksig,
298         struct pt_regs *regs, size_t framesize)
299 {
300         unsigned long sp;
301         /* Default to using normal stack */
302         sp = regs->sp;
303
304         /*
305          * If we are on the alternate signal stack and would overflow it, don't.
306          * Return an always-bogus address instead so we will die with SIGSEGV.
307          */
308         if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
309                 return (void __user __force *)(-1UL);
310
311         /* This is the X/Open sanctioned signal stack switching. */
312         sp = sigsp(sp, ksig) - framesize;
313
314         /* Align the stack frame. */
315         sp &= ~0xfUL;
316
317         return (void __user *)sp;
318 }
319
320 static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
321         struct pt_regs *regs)
322 {
323         struct rt_sigframe __user *frame;
324         long err = 0;
325         unsigned long __maybe_unused addr;
326         size_t frame_size = get_rt_frame_size(false);
327
328         frame = get_sigframe(ksig, regs, frame_size);
329         if (!access_ok(frame, frame_size))
330                 return -EFAULT;
331
332         err |= copy_siginfo_to_user(&frame->info, &ksig->info);
333
334         /* Create the ucontext. */
335         err |= __put_user(0, &frame->uc.uc_flags);
336         err |= __put_user(NULL, &frame->uc.uc_link);
337         err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
338         err |= setup_sigcontext(frame, regs);
339         err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
340         if (err)
341                 return -EFAULT;
342
343         /* Set up to return from userspace. */
344 #ifdef CONFIG_MMU
345         regs->ra = (unsigned long)VDSO_SYMBOL(
346                 current->mm->context.vdso, rt_sigreturn);
347 #else
348         /*
349          * For the nommu case we don't have a VDSO.  Instead we push two
350          * instructions to call the rt_sigreturn syscall onto the user stack.
351          */
352         if (copy_to_user(&frame->sigreturn_code, __user_rt_sigreturn,
353                          sizeof(frame->sigreturn_code)))
354                 return -EFAULT;
355
356         addr = (unsigned long)&frame->sigreturn_code;
357         /* Make sure the two instructions are pushed to icache. */
358         flush_icache_range(addr, addr + sizeof(frame->sigreturn_code));
359
360         regs->ra = addr;
361 #endif /* CONFIG_MMU */
362
363         /*
364          * Set up registers for signal handler.
365          * Registers that we don't modify keep the value they had from
366          * user-space at the time we took the signal.
367          * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
368          * since some things rely on this (e.g. glibc's debug/segfault.c).
369          */
370         regs->epc = (unsigned long)ksig->ka.sa.sa_handler;
371         regs->sp = (unsigned long)frame;
372         regs->a0 = ksig->sig;                     /* a0: signal number */
373         regs->a1 = (unsigned long)(&frame->info); /* a1: siginfo pointer */
374         regs->a2 = (unsigned long)(&frame->uc);   /* a2: ucontext pointer */
375
376 #if DEBUG_SIG
377         pr_info("SIG deliver (%s:%d): sig=%d pc=%p ra=%p sp=%p\n",
378                 current->comm, task_pid_nr(current), ksig->sig,
379                 (void *)regs->epc, (void *)regs->ra, frame);
380 #endif
381
382         return 0;
383 }
384
385 static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
386 {
387         sigset_t *oldset = sigmask_to_save();
388         int ret;
389
390         rseq_signal_deliver(ksig, regs);
391
392         /* Set up the stack frame */
393         if (is_compat_task())
394                 ret = compat_setup_rt_frame(ksig, oldset, regs);
395         else
396                 ret = setup_rt_frame(ksig, oldset, regs);
397
398         signal_setup_done(ret, ksig, 0);
399 }
400
401 void arch_do_signal_or_restart(struct pt_regs *regs)
402 {
403         unsigned long continue_addr = 0, restart_addr = 0;
404         int retval = 0;
405         struct ksignal ksig;
406         bool syscall = (regs->cause == EXC_SYSCALL);
407
408         /* If we were from a system call, check for system call restarting */
409         if (syscall) {
410                 continue_addr = regs->epc;
411                 restart_addr = continue_addr - 4;
412                 retval = regs->a0;
413
414                 /* Avoid additional syscall restarting via ret_from_exception */
415                 regs->cause = -1UL;
416
417                 /*
418                  * Prepare for system call restart. We do this here so that a
419                  * debugger will see the already changed PC.
420                  */
421                 switch (retval) {
422                 case -ERESTARTNOHAND:
423                 case -ERESTARTSYS:
424                 case -ERESTARTNOINTR:
425                 case -ERESTART_RESTARTBLOCK:
426                         regs->a0 = regs->orig_a0;
427                         regs->epc = restart_addr;
428                         break;
429                 }
430         }
431
432         /*
433          * Get the signal to deliver. When running under ptrace, at this point
434          * the debugger may change all of our registers.
435          */
436         if (get_signal(&ksig)) {
437                 /*
438                  * Depending on the signal settings, we may need to revert the
439                  * decision to restart the system call, but skip this if a
440                  * debugger has chosen to restart at a different PC.
441                  */
442                 if (regs->epc == restart_addr &&
443                     (retval == -ERESTARTNOHAND ||
444                      retval == -ERESTART_RESTARTBLOCK ||
445                      (retval == -ERESTARTSYS &&
446                       !(ksig.ka.sa.sa_flags & SA_RESTART)))) {
447                         regs->a0 = -EINTR;
448                         regs->epc = continue_addr;
449                 }
450
451                 /* Actually deliver the signal */
452                 handle_signal(&ksig, regs);
453                 return;
454         }
455
456         /*
457          * Handle restarting a different system call. As above, if a debugger
458          * has chosen to restart at a different PC, ignore the restart.
459          */
460         if (syscall && regs->epc == restart_addr && retval == -ERESTART_RESTARTBLOCK)
461                 regs->a7 = __NR_restart_syscall;
462
463         /*
464          * If there is no signal to deliver, we just put the saved
465          * sigmask back.
466          */
467         restore_saved_sigmask();
468 }
469
470 void init_rt_signal_env(void);
471 void __init init_rt_signal_env(void)
472 {
473         riscv_v_sc_size = sizeof(struct __riscv_ctx_hdr) +
474                           sizeof(struct __sc_riscv_v_state) + riscv_v_vsize;
475         /*
476          * Determine the stack space required for guaranteed signal delivery.
477          * The signal_minsigstksz will be populated into the AT_MINSIGSTKSZ entry
478          * in the auxiliary array at process startup.
479          */
480         signal_minsigstksz = get_rt_frame_size(true);
481 }
482
483 #ifdef CONFIG_DYNAMIC_SIGFRAME
484 bool sigaltstack_size_valid(size_t ss_size)
485 {
486         return ss_size > get_rt_frame_size(false);
487 }
488 #endif /* CONFIG_DYNAMIC_SIGFRAME */
This page took 0.058902 seconds and 4 git commands to generate.