1 // SPDX-License-Identifier: GPL-2.0+
3 * Author: Hanlu Li <lihanlu@loongson.cn>
4 * Huacai Chen <chenhuacai@loongson.cn>
5 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
8 * Copyright (C) 1991, 1992 Linus Torvalds
9 * Copyright (C) 1994 - 2000 Ralf Baechle
10 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
11 * Copyright (C) 2014, Imagination Technologies Ltd.
13 #include <linux/audit.h>
14 #include <linux/cache.h>
15 #include <linux/context_tracking.h>
16 #include <linux/entry-common.h>
17 #include <linux/irqflags.h>
18 #include <linux/sched.h>
20 #include <linux/personality.h>
21 #include <linux/smp.h>
22 #include <linux/kernel.h>
23 #include <linux/signal.h>
24 #include <linux/errno.h>
25 #include <linux/wait.h>
26 #include <linux/ptrace.h>
27 #include <linux/unistd.h>
28 #include <linux/compiler.h>
29 #include <linux/syscalls.h>
30 #include <linux/uaccess.h>
33 #include <asm/cacheflush.h>
34 #include <asm/cpu-features.h>
37 #include <asm/ucontext.h>
41 # define DEBUGP(fmt, args...) printk("%s: " fmt, __func__, ##args)
43 # define DEBUGP(fmt, args...)
46 /* Make sure we will not lose FPU ownership */
47 #define lock_fpu_owner() ({ preempt_disable(); pagefault_disable(); })
48 #define unlock_fpu_owner() ({ pagefault_enable(); preempt_enable(); })
49 /* Make sure we will not lose LBT ownership */
50 #define lock_lbt_owner() ({ preempt_disable(); pagefault_disable(); })
51 #define unlock_lbt_owner() ({ pagefault_enable(); preempt_enable(); })
53 /* Assembly functions to move context to/from the FPU */
55 _save_fp_context(void __user *fpregs, void __user *fcc, void __user *csr);
57 _restore_fp_context(void __user *fpregs, void __user *fcc, void __user *csr);
59 _save_lsx_context(void __user *fpregs, void __user *fcc, void __user *fcsr);
61 _restore_lsx_context(void __user *fpregs, void __user *fcc, void __user *fcsr);
63 _save_lasx_context(void __user *fpregs, void __user *fcc, void __user *fcsr);
65 _restore_lasx_context(void __user *fpregs, void __user *fcc, void __user *fcsr);
67 #ifdef CONFIG_CPU_HAS_LBT
68 extern asmlinkage int _save_lbt_context(void __user *regs, void __user *eflags);
69 extern asmlinkage int _restore_lbt_context(void __user *regs, void __user *eflags);
70 extern asmlinkage int _save_ftop_context(void __user *ftop);
71 extern asmlinkage int _restore_ftop_context(void __user *ftop);
75 struct siginfo rs_info;
76 struct ucontext rs_uctx;
80 struct sctx_info *addr;
84 struct extctx_layout {
87 struct _ctx_layout fpu;
88 struct _ctx_layout lsx;
89 struct _ctx_layout lasx;
90 struct _ctx_layout lbt;
91 struct _ctx_layout end;
94 static void __user *get_ctx_through_ctxinfo(struct sctx_info *info)
96 return (void __user *)((char *)info + sizeof(struct sctx_info));
100 * Thread saved context copy to/from a signal context presumed to be on the
101 * user stack, and therefore accessed with appropriate macros from uaccess.h.
103 static int copy_fpu_to_sigcontext(struct fpu_context __user *ctx)
107 uint64_t __user *regs = (uint64_t *)&ctx->regs;
108 uint64_t __user *fcc = &ctx->fcc;
109 uint32_t __user *fcsr = &ctx->fcsr;
111 for (i = 0; i < NUM_FPU_REGS; i++) {
113 __put_user(get_fpr64(¤t->thread.fpu.fpr[i], 0),
116 err |= __put_user(current->thread.fpu.fcc, fcc);
117 err |= __put_user(current->thread.fpu.fcsr, fcsr);
122 static int copy_fpu_from_sigcontext(struct fpu_context __user *ctx)
127 uint64_t __user *regs = (uint64_t *)&ctx->regs;
128 uint64_t __user *fcc = &ctx->fcc;
129 uint32_t __user *fcsr = &ctx->fcsr;
131 for (i = 0; i < NUM_FPU_REGS; i++) {
132 err |= __get_user(fpr_val, ®s[i]);
133 set_fpr64(¤t->thread.fpu.fpr[i], 0, fpr_val);
135 err |= __get_user(current->thread.fpu.fcc, fcc);
136 err |= __get_user(current->thread.fpu.fcsr, fcsr);
141 static int copy_lsx_to_sigcontext(struct lsx_context __user *ctx)
145 uint64_t __user *regs = (uint64_t *)&ctx->regs;
146 uint64_t __user *fcc = &ctx->fcc;
147 uint32_t __user *fcsr = &ctx->fcsr;
149 for (i = 0; i < NUM_FPU_REGS; i++) {
150 err |= __put_user(get_fpr64(¤t->thread.fpu.fpr[i], 0),
152 err |= __put_user(get_fpr64(¤t->thread.fpu.fpr[i], 1),
155 err |= __put_user(current->thread.fpu.fcc, fcc);
156 err |= __put_user(current->thread.fpu.fcsr, fcsr);
161 static int copy_lsx_from_sigcontext(struct lsx_context __user *ctx)
166 uint64_t __user *regs = (uint64_t *)&ctx->regs;
167 uint64_t __user *fcc = &ctx->fcc;
168 uint32_t __user *fcsr = &ctx->fcsr;
170 for (i = 0; i < NUM_FPU_REGS; i++) {
171 err |= __get_user(fpr_val, ®s[2*i]);
172 set_fpr64(¤t->thread.fpu.fpr[i], 0, fpr_val);
173 err |= __get_user(fpr_val, ®s[2*i+1]);
174 set_fpr64(¤t->thread.fpu.fpr[i], 1, fpr_val);
176 err |= __get_user(current->thread.fpu.fcc, fcc);
177 err |= __get_user(current->thread.fpu.fcsr, fcsr);
182 static int copy_lasx_to_sigcontext(struct lasx_context __user *ctx)
186 uint64_t __user *regs = (uint64_t *)&ctx->regs;
187 uint64_t __user *fcc = &ctx->fcc;
188 uint32_t __user *fcsr = &ctx->fcsr;
190 for (i = 0; i < NUM_FPU_REGS; i++) {
191 err |= __put_user(get_fpr64(¤t->thread.fpu.fpr[i], 0),
193 err |= __put_user(get_fpr64(¤t->thread.fpu.fpr[i], 1),
195 err |= __put_user(get_fpr64(¤t->thread.fpu.fpr[i], 2),
197 err |= __put_user(get_fpr64(¤t->thread.fpu.fpr[i], 3),
200 err |= __put_user(current->thread.fpu.fcc, fcc);
201 err |= __put_user(current->thread.fpu.fcsr, fcsr);
206 static int copy_lasx_from_sigcontext(struct lasx_context __user *ctx)
211 uint64_t __user *regs = (uint64_t *)&ctx->regs;
212 uint64_t __user *fcc = &ctx->fcc;
213 uint32_t __user *fcsr = &ctx->fcsr;
215 for (i = 0; i < NUM_FPU_REGS; i++) {
216 err |= __get_user(fpr_val, ®s[4*i]);
217 set_fpr64(¤t->thread.fpu.fpr[i], 0, fpr_val);
218 err |= __get_user(fpr_val, ®s[4*i+1]);
219 set_fpr64(¤t->thread.fpu.fpr[i], 1, fpr_val);
220 err |= __get_user(fpr_val, ®s[4*i+2]);
221 set_fpr64(¤t->thread.fpu.fpr[i], 2, fpr_val);
222 err |= __get_user(fpr_val, ®s[4*i+3]);
223 set_fpr64(¤t->thread.fpu.fpr[i], 3, fpr_val);
225 err |= __get_user(current->thread.fpu.fcc, fcc);
226 err |= __get_user(current->thread.fpu.fcsr, fcsr);
231 #ifdef CONFIG_CPU_HAS_LBT
232 static int copy_lbt_to_sigcontext(struct lbt_context __user *ctx)
235 uint64_t __user *regs = (uint64_t *)&ctx->regs;
236 uint32_t __user *eflags = (uint32_t *)&ctx->eflags;
238 err |= __put_user(current->thread.lbt.scr0, ®s[0]);
239 err |= __put_user(current->thread.lbt.scr1, ®s[1]);
240 err |= __put_user(current->thread.lbt.scr2, ®s[2]);
241 err |= __put_user(current->thread.lbt.scr3, ®s[3]);
242 err |= __put_user(current->thread.lbt.eflags, eflags);
247 static int copy_lbt_from_sigcontext(struct lbt_context __user *ctx)
250 uint64_t __user *regs = (uint64_t *)&ctx->regs;
251 uint32_t __user *eflags = (uint32_t *)&ctx->eflags;
253 err |= __get_user(current->thread.lbt.scr0, ®s[0]);
254 err |= __get_user(current->thread.lbt.scr1, ®s[1]);
255 err |= __get_user(current->thread.lbt.scr2, ®s[2]);
256 err |= __get_user(current->thread.lbt.scr3, ®s[3]);
257 err |= __get_user(current->thread.lbt.eflags, eflags);
262 static int copy_ftop_to_sigcontext(struct lbt_context __user *ctx)
264 uint32_t __user *ftop = &ctx->ftop;
266 return __put_user(current->thread.fpu.ftop, ftop);
269 static int copy_ftop_from_sigcontext(struct lbt_context __user *ctx)
271 uint32_t __user *ftop = &ctx->ftop;
273 return __get_user(current->thread.fpu.ftop, ftop);
278 * Wrappers for the assembly _{save,restore}_fp_context functions.
280 static int save_hw_fpu_context(struct fpu_context __user *ctx)
282 uint64_t __user *regs = (uint64_t *)&ctx->regs;
283 uint64_t __user *fcc = &ctx->fcc;
284 uint32_t __user *fcsr = &ctx->fcsr;
286 return _save_fp_context(regs, fcc, fcsr);
289 static int restore_hw_fpu_context(struct fpu_context __user *ctx)
291 uint64_t __user *regs = (uint64_t *)&ctx->regs;
292 uint64_t __user *fcc = &ctx->fcc;
293 uint32_t __user *fcsr = &ctx->fcsr;
295 return _restore_fp_context(regs, fcc, fcsr);
298 static int save_hw_lsx_context(struct lsx_context __user *ctx)
300 uint64_t __user *regs = (uint64_t *)&ctx->regs;
301 uint64_t __user *fcc = &ctx->fcc;
302 uint32_t __user *fcsr = &ctx->fcsr;
304 return _save_lsx_context(regs, fcc, fcsr);
307 static int restore_hw_lsx_context(struct lsx_context __user *ctx)
309 uint64_t __user *regs = (uint64_t *)&ctx->regs;
310 uint64_t __user *fcc = &ctx->fcc;
311 uint32_t __user *fcsr = &ctx->fcsr;
313 return _restore_lsx_context(regs, fcc, fcsr);
316 static int save_hw_lasx_context(struct lasx_context __user *ctx)
318 uint64_t __user *regs = (uint64_t *)&ctx->regs;
319 uint64_t __user *fcc = &ctx->fcc;
320 uint32_t __user *fcsr = &ctx->fcsr;
322 return _save_lasx_context(regs, fcc, fcsr);
325 static int restore_hw_lasx_context(struct lasx_context __user *ctx)
327 uint64_t __user *regs = (uint64_t *)&ctx->regs;
328 uint64_t __user *fcc = &ctx->fcc;
329 uint32_t __user *fcsr = &ctx->fcsr;
331 return _restore_lasx_context(regs, fcc, fcsr);
335 * Wrappers for the assembly _{save,restore}_lbt_context functions.
337 #ifdef CONFIG_CPU_HAS_LBT
338 static int save_hw_lbt_context(struct lbt_context __user *ctx)
340 uint64_t __user *regs = (uint64_t *)&ctx->regs;
341 uint32_t __user *eflags = (uint32_t *)&ctx->eflags;
343 return _save_lbt_context(regs, eflags);
346 static int restore_hw_lbt_context(struct lbt_context __user *ctx)
348 uint64_t __user *regs = (uint64_t *)&ctx->regs;
349 uint32_t __user *eflags = (uint32_t *)&ctx->eflags;
351 return _restore_lbt_context(regs, eflags);
354 static int save_hw_ftop_context(struct lbt_context __user *ctx)
356 uint32_t __user *ftop = &ctx->ftop;
358 return _save_ftop_context(ftop);
361 static int restore_hw_ftop_context(struct lbt_context __user *ctx)
363 uint32_t __user *ftop = &ctx->ftop;
365 return _restore_ftop_context(ftop);
369 static int fcsr_pending(unsigned int __user *fcsr)
372 unsigned int csr, enabled;
374 err = __get_user(csr, fcsr);
375 enabled = ((csr & FPU_CSR_ALL_E) << 24);
377 * If the signal handler set some FPU exceptions, clear it and
382 err |= __put_user(csr, fcsr);
391 static int protected_save_fpu_context(struct extctx_layout *extctx)
394 struct sctx_info __user *info = extctx->fpu.addr;
395 struct fpu_context __user *fpu_ctx = (struct fpu_context *)get_ctx_through_ctxinfo(info);
396 uint64_t __user *regs = (uint64_t *)&fpu_ctx->regs;
397 uint64_t __user *fcc = &fpu_ctx->fcc;
398 uint32_t __user *fcsr = &fpu_ctx->fcsr;
403 err = save_hw_fpu_context(fpu_ctx);
405 err = copy_fpu_to_sigcontext(fpu_ctx);
408 err |= __put_user(FPU_CTX_MAGIC, &info->magic);
409 err |= __put_user(extctx->fpu.size, &info->size);
413 /* Touch the FPU context and try again */
414 err = __put_user(0, ®s[0]) |
415 __put_user(0, ®s[31]) |
419 return err; /* really bad sigcontext */
425 static int protected_restore_fpu_context(struct extctx_layout *extctx)
427 int err = 0, sig = 0, tmp __maybe_unused;
428 struct sctx_info __user *info = extctx->fpu.addr;
429 struct fpu_context __user *fpu_ctx = (struct fpu_context *)get_ctx_through_ctxinfo(info);
430 uint64_t __user *regs = (uint64_t *)&fpu_ctx->regs;
431 uint64_t __user *fcc = &fpu_ctx->fcc;
432 uint32_t __user *fcsr = &fpu_ctx->fcsr;
434 err = sig = fcsr_pending(fcsr);
441 err = restore_hw_fpu_context(fpu_ctx);
443 err = copy_fpu_from_sigcontext(fpu_ctx);
448 /* Touch the FPU context and try again */
449 err = __get_user(tmp, ®s[0]) |
450 __get_user(tmp, ®s[31]) |
451 __get_user(tmp, fcc) |
452 __get_user(tmp, fcsr);
454 break; /* really bad sigcontext */
460 static int protected_save_lsx_context(struct extctx_layout *extctx)
463 struct sctx_info __user *info = extctx->lsx.addr;
464 struct lsx_context __user *lsx_ctx = (struct lsx_context *)get_ctx_through_ctxinfo(info);
465 uint64_t __user *regs = (uint64_t *)&lsx_ctx->regs;
466 uint64_t __user *fcc = &lsx_ctx->fcc;
467 uint32_t __user *fcsr = &lsx_ctx->fcsr;
471 if (is_lsx_enabled())
472 err = save_hw_lsx_context(lsx_ctx);
476 err = copy_lsx_to_sigcontext(lsx_ctx);
480 err |= __put_user(LSX_CTX_MAGIC, &info->magic);
481 err |= __put_user(extctx->lsx.size, &info->size);
485 /* Touch the LSX context and try again */
486 err = __put_user(0, ®s[0]) |
487 __put_user(0, ®s[32*2-1]) |
491 return err; /* really bad sigcontext */
497 static int protected_restore_lsx_context(struct extctx_layout *extctx)
499 int err = 0, sig = 0, tmp __maybe_unused;
500 struct sctx_info __user *info = extctx->lsx.addr;
501 struct lsx_context __user *lsx_ctx = (struct lsx_context *)get_ctx_through_ctxinfo(info);
502 uint64_t __user *regs = (uint64_t *)&lsx_ctx->regs;
503 uint64_t __user *fcc = &lsx_ctx->fcc;
504 uint32_t __user *fcsr = &lsx_ctx->fcsr;
506 err = sig = fcsr_pending(fcsr);
512 if (is_lsx_enabled())
513 err = restore_hw_lsx_context(lsx_ctx);
515 err = copy_lsx_from_sigcontext(lsx_ctx);
523 /* Touch the LSX context and try again */
524 err = __get_user(tmp, ®s[0]) |
525 __get_user(tmp, ®s[32*2-1]) |
526 __get_user(tmp, fcc) |
527 __get_user(tmp, fcsr);
529 break; /* really bad sigcontext */
535 static int protected_save_lasx_context(struct extctx_layout *extctx)
538 struct sctx_info __user *info = extctx->lasx.addr;
539 struct lasx_context __user *lasx_ctx =
540 (struct lasx_context *)get_ctx_through_ctxinfo(info);
541 uint64_t __user *regs = (uint64_t *)&lasx_ctx->regs;
542 uint64_t __user *fcc = &lasx_ctx->fcc;
543 uint32_t __user *fcsr = &lasx_ctx->fcsr;
547 if (is_lasx_enabled())
548 err = save_hw_lasx_context(lasx_ctx);
550 if (is_lsx_enabled())
552 else if (is_fpu_owner())
554 err = copy_lasx_to_sigcontext(lasx_ctx);
558 err |= __put_user(LASX_CTX_MAGIC, &info->magic);
559 err |= __put_user(extctx->lasx.size, &info->size);
563 /* Touch the LASX context and try again */
564 err = __put_user(0, ®s[0]) |
565 __put_user(0, ®s[32*4-1]) |
569 return err; /* really bad sigcontext */
575 static int protected_restore_lasx_context(struct extctx_layout *extctx)
577 int err = 0, sig = 0, tmp __maybe_unused;
578 struct sctx_info __user *info = extctx->lasx.addr;
579 struct lasx_context __user *lasx_ctx =
580 (struct lasx_context *)get_ctx_through_ctxinfo(info);
581 uint64_t __user *regs = (uint64_t *)&lasx_ctx->regs;
582 uint64_t __user *fcc = &lasx_ctx->fcc;
583 uint32_t __user *fcsr = &lasx_ctx->fcsr;
585 err = sig = fcsr_pending(fcsr);
591 if (is_lasx_enabled())
592 err = restore_hw_lasx_context(lasx_ctx);
594 err = copy_lasx_from_sigcontext(lasx_ctx);
595 if (is_lsx_enabled())
596 restore_lsx(current);
597 else if (is_fpu_owner())
604 /* Touch the LASX context and try again */
605 err = __get_user(tmp, ®s[0]) |
606 __get_user(tmp, ®s[32*4-1]) |
607 __get_user(tmp, fcc) |
608 __get_user(tmp, fcsr);
610 break; /* really bad sigcontext */
616 #ifdef CONFIG_CPU_HAS_LBT
617 static int protected_save_lbt_context(struct extctx_layout *extctx)
620 struct sctx_info __user *info = extctx->lbt.addr;
621 struct lbt_context __user *lbt_ctx =
622 (struct lbt_context *)get_ctx_through_ctxinfo(info);
623 uint64_t __user *regs = (uint64_t *)&lbt_ctx->regs;
624 uint32_t __user *eflags = (uint32_t *)&lbt_ctx->eflags;
629 err |= save_hw_lbt_context(lbt_ctx);
631 err |= copy_lbt_to_sigcontext(lbt_ctx);
633 err |= save_hw_ftop_context(lbt_ctx);
635 err |= copy_ftop_to_sigcontext(lbt_ctx);
638 err |= __put_user(LBT_CTX_MAGIC, &info->magic);
639 err |= __put_user(extctx->lbt.size, &info->size);
643 /* Touch the LBT context and try again */
644 err = __put_user(0, ®s[0]) | __put_user(0, eflags);
653 static int protected_restore_lbt_context(struct extctx_layout *extctx)
655 int err = 0, tmp __maybe_unused;
656 struct sctx_info __user *info = extctx->lbt.addr;
657 struct lbt_context __user *lbt_ctx =
658 (struct lbt_context *)get_ctx_through_ctxinfo(info);
659 uint64_t __user *regs = (uint64_t *)&lbt_ctx->regs;
660 uint32_t __user *eflags = (uint32_t *)&lbt_ctx->eflags;
665 err |= restore_hw_lbt_context(lbt_ctx);
667 err |= copy_lbt_from_sigcontext(lbt_ctx);
669 err |= restore_hw_ftop_context(lbt_ctx);
671 err |= copy_ftop_from_sigcontext(lbt_ctx);
676 /* Touch the LBT context and try again */
677 err = __get_user(tmp, ®s[0]) | __get_user(tmp, eflags);
687 static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
688 struct extctx_layout *extctx)
691 struct sctx_info __user *info;
693 err |= __put_user(regs->csr_era, &sc->sc_pc);
694 err |= __put_user(extctx->flags, &sc->sc_flags);
696 err |= __put_user(0, &sc->sc_regs[0]);
697 for (i = 1; i < 32; i++)
698 err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
700 if (extctx->lasx.addr)
701 err |= protected_save_lasx_context(extctx);
702 else if (extctx->lsx.addr)
703 err |= protected_save_lsx_context(extctx);
704 else if (extctx->fpu.addr)
705 err |= protected_save_fpu_context(extctx);
707 #ifdef CONFIG_CPU_HAS_LBT
708 if (extctx->lbt.addr)
709 err |= protected_save_lbt_context(extctx);
712 /* Set the "end" magic */
713 info = (struct sctx_info *)extctx->end.addr;
714 err |= __put_user(0, &info->magic);
715 err |= __put_user(0, &info->size);
720 static int parse_extcontext(struct sigcontext __user *sc, struct extctx_layout *extctx)
723 unsigned int magic, size;
724 struct sctx_info __user *info = (struct sctx_info __user *)&sc->sc_extcontext;
727 err |= __get_user(magic, &info->magic);
728 err |= __get_user(size, &info->size);
737 if (size < (sizeof(struct sctx_info) +
738 sizeof(struct fpu_context)))
740 extctx->fpu.addr = info;
744 if (size < (sizeof(struct sctx_info) +
745 sizeof(struct lsx_context)))
747 extctx->lsx.addr = info;
751 if (size < (sizeof(struct sctx_info) +
752 sizeof(struct lasx_context)))
754 extctx->lasx.addr = info;
758 if (size < (sizeof(struct sctx_info) +
759 sizeof(struct lbt_context)))
761 extctx->lbt.addr = info;
768 info = (struct sctx_info *)((char *)info + size);
778 static int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
781 struct extctx_layout extctx;
783 memset(&extctx, 0, sizeof(struct extctx_layout));
785 err = __get_user(extctx.flags, &sc->sc_flags);
789 err = parse_extcontext(sc, &extctx);
793 conditional_used_math(extctx.flags & SC_USED_FP);
796 * The signal handler may have used FPU; give it up if the program
797 * doesn't want it following sigreturn.
799 if (!(extctx.flags & SC_USED_FP))
802 /* Always make any pending restarted system calls return -EINTR */
803 current->restart_block.fn = do_no_restart_syscall;
805 err |= __get_user(regs->csr_era, &sc->sc_pc);
806 for (i = 1; i < 32; i++)
807 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
809 if (extctx.lasx.addr)
810 err |= protected_restore_lasx_context(&extctx);
811 else if (extctx.lsx.addr)
812 err |= protected_restore_lsx_context(&extctx);
813 else if (extctx.fpu.addr)
814 err |= protected_restore_fpu_context(&extctx);
816 #ifdef CONFIG_CPU_HAS_LBT
818 err |= protected_restore_lbt_context(&extctx);
825 static unsigned int handle_flags(void)
827 unsigned int flags = 0;
829 flags = used_math() ? SC_USED_FP : 0;
831 switch (current->thread.error_code) {
833 flags |= SC_ADDRERR_RD;
836 flags |= SC_ADDRERR_WR;
843 static unsigned long extframe_alloc(struct extctx_layout *extctx,
844 struct _ctx_layout *layout,
845 size_t size, unsigned int align, unsigned long base)
847 unsigned long new_base = base - size;
849 new_base = round_down(new_base, (align < 16 ? 16 : align));
850 new_base -= sizeof(struct sctx_info);
852 layout->addr = (void *)new_base;
853 layout->size = (unsigned int)(base - new_base);
854 extctx->size += layout->size;
859 static unsigned long setup_extcontext(struct extctx_layout *extctx, unsigned long sp)
861 unsigned long new_sp = sp;
863 memset(extctx, 0, sizeof(struct extctx_layout));
865 extctx->flags = handle_flags();
867 /* Grow down, alloc "end" context info first. */
868 new_sp -= sizeof(struct sctx_info);
869 extctx->end.addr = (void *)new_sp;
870 extctx->end.size = (unsigned int)sizeof(struct sctx_info);
871 extctx->size += extctx->end.size;
873 if (extctx->flags & SC_USED_FP) {
874 if (cpu_has_lasx && thread_lasx_context_live())
875 new_sp = extframe_alloc(extctx, &extctx->lasx,
876 sizeof(struct lasx_context), LASX_CTX_ALIGN, new_sp);
877 else if (cpu_has_lsx && thread_lsx_context_live())
878 new_sp = extframe_alloc(extctx, &extctx->lsx,
879 sizeof(struct lsx_context), LSX_CTX_ALIGN, new_sp);
880 else if (cpu_has_fpu)
881 new_sp = extframe_alloc(extctx, &extctx->fpu,
882 sizeof(struct fpu_context), FPU_CTX_ALIGN, new_sp);
885 #ifdef CONFIG_CPU_HAS_LBT
886 if (cpu_has_lbt && thread_lbt_context_live()) {
887 new_sp = extframe_alloc(extctx, &extctx->lbt,
888 sizeof(struct lbt_context), LBT_CTX_ALIGN, new_sp);
895 static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
896 struct extctx_layout *extctx)
900 /* Default to using normal stack */
904 * If we are on the alternate signal stack and would overflow it, don't.
905 * Return an always-bogus address instead so we will die with SIGSEGV.
907 if (on_sig_stack(sp) &&
908 !likely(on_sig_stack(sp - sizeof(struct rt_sigframe))))
909 return (void __user __force *)(-1UL);
911 sp = sigsp(sp, ksig);
912 sp = round_down(sp, 16);
913 sp = setup_extcontext(extctx, sp);
914 sp -= sizeof(struct rt_sigframe);
916 if (!IS_ALIGNED(sp, 16))
919 return (void __user *)sp;
923 * Atomically swap in the new signal mask, and wait for a signal.
926 SYSCALL_DEFINE0(rt_sigreturn)
930 struct pt_regs *regs;
931 struct rt_sigframe __user *frame;
933 regs = current_pt_regs();
934 frame = (struct rt_sigframe __user *)regs->regs[3];
935 if (!access_ok(frame, sizeof(*frame)))
937 if (__copy_from_user(&set, &frame->rs_uctx.uc_sigmask, sizeof(set)))
940 set_current_blocked(&set);
942 sig = restore_sigcontext(regs, &frame->rs_uctx.uc_mcontext);
948 regs->regs[0] = 0; /* No syscall restarting */
949 if (restore_altstack(&frame->rs_uctx.uc_stack))
952 return regs->regs[4];
959 static int setup_rt_frame(void *sig_return, struct ksignal *ksig,
960 struct pt_regs *regs, sigset_t *set)
963 struct extctx_layout extctx;
964 struct rt_sigframe __user *frame;
966 frame = get_sigframe(ksig, regs, &extctx);
967 if (!access_ok(frame, sizeof(*frame) + extctx.size))
970 /* Create siginfo. */
971 err |= copy_siginfo_to_user(&frame->rs_info, &ksig->info);
973 /* Create the ucontext. */
974 err |= __put_user(0, &frame->rs_uctx.uc_flags);
975 err |= __put_user(NULL, &frame->rs_uctx.uc_link);
976 err |= __save_altstack(&frame->rs_uctx.uc_stack, regs->regs[3]);
977 err |= setup_sigcontext(regs, &frame->rs_uctx.uc_mcontext, &extctx);
978 err |= __copy_to_user(&frame->rs_uctx.uc_sigmask, set, sizeof(*set));
984 * Arguments to signal handler:
987 * a1 = pointer to siginfo
988 * a2 = pointer to ucontext
990 * c0_era point to the signal handler, $r3 (sp) points to
991 * the struct rt_sigframe.
993 regs->regs[4] = ksig->sig;
994 regs->regs[5] = (unsigned long) &frame->rs_info;
995 regs->regs[6] = (unsigned long) &frame->rs_uctx;
996 regs->regs[3] = (unsigned long) frame;
997 regs->regs[1] = (unsigned long) sig_return;
998 regs->csr_era = (unsigned long) ksig->ka.sa.sa_handler;
1000 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
1001 current->comm, current->pid,
1002 frame, regs->csr_era, regs->regs[1]);
1007 static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
1010 sigset_t *oldset = sigmask_to_save();
1011 void *vdso = current->mm->context.vdso;
1013 /* Are we from a system call? */
1014 if (regs->regs[0]) {
1015 switch (regs->regs[4]) {
1016 case -ERESTART_RESTARTBLOCK:
1017 case -ERESTARTNOHAND:
1018 regs->regs[4] = -EINTR;
1021 if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
1022 regs->regs[4] = -EINTR;
1026 case -ERESTARTNOINTR:
1027 regs->regs[4] = regs->orig_a0;
1031 regs->regs[0] = 0; /* Don't deal with this again. */
1034 rseq_signal_deliver(ksig, regs);
1036 ret = setup_rt_frame(vdso + current->thread.vdso->offset_sigreturn, ksig, regs, oldset);
1038 signal_setup_done(ret, ksig, 0);
1041 void arch_do_signal_or_restart(struct pt_regs *regs)
1043 struct ksignal ksig;
1045 if (get_signal(&ksig)) {
1046 /* Whee! Actually deliver the signal. */
1047 handle_signal(&ksig, regs);
1051 /* Are we from a system call? */
1052 if (regs->regs[0]) {
1053 switch (regs->regs[4]) {
1054 case -ERESTARTNOHAND:
1056 case -ERESTARTNOINTR:
1057 regs->regs[4] = regs->orig_a0;
1061 case -ERESTART_RESTARTBLOCK:
1062 regs->regs[4] = regs->orig_a0;
1063 regs->regs[11] = __NR_restart_syscall;
1067 regs->regs[0] = 0; /* Don't deal with this again. */
1071 * If there's no signal to deliver, we just put the saved sigmask
1074 restore_saved_sigmask();