hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/arch/powerpc/kernel/signal_64.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * PowerPC version
34 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
....@@ -5,11 +6,6 @@
56 * Derived from "arch/i386/kernel/signal.c"
67 * Copyright (C) 1991, 1992 Linus Torvalds
78 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
8
- *
9
- * This program is free software; you can redistribute it and/or
10
- * modify it under the terms of the GNU General Public License
11
- * as published by the Free Software Foundation; either version
12
- * 2 of the License, or (at your option) any later version.
139 */
1410
1511 #include <linux/sched.h>
....@@ -25,11 +21,11 @@
2521 #include <linux/ptrace.h>
2622 #include <linux/ratelimit.h>
2723 #include <linux/syscalls.h>
24
+#include <linux/pagemap.h>
2825
2926 #include <asm/sigcontext.h>
3027 #include <asm/ucontext.h>
3128 #include <linux/uaccess.h>
32
-#include <asm/pgtable.h>
3329 #include <asm/unistd.h>
3430 #include <asm/cacheflush.h>
3531 #include <asm/syscalls.h>
....@@ -44,8 +40,8 @@
4440 #define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
4541 #define FP_REGS_SIZE sizeof(elf_fpregset_t)
4642
47
-#define TRAMP_TRACEBACK 3
48
-#define TRAMP_SIZE 6
43
+#define TRAMP_TRACEBACK 4
44
+#define TRAMP_SIZE 7
4945
5046 /*
5147 * When we have signals to deliver, we set up on the user stack,
....@@ -354,8 +350,8 @@
354350 err |= __get_user(regs->link, &sc->gp_regs[PT_LNK]);
355351 err |= __get_user(regs->xer, &sc->gp_regs[PT_XER]);
356352 err |= __get_user(regs->ccr, &sc->gp_regs[PT_CCR]);
357
- /* skip SOFTE */
358
- regs->trap = 0;
353
+ /* Don't allow userspace to set SOFTE */
354
+ set_trap_norestart(regs);
359355 err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]);
360356 err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]);
361357 err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]);
....@@ -376,7 +372,7 @@
376372 err |= __get_user(v_regs, &sc->v_regs);
377373 if (err)
378374 return err;
379
- if (v_regs && !access_ok(VERIFY_READ, v_regs, 34 * sizeof(vector128)))
375
+ if (v_regs && !access_ok(v_regs, 34 * sizeof(vector128)))
380376 return -EFAULT;
381377 /* Copy 33 vec registers (vr0..31 and vscr) from the stack */
382378 if (v_regs != NULL && (msr & MSR_VEC) != 0) {
....@@ -476,10 +472,8 @@
476472 &sc->gp_regs[PT_XER]);
477473 err |= __get_user(tsk->thread.ckpt_regs.ccr,
478474 &sc->gp_regs[PT_CCR]);
479
-
480
- /* Don't allow userspace to set the trap value */
481
- regs->trap = 0;
482
-
475
+ /* Don't allow userspace to set SOFTE */
476
+ set_trap_norestart(regs);
483477 /* These regs are not checkpointed; they can go in 'regs'. */
484478 err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]);
485479 err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]);
....@@ -497,10 +491,9 @@
497491 err |= __get_user(tm_v_regs, &tm_sc->v_regs);
498492 if (err)
499493 return err;
500
- if (v_regs && !access_ok(VERIFY_READ, v_regs, 34 * sizeof(vector128)))
494
+ if (v_regs && !access_ok(v_regs, 34 * sizeof(vector128)))
501495 return -EFAULT;
502
- if (tm_v_regs && !access_ok(VERIFY_READ,
503
- tm_v_regs, 34 * sizeof(vector128)))
496
+ if (tm_v_regs && !access_ok(tm_v_regs, 34 * sizeof(vector128)))
504497 return -EFAULT;
505498 /* Copy 33 vec registers (vr0..31 and vscr) from the stack */
506499 if (v_regs != NULL && tm_v_regs != NULL && (msr & MSR_VEC) != 0) {
....@@ -561,7 +554,7 @@
561554 preempt_disable();
562555
563556 /* pull in MSR TS bits from user context */
564
- regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK);
557
+ regs->msr |= msr & MSR_TS_MASK;
565558
566559 /*
567560 * Ensure that TM is enabled in regs->msr before we leave the signal
....@@ -608,12 +601,15 @@
608601 int i;
609602 long err = 0;
610603
604
+ /* bctrl # call the handler */
605
+ err |= __put_user(PPC_INST_BCTRL, &tramp[0]);
611606 /* addi r1, r1, __SIGNAL_FRAMESIZE # Pop the dummy stackframe */
612
- err |= __put_user(0x38210000UL | (__SIGNAL_FRAMESIZE & 0xffff), &tramp[0]);
607
+ err |= __put_user(PPC_INST_ADDI | __PPC_RT(R1) | __PPC_RA(R1) |
608
+ (__SIGNAL_FRAMESIZE & 0xffff), &tramp[1]);
613609 /* li r0, __NR_[rt_]sigreturn| */
614
- err |= __put_user(0x38000000UL | (syscall & 0xffff), &tramp[1]);
610
+ err |= __put_user(PPC_INST_ADDI | (syscall & 0xffff), &tramp[2]);
615611 /* sc */
616
- err |= __put_user(0x44000002UL, &tramp[2]);
612
+ err |= __put_user(PPC_INST_SC, &tramp[3]);
617613
618614 /* Minimal traceback info */
619615 for (i=TRAMP_TRACEBACK; i < TRAMP_SIZE ;i++)
....@@ -639,7 +635,6 @@
639635 SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx,
640636 struct ucontext __user *, new_ctx, long, ctx_size)
641637 {
642
- unsigned char tmp;
643638 sigset_t set;
644639 unsigned long new_msr = 0;
645640 int ctx_has_vsx_region = 0;
....@@ -665,7 +660,7 @@
665660 ctx_has_vsx_region = 1;
666661
667662 if (old_ctx != NULL) {
668
- if (!access_ok(VERIFY_WRITE, old_ctx, ctx_size)
663
+ if (!access_ok(old_ctx, ctx_size)
669664 || setup_sigcontext(&old_ctx->uc_mcontext, current, 0, NULL, 0,
670665 ctx_has_vsx_region)
671666 || __copy_to_user(&old_ctx->uc_sigmask,
....@@ -674,9 +669,8 @@
674669 }
675670 if (new_ctx == NULL)
676671 return 0;
677
- if (!access_ok(VERIFY_READ, new_ctx, ctx_size)
678
- || __get_user(tmp, (u8 __user *) new_ctx)
679
- || __get_user(tmp, (u8 __user *) new_ctx + ctx_size - 1))
672
+ if (!access_ok(new_ctx, ctx_size) ||
673
+ fault_in_pages_readable((u8 __user *)new_ctx, ctx_size))
680674 return -EFAULT;
681675
682676 /*
....@@ -719,7 +713,7 @@
719713 /* Always make any pending restarted system calls return -EINTR */
720714 current->restart_block.fn = do_no_restart_syscall;
721715
722
- if (!access_ok(VERIFY_READ, uc, sizeof(*uc)))
716
+ if (!access_ok(uc, sizeof(*uc)))
723717 goto badframe;
724718
725719 if (__copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
....@@ -739,6 +733,31 @@
739733 */
740734 if (MSR_TM_SUSPENDED(mfmsr()))
741735 tm_reclaim_current(0);
736
+
737
+ /*
738
+ * Disable MSR[TS] bit also, so, if there is an exception in the
739
+ * code below (as a page fault in copy_ckvsx_to_user()), it does
740
+ * not recheckpoint this task if there was a context switch inside
741
+ * the exception.
742
+ *
743
+ * A major page fault can indirectly call schedule(). A reschedule
744
+ * process in the middle of an exception can have a side effect
745
+ * (Changing the CPU MSR[TS] state), since schedule() is called
746
+ * with the CPU MSR[TS] disable and returns with MSR[TS]=Suspended
747
+ * (switch_to() calls tm_recheckpoint() for the 'new' process). In
748
+ * this case, the process continues to be the same in the CPU, but
749
+ * the CPU state just changed.
750
+ *
751
+ * This can cause a TM Bad Thing, since the MSR in the stack will
752
+ * have the MSR[TS]=0, and this is what will be used to RFID.
753
+ *
754
+ * Clearing MSR[TS] state here will avoid a recheckpoint if there
755
+ * is any process reschedule in kernel space. The MSR[TS] state
756
+ * does not need to be saved also, since it will be replaced with
757
+ * the MSR[TS] that came from user context later, at
758
+ * restore_tm_sigcontexts.
759
+ */
760
+ regs->msr &= ~MSR_TS_MASK;
742761
743762 if (__get_user(msr, &uc->uc_mcontext.gp_regs[PT_MSR]))
744763 goto badframe;
....@@ -787,7 +806,7 @@
787806 current->comm, current->pid, "rt_sigreturn",
788807 (long)uc, regs->nip, regs->link);
789808
790
- force_sig(SIGSEGV, current);
809
+ force_sig(SIGSEGV);
791810 return 0;
792811 }
793812
....@@ -846,12 +865,12 @@
846865
847866 /* Set up to return from userspace. */
848867 if (vdso64_rt_sigtramp && tsk->mm->context.vdso_base) {
849
- regs->link = tsk->mm->context.vdso_base + vdso64_rt_sigtramp;
868
+ regs->nip = tsk->mm->context.vdso_base + vdso64_rt_sigtramp;
850869 } else {
851870 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
852871 if (err)
853872 goto badframe;
854
- regs->link = (unsigned long) &frame->tramp[0];
873
+ regs->nip = (unsigned long) &frame->tramp[0];
855874 }
856875
857876 /* Allocate a dummy caller frame for the signal handler. */
....@@ -860,8 +879,8 @@
860879
861880 /* Set up "regs" so we "return" to the signal handler. */
862881 if (is_elf2_task()) {
863
- regs->nip = (unsigned long) ksig->ka.sa.sa_handler;
864
- regs->gpr[12] = regs->nip;
882
+ regs->ctr = (unsigned long) ksig->ka.sa.sa_handler;
883
+ regs->gpr[12] = regs->ctr;
865884 } else {
866885 /* Handler is *really* a pointer to the function descriptor for
867886 * the signal routine. The first entry in the function
....@@ -871,7 +890,7 @@
871890 func_descr_t __user *funct_desc_ptr =
872891 (func_descr_t __user *) ksig->ka.sa.sa_handler;
873892
874
- err |= get_user(regs->nip, &funct_desc_ptr->entry);
893
+ err |= get_user(regs->ctr, &funct_desc_ptr->entry);
875894 err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
876895 }
877896