signal.c (34069d12e239ae8f36dd96c378e4622fb1c42a76) | signal.c (bd3c5798484aa9a08302a844d7a75a2ee3b53d05) |
---|---|
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Author: Hanlu Li <lihanlu@loongson.cn> 4 * Huacai Chen <chenhuacai@loongson.cn> 5 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 6 * 7 * Derived from MIPS: 8 * Copyright (C) 1991, 1992 Linus Torvalds --- 18 unchanged lines hidden (view full) --- 27#include <linux/compiler.h> 28#include <linux/syscalls.h> 29#include <linux/uaccess.h> 30 31#include <asm/asm.h> 32#include <asm/cacheflush.h> 33#include <asm/cpu-features.h> 34#include <asm/fpu.h> | 1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Author: Hanlu Li <lihanlu@loongson.cn> 4 * Huacai Chen <chenhuacai@loongson.cn> 5 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 6 * 7 * Derived from MIPS: 8 * Copyright (C) 1991, 1992 Linus Torvalds --- 18 unchanged lines hidden (view full) --- 27#include <linux/compiler.h> 28#include <linux/syscalls.h> 29#include <linux/uaccess.h> 30 31#include <asm/asm.h> 32#include <asm/cacheflush.h> 33#include <asm/cpu-features.h> 34#include <asm/fpu.h> |
35#include <asm/lbt.h> |
|
35#include <asm/ucontext.h> 36#include <asm/vdso.h> 37 38#ifdef DEBUG_SIG 39# define DEBUGP(fmt, args...) printk("%s: " fmt, __func__, ##args) 40#else 41# define DEBUGP(fmt, args...) 42#endif 43 44/* Make sure we will not lose FPU ownership */ 45#define lock_fpu_owner() ({ preempt_disable(); pagefault_disable(); }) 46#define unlock_fpu_owner() ({ pagefault_enable(); preempt_enable(); }) | 36#include <asm/ucontext.h> 37#include <asm/vdso.h> 38 39#ifdef DEBUG_SIG 40# define DEBUGP(fmt, args...) printk("%s: " fmt, __func__, ##args) 41#else 42# define DEBUGP(fmt, args...) 43#endif 44 45/* Make sure we will not lose FPU ownership */ 46#define lock_fpu_owner() ({ preempt_disable(); pagefault_disable(); }) 47#define unlock_fpu_owner() ({ pagefault_enable(); preempt_enable(); }) |
48/* Make sure we will not lose LBT ownership */ 49#define lock_lbt_owner() ({ preempt_disable(); pagefault_disable(); }) 50#define unlock_lbt_owner() ({ pagefault_enable(); preempt_enable(); }) |
|
47 48/* Assembly functions to move context to/from the FPU */ 49extern asmlinkage int 50_save_fp_context(void __user *fpregs, void __user *fcc, void __user *csr); 51extern asmlinkage int 52_restore_fp_context(void __user *fpregs, void __user *fcc, void __user *csr); 53extern asmlinkage int 54_save_lsx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); 55extern asmlinkage int 56_restore_lsx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); 57extern asmlinkage int 58_save_lasx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); 59extern asmlinkage int 60_restore_lasx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); 61 | 51 52/* Assembly functions to move context to/from the FPU */ 53extern asmlinkage int 54_save_fp_context(void __user *fpregs, void __user *fcc, void __user *csr); 55extern asmlinkage int 56_restore_fp_context(void __user *fpregs, void __user *fcc, void __user *csr); 57extern asmlinkage int 58_save_lsx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); 59extern asmlinkage int 60_restore_lsx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); 61extern asmlinkage int 62_save_lasx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); 63extern asmlinkage int 64_restore_lasx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); 65 |
66#ifdef CONFIG_CPU_HAS_LBT 67extern asmlinkage int _save_lbt_context(void __user *regs, void __user *eflags); 68extern asmlinkage int _restore_lbt_context(void __user *regs, void __user *eflags); 69extern asmlinkage int _save_ftop_context(void __user *ftop); 70extern asmlinkage int _restore_ftop_context(void __user *ftop); 71#endif 72 |
|
62struct rt_sigframe { 63 struct siginfo rs_info; 64 struct ucontext rs_uctx; 65}; 66 67struct _ctx_layout { 68 struct sctx_info *addr; 69 unsigned int size; 70}; 71 72struct extctx_layout { 73 unsigned long size; 74 unsigned int flags; 75 struct _ctx_layout fpu; 76 struct _ctx_layout lsx; 77 struct _ctx_layout lasx; | 73struct rt_sigframe { 74 struct siginfo rs_info; 75 struct ucontext rs_uctx; 76}; 77 78struct _ctx_layout { 79 struct sctx_info *addr; 80 unsigned int size; 81}; 82 83struct extctx_layout { 84 unsigned long size; 85 unsigned int flags; 86 struct _ctx_layout fpu; 87 struct _ctx_layout lsx; 88 struct _ctx_layout lasx; |
89 struct _ctx_layout lbt; |
|
78 struct _ctx_layout end; 79}; 80 81static void __user *get_ctx_through_ctxinfo(struct sctx_info *info) 82{ 83 return (void __user *)((char *)info + sizeof(struct sctx_info)); 84} 85 --- 124 unchanged lines hidden (view full) --- 210 set_fpr64(¤t->thread.fpu.fpr[i], 3, fpr_val); 211 } 212 err |= __get_user(current->thread.fpu.fcc, fcc); 213 err |= __get_user(current->thread.fpu.fcsr, fcsr); 214 215 return err; 216} 217 | 90 struct _ctx_layout end; 91}; 92 93static void __user *get_ctx_through_ctxinfo(struct sctx_info *info) 94{ 95 return (void __user *)((char *)info + sizeof(struct sctx_info)); 96} 97 --- 124 unchanged lines hidden (view full) --- 222 set_fpr64(¤t->thread.fpu.fpr[i], 3, fpr_val); 223 } 224 err |= __get_user(current->thread.fpu.fcc, fcc); 225 err |= __get_user(current->thread.fpu.fcsr, fcsr); 226 227 return err; 228} 229 |
230#ifdef CONFIG_CPU_HAS_LBT 231static int copy_lbt_to_sigcontext(struct lbt_context __user *ctx) 232{ 233 int err = 0; 234 uint64_t __user *regs = (uint64_t *)&ctx->regs; 235 uint32_t __user *eflags = (uint32_t *)&ctx->eflags; 236 237 err |= __put_user(current->thread.lbt.scr0, ®s[0]); 238 err |= __put_user(current->thread.lbt.scr1, ®s[1]); 239 err |= __put_user(current->thread.lbt.scr2, ®s[2]); 240 err |= __put_user(current->thread.lbt.scr3, ®s[3]); 241 err |= __put_user(current->thread.lbt.eflags, eflags); 242 243 return err; 244} 245 246static int copy_lbt_from_sigcontext(struct lbt_context __user *ctx) 247{ 248 int err = 0; 249 uint64_t __user *regs = (uint64_t *)&ctx->regs; 250 uint32_t __user *eflags = (uint32_t *)&ctx->eflags; 251 252 err |= __get_user(current->thread.lbt.scr0, ®s[0]); 253 err |= __get_user(current->thread.lbt.scr1, ®s[1]); 254 err |= __get_user(current->thread.lbt.scr2, ®s[2]); 255 err |= __get_user(current->thread.lbt.scr3, ®s[3]); 256 err |= __get_user(current->thread.lbt.eflags, eflags); 257 258 return err; 259} 260 261static int copy_ftop_to_sigcontext(struct lbt_context __user *ctx) 262{ 263 uint32_t __user *ftop = &ctx->ftop; 264 265 return __put_user(current->thread.fpu.ftop, ftop); 266} 267 268static int copy_ftop_from_sigcontext(struct lbt_context __user *ctx) 269{ 270 uint32_t __user *ftop = &ctx->ftop; 271 272 return __get_user(current->thread.fpu.ftop, ftop); 273} 274#endif 275 |
|
218/* 219 * Wrappers for the assembly _{save,restore}_fp_context functions. 220 */ 221static int save_hw_fpu_context(struct fpu_context __user *ctx) 222{ 223 uint64_t __user *regs = (uint64_t *)&ctx->regs; 224 uint64_t __user *fcc = &ctx->fcc; 225 uint32_t __user *fcsr = &ctx->fcsr; --- 41 unchanged lines hidden (view full) --- 267{ 268 uint64_t __user *regs = (uint64_t *)&ctx->regs; 269 uint64_t __user *fcc = &ctx->fcc; 270 uint32_t __user *fcsr = &ctx->fcsr; 271 272 return _restore_lasx_context(regs, fcc, fcsr); 273} 274 | 276/* 277 * Wrappers for the assembly _{save,restore}_fp_context functions. 278 */ 279static int save_hw_fpu_context(struct fpu_context __user *ctx) 280{ 281 uint64_t __user *regs = (uint64_t *)&ctx->regs; 282 uint64_t __user *fcc = &ctx->fcc; 283 uint32_t __user *fcsr = &ctx->fcsr; --- 41 unchanged lines hidden (view full) --- 325{ 326 uint64_t __user *regs = (uint64_t *)&ctx->regs; 327 uint64_t __user *fcc = &ctx->fcc; 328 uint32_t __user *fcsr = &ctx->fcsr; 329 330 return _restore_lasx_context(regs, fcc, fcsr); 331} 332 |
333/* 334 * Wrappers for the assembly _{save,restore}_lbt_context functions. 335 */ 336#ifdef CONFIG_CPU_HAS_LBT 337static int save_hw_lbt_context(struct lbt_context __user *ctx) 338{ 339 uint64_t __user *regs = (uint64_t *)&ctx->regs; 340 uint32_t __user *eflags = (uint32_t *)&ctx->eflags; 341 342 return _save_lbt_context(regs, eflags); 343} 344 345static int restore_hw_lbt_context(struct lbt_context __user *ctx) 346{ 347 uint64_t __user *regs = (uint64_t *)&ctx->regs; 348 uint32_t __user *eflags = (uint32_t *)&ctx->eflags; 349 350 return _restore_lbt_context(regs, eflags); 351} 352 353static int save_hw_ftop_context(struct lbt_context __user *ctx) 354{ 355 uint32_t __user *ftop = &ctx->ftop; 356 357 return _save_ftop_context(ftop); 358} 359 360static int restore_hw_ftop_context(struct lbt_context __user *ctx) 361{ 362 uint32_t __user *ftop = &ctx->ftop; 363 364 return _restore_ftop_context(ftop); 365} 366#endif 367 |
|
275static int fcsr_pending(unsigned int __user *fcsr) 276{ 277 int err, sig = 0; 278 unsigned int csr, enabled; 279 280 err = __get_user(csr, fcsr); 281 enabled = ((csr & FPU_CSR_ALL_E) << 24); 282 /* --- 231 unchanged lines hidden (view full) --- 514 __get_user(tmp, fcsr); 515 if (err) 516 break; /* really bad sigcontext */ 517 } 518 519 return err ?: sig; 520} 521 | 368static int fcsr_pending(unsigned int __user *fcsr) 369{ 370 int err, sig = 0; 371 unsigned int csr, enabled; 372 373 err = __get_user(csr, fcsr); 374 enabled = ((csr & FPU_CSR_ALL_E) << 24); 375 /* --- 231 unchanged lines hidden (view full) --- 607 __get_user(tmp, fcsr); 608 if (err) 609 break; /* really bad sigcontext */ 610 } 611 612 return err ?: sig; 613} 614 |
615#ifdef CONFIG_CPU_HAS_LBT 616static int protected_save_lbt_context(struct extctx_layout *extctx) 617{ 618 int err = 0; 619 struct sctx_info __user *info = extctx->lbt.addr; 620 struct lbt_context __user *lbt_ctx = 621 (struct lbt_context *)get_ctx_through_ctxinfo(info); 622 uint64_t __user *regs = (uint64_t *)&lbt_ctx->regs; 623 uint32_t __user *eflags = (uint32_t *)&lbt_ctx->eflags; 624 625 while (1) { 626 lock_lbt_owner(); 627 if (is_lbt_owner()) 628 err |= save_hw_lbt_context(lbt_ctx); 629 else 630 err |= copy_lbt_to_sigcontext(lbt_ctx); 631 if (is_fpu_owner()) 632 err |= save_hw_ftop_context(lbt_ctx); 633 else 634 err |= copy_ftop_to_sigcontext(lbt_ctx); 635 unlock_lbt_owner(); 636 637 err |= __put_user(LBT_CTX_MAGIC, &info->magic); 638 err |= __put_user(extctx->lbt.size, &info->size); 639 640 if (likely(!err)) 641 break; 642 /* Touch the LBT context and try again */ 643 err = __put_user(0, ®s[0]) | __put_user(0, eflags); 644 645 if (err) 646 return err; 647 } 648 649 return err; 650} 651 652static int protected_restore_lbt_context(struct extctx_layout *extctx) 653{ 654 int err = 0, tmp __maybe_unused; 655 struct sctx_info __user *info = extctx->lbt.addr; 656 struct lbt_context __user *lbt_ctx = 657 (struct lbt_context *)get_ctx_through_ctxinfo(info); 658 uint64_t __user *regs = (uint64_t *)&lbt_ctx->regs; 659 uint32_t __user *eflags = (uint32_t *)&lbt_ctx->eflags; 660 661 while (1) { 662 lock_lbt_owner(); 663 if (is_lbt_owner()) 664 err |= restore_hw_lbt_context(lbt_ctx); 665 else 666 err |= copy_lbt_from_sigcontext(lbt_ctx); 667 if (is_fpu_owner()) 668 err |= restore_hw_ftop_context(lbt_ctx); 669 else 670 err |= copy_ftop_from_sigcontext(lbt_ctx); 671 unlock_lbt_owner(); 672 673 if (likely(!err)) 674 break; 675 /* Touch the LBT context and try again */ 676 err = __get_user(tmp, ®s[0]) | __get_user(tmp, eflags); 677 678 if (err) 679 return err; 680 } 681 682 return err; 683} 684#endif 685 |
|
522static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, 523 struct extctx_layout *extctx) 524{ 525 int i, err = 0; 526 struct sctx_info __user *info; 527 528 err |= __put_user(regs->csr_era, &sc->sc_pc); 529 err |= __put_user(extctx->flags, &sc->sc_flags); --- 4 unchanged lines hidden (view full) --- 534 535 if (extctx->lasx.addr) 536 err |= protected_save_lasx_context(extctx); 537 else if (extctx->lsx.addr) 538 err |= protected_save_lsx_context(extctx); 539 else if (extctx->fpu.addr) 540 err |= protected_save_fpu_context(extctx); 541 | 686static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, 687 struct extctx_layout *extctx) 688{ 689 int i, err = 0; 690 struct sctx_info __user *info; 691 692 err |= __put_user(regs->csr_era, &sc->sc_pc); 693 err |= __put_user(extctx->flags, &sc->sc_flags); --- 4 unchanged lines hidden (view full) --- 698 699 if (extctx->lasx.addr) 700 err |= protected_save_lasx_context(extctx); 701 else if (extctx->lsx.addr) 702 err |= protected_save_lsx_context(extctx); 703 else if (extctx->fpu.addr) 704 err |= protected_save_fpu_context(extctx); 705 |
706#ifdef CONFIG_CPU_HAS_LBT 707 if (extctx->lbt.addr) 708 err |= protected_save_lbt_context(extctx); 709#endif 710 |
|
542 /* Set the "end" magic */ 543 info = (struct sctx_info *)extctx->end.addr; 544 err |= __put_user(0, &info->magic); 545 err |= __put_user(0, &info->size); 546 547 return err; 548} 549 --- 29 unchanged lines hidden (view full) --- 579 580 case LASX_CTX_MAGIC: 581 if (size < (sizeof(struct sctx_info) + 582 sizeof(struct lasx_context))) 583 goto invalid; 584 extctx->lasx.addr = info; 585 break; 586 | 711 /* Set the "end" magic */ 712 info = (struct sctx_info *)extctx->end.addr; 713 err |= __put_user(0, &info->magic); 714 err |= __put_user(0, &info->size); 715 716 return err; 717} 718 --- 29 unchanged lines hidden (view full) --- 748 749 case LASX_CTX_MAGIC: 750 if (size < (sizeof(struct sctx_info) + 751 sizeof(struct lasx_context))) 752 goto invalid; 753 extctx->lasx.addr = info; 754 break; 755 |
756 case LBT_CTX_MAGIC: 757 if (size < (sizeof(struct sctx_info) + 758 sizeof(struct lbt_context))) 759 goto invalid; 760 extctx->lbt.addr = info; 761 break; 762 |
|
587 default: 588 goto invalid; 589 } 590 591 info = (struct sctx_info *)((char *)info + size); 592 } 593 594done: --- 36 unchanged lines hidden (view full) --- 631 632 if (extctx.lasx.addr) 633 err |= protected_restore_lasx_context(&extctx); 634 else if (extctx.lsx.addr) 635 err |= protected_restore_lsx_context(&extctx); 636 else if (extctx.fpu.addr) 637 err |= protected_restore_fpu_context(&extctx); 638 | 763 default: 764 goto invalid; 765 } 766 767 info = (struct sctx_info *)((char *)info + size); 768 } 769 770done: --- 36 unchanged lines hidden (view full) --- 807 808 if (extctx.lasx.addr) 809 err |= protected_restore_lasx_context(&extctx); 810 else if (extctx.lsx.addr) 811 err |= protected_restore_lsx_context(&extctx); 812 else if (extctx.fpu.addr) 813 err |= protected_restore_fpu_context(&extctx); 814 |
815#ifdef CONFIG_CPU_HAS_LBT 816 if (extctx.lbt.addr) 817 err |= protected_restore_lbt_context(&extctx); 818#endif 819 |
|
639bad: 640 return err; 641} 642 643static unsigned int handle_flags(void) 644{ 645 unsigned int flags = 0; 646 --- 48 unchanged lines hidden (view full) --- 695 else if (cpu_has_lsx && thread_lsx_context_live()) 696 new_sp = extframe_alloc(extctx, &extctx->lsx, 697 sizeof(struct lsx_context), LSX_CTX_ALIGN, new_sp); 698 else if (cpu_has_fpu) 699 new_sp = extframe_alloc(extctx, &extctx->fpu, 700 sizeof(struct fpu_context), FPU_CTX_ALIGN, new_sp); 701 } 702 | 820bad: 821 return err; 822} 823 824static unsigned int handle_flags(void) 825{ 826 unsigned int flags = 0; 827 --- 48 unchanged lines hidden (view full) --- 876 else if (cpu_has_lsx && thread_lsx_context_live()) 877 new_sp = extframe_alloc(extctx, &extctx->lsx, 878 sizeof(struct lsx_context), LSX_CTX_ALIGN, new_sp); 879 else if (cpu_has_fpu) 880 new_sp = extframe_alloc(extctx, &extctx->fpu, 881 sizeof(struct fpu_context), FPU_CTX_ALIGN, new_sp); 882 } 883 |
884#ifdef CONFIG_CPU_HAS_LBT 885 if (cpu_has_lbt && thread_lbt_context_live()) { 886 new_sp = extframe_alloc(extctx, &extctx->lbt, 887 sizeof(struct lbt_context), LBT_CTX_ALIGN, new_sp); 888 } 889#endif 890 |
|
703 return new_sp; 704} 705 706void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, 707 struct extctx_layout *extctx) 708{ 709 unsigned long sp; 710 --- 176 unchanged lines hidden --- | 891 return new_sp; 892} 893 894void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, 895 struct extctx_layout *extctx) 896{ 897 unsigned long sp; 898 --- 176 unchanged lines hidden --- |