powerpc: remove partial register save logic
authorNicholas Piggin <npiggin@gmail.com>
Tue, 16 Mar 2021 10:42:04 +0000 (20:42 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 14 Apr 2021 13:04:44 +0000 (23:04 +1000)
All subarchitectures always save all GPRs to pt_regs interrupt frames
now. Remove FULL_REGS and associated bits.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210316104206.407354-11-npiggin@gmail.com
12 files changed:
arch/powerpc/include/asm/ptrace.h
arch/powerpc/kernel/align.c
arch/powerpc/kernel/interrupt.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/ptrace/ptrace-view.c
arch/powerpc/kernel/ptrace/ptrace.c
arch/powerpc/kernel/ptrace/ptrace32.c
arch/powerpc/kernel/signal_32.c
arch/powerpc/kernel/signal_64.c
arch/powerpc/kernel/traps.c
arch/powerpc/lib/sstep.c
arch/powerpc/xmon/xmon.c

index c93511b..7793d6b 100644 (file)
@@ -188,29 +188,16 @@ static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
 #ifdef __powerpc64__
 #define TRAP_FLAGS_MASK                0x10
 #define TRAP(regs)             ((regs)->trap & ~TRAP_FLAGS_MASK)
-#define FULL_REGS(regs)                true
-#define SET_FULL_REGS(regs)    do { } while (0)
-#define CHECK_FULL_REGS(regs)  do { } while (0)
-#define NV_REG_POISON          0xdeadbeefdeadbeefUL
 #else
 /*
- * We use the least-significant bit of the trap field to indicate
- * whether we have saved the full set of registers, or only a
- * partial set.  A 1 there means the partial set.
- * On 4xx we use the next bit to indicate whether the exception
+ * On 4xx we use bit 1 in the trap word to indicate whether the exception
  * is a critical exception (1 means it is).
  */
-#define TRAP_FLAGS_MASK                0x1F
+#define TRAP_FLAGS_MASK                0x1E
 #define TRAP(regs)             ((regs)->trap & ~TRAP_FLAGS_MASK)
-#define FULL_REGS(regs)                true
-#define SET_FULL_REGS(regs)    do { } while (0)
 #define IS_CRITICAL_EXC(regs)  (((regs)->trap & 2) != 0)
 #define IS_MCHECK_EXC(regs)    (((regs)->trap & 4) != 0)
 #define IS_DEBUG_EXC(regs)     (((regs)->trap & 8) != 0)
-#define NV_REG_POISON          0xdeadbeef
-#define CHECK_FULL_REGS(regs)                                                \
-do {                                                                         \
-} while (0)
 #endif /* __powerpc64__ */
 
 static __always_inline void set_trap(struct pt_regs *regs, unsigned long val)
index a97d5f1..938db36 100644 (file)
@@ -304,12 +304,6 @@ int fix_alignment(struct pt_regs *regs)
        struct instruction_op op;
        int r, type;
 
-       /*
-        * We require a complete register set, if not, then our assembly
-        * is broken
-        */
-       CHECK_FULL_REGS(regs);
-
        if (is_kernel_addr(regs->nip))
                r = probe_kernel_read_inst(&instr, (void *)regs->nip);
        else
index 1b0e179..b953bb5 100644 (file)
@@ -51,7 +51,6 @@ notrace long system_call_exception(long r3, long r4, long r5,
        if (!IS_ENABLED(CONFIG_BOOKE) && !IS_ENABLED(CONFIG_40x))
                BUG_ON(!(regs->msr & MSR_RI));
        BUG_ON(!(regs->msr & MSR_PR));
-       BUG_ON(!FULL_REGS(regs));
        BUG_ON(arch_irq_disabled_regs(regs));
 
 #ifdef CONFIG_PPC_PKEY
@@ -365,7 +364,6 @@ notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs, unsigned
        if (!IS_ENABLED(CONFIG_BOOKE) && !IS_ENABLED(CONFIG_40x))
                BUG_ON(!(regs->msr & MSR_RI));
        BUG_ON(!(regs->msr & MSR_PR));
-       BUG_ON(!FULL_REGS(regs));
        BUG_ON(arch_irq_disabled_regs(regs));
        CT_WARN_ON(ct_state() == CONTEXT_USER);
 
@@ -445,7 +443,6 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs, unsign
            unlikely(!(regs->msr & MSR_RI)))
                unrecoverable_exception(regs);
        BUG_ON(regs->msr & MSR_PR);
-       BUG_ON(!FULL_REGS(regs));
        /*
         * CT_WARN_ON comes here via program_check_exception,
         * so avoid recursion.
index b966c8e..5269a0d 100644 (file)
@@ -1448,11 +1448,9 @@ static void print_msr_bits(unsigned long val)
 #ifdef CONFIG_PPC64
 #define REG            "%016lx"
 #define REGS_PER_LINE  4
-#define LAST_VOLATILE  13
 #else
 #define REG            "%08lx"
 #define REGS_PER_LINE  8
-#define LAST_VOLATILE  12
 #endif
 
 static void __show_regs(struct pt_regs *regs)
@@ -1488,8 +1486,6 @@ static void __show_regs(struct pt_regs *regs)
                if ((i % REGS_PER_LINE) == 0)
                        pr_cont("\nGPR%02d: ", i);
                pr_cont(REG " ", regs->gpr[i]);
-               if (i == LAST_VOLATILE && !FULL_REGS(regs))
-                       break;
        }
        pr_cont("\n");
        /*
@@ -1692,7 +1688,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
        } else {
                /* user thread */
                struct pt_regs *regs = current_pt_regs();
-               CHECK_FULL_REGS(regs);
                *childregs = *regs;
                if (usp)
                        childregs->gpr[1] = usp;
@@ -1797,13 +1792,6 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
        regs->ccr = 0;
        regs->gpr[1] = sp;
 
-       /*
-        * We have just cleared all the nonvolatile GPRs, so make
-        * FULL_REGS(regs) return true.  This is necessary to allow
-        * ptrace to examine the thread immediately after exec.
-        */
-       SET_FULL_REGS(regs);
-
 #ifdef CONFIG_PPC32
        regs->mq = 0;
        regs->nip = start;
index 0923c94..48ff912 100644 (file)
@@ -221,17 +221,9 @@ static int gpr_get(struct task_struct *target, const struct user_regset *regset,
 #ifdef CONFIG_PPC64
        struct membuf to_softe = membuf_at(&to, offsetof(struct pt_regs, softe));
 #endif
-       int i;
-
        if (target->thread.regs == NULL)
                return -EIO;
 
-       if (!FULL_REGS(target->thread.regs)) {
-               /* We have a partial register set.  Fill 14-31 with bogus values */
-               for (i = 14; i < 32; i++)
-                       target->thread.regs->gpr[i] = NV_REG_POISON;
-       }
-
        membuf_write(&to, target->thread.regs, sizeof(struct user_pt_regs));
 
        membuf_store(&to_msr, get_user_msr(target));
@@ -252,8 +244,6 @@ static int gpr_set(struct task_struct *target, const struct user_regset *regset,
        if (target->thread.regs == NULL)
                return -EIO;
 
-       CHECK_FULL_REGS(target->thread.regs);
-
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
                                 target->thread.regs,
                                 0, PT_MSR * sizeof(reg));
@@ -729,19 +719,9 @@ static int gpr32_get(struct task_struct *target,
                     const struct user_regset *regset,
                     struct membuf to)
 {
-       int i;
-
        if (target->thread.regs == NULL)
                return -EIO;
 
-       if (!FULL_REGS(target->thread.regs)) {
-               /*
-                * We have a partial register set.
-                * Fill 14-31 with bogus values.
-                */
-               for (i = 14; i < 32; i++)
-                       target->thread.regs->gpr[i] = NV_REG_POISON;
-       }
        return gpr32_get_common(target, regset, to,
                        &target->thread.regs->gpr[0]);
 }
@@ -754,7 +734,6 @@ static int gpr32_set(struct task_struct *target,
        if (target->thread.regs == NULL)
                return -EIO;
 
-       CHECK_FULL_REGS(target->thread.regs);
        return gpr32_set_common(target, regset, pos, count, kbuf, ubuf,
                        &target->thread.regs->gpr[0]);
 }
index 5180177..0a0a33e 100644 (file)
@@ -59,7 +59,6 @@ long arch_ptrace(struct task_struct *child, long request,
                if ((addr & (sizeof(long) - 1)) || !child->thread.regs)
                        break;
 
-               CHECK_FULL_REGS(child->thread.regs);
                if (index < PT_FPR0)
                        ret = ptrace_get_reg(child, (int) index, &tmp);
                else
@@ -81,7 +80,6 @@ long arch_ptrace(struct task_struct *child, long request,
                if ((addr & (sizeof(long) - 1)) || !child->thread.regs)
                        break;
 
-               CHECK_FULL_REGS(child->thread.regs);
                if (index < PT_FPR0)
                        ret = ptrace_put_reg(child, index, data);
                else
index d30b9ad..19c2248 100644 (file)
@@ -83,7 +83,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                if ((addr & 3) || (index > PT_FPSCR32))
                        break;
 
-               CHECK_FULL_REGS(child->thread.regs);
                if (index < PT_FPR0) {
                        ret = ptrace_get_reg(child, index, &tmp);
                        if (ret)
@@ -133,7 +132,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                if ((addr & 3) || numReg > PT_FPSCR)
                        break;
 
-               CHECK_FULL_REGS(child->thread.regs);
                if (numReg >= PT_FPR0) {
                        flush_fp_to_thread(child);
                        /* get 64 bit FPR */
@@ -187,7 +185,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                if ((addr & 3) || (index > PT_FPSCR32))
                        break;
 
-               CHECK_FULL_REGS(child->thread.regs);
                if (index < PT_FPR0) {
                        ret = ptrace_put_reg(child, index, data);
                } else {
@@ -226,7 +223,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                 */
                if ((addr & 3) || (numReg > PT_FPSCR))
                        break;
-               CHECK_FULL_REGS(child->thread.regs);
                if (numReg < PT_FPR0) {
                        unsigned long freg;
                        ret = ptrace_get_reg(child, numReg, &freg);
index fff4adc..94442af 100644 (file)
@@ -94,8 +94,6 @@ __unsafe_save_general_regs(struct pt_regs *regs, struct mcontext __user *frame)
        elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
        int val, i;
 
-       WARN_ON(!FULL_REGS(regs));
-
        for (i = 0; i <= PT_RESULT; i ++) {
                /* Force usr to alway see softe as 1 (interrupts enabled) */
                if (i == PT_SOFTE)
@@ -147,7 +145,6 @@ failed:
 static __always_inline int
 __unsafe_save_general_regs(struct pt_regs *regs, struct mcontext __user *frame)
 {
-       WARN_ON(!FULL_REGS(regs));
        unsafe_copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE, failed);
        return 0;
 
index e10459f..dca6648 100644 (file)
@@ -172,7 +172,6 @@ static long notrace __unsafe_setup_sigcontext(struct sigcontext __user *sc,
        }
 #endif /* CONFIG_VSX */
        unsafe_put_user(&sc->gp_regs, &sc->regs, efault_out);
-       WARN_ON(!FULL_REGS(regs));
        unsafe_copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE, efault_out);
        unsafe_put_user(msr, &sc->gp_regs[PT_MSR], efault_out);
        unsafe_put_user(softe, &sc->gp_regs[PT_SOFTE], efault_out);
@@ -309,7 +308,6 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc,
 
        err |= __put_user(&sc->gp_regs, &sc->regs);
        err |= __put_user(&tm_sc->gp_regs, &tm_sc->regs);
-       WARN_ON(!FULL_REGS(regs));
        err |= __copy_to_user(&tm_sc->gp_regs, regs, GP_REGS_SIZE);
        err |= __copy_to_user(&sc->gp_regs,
                              &tsk->thread.ckpt_regs, GP_REGS_SIZE);
index fd965cb..2babed7 100644 (file)
@@ -1318,7 +1318,6 @@ static int emulate_instruction(struct pt_regs *regs)
 
        if (!user_mode(regs))
                return -EINVAL;
-       CHECK_FULL_REGS(regs);
 
        if (get_user(instword, (u32 __user *)(regs->nip)))
                return -EFAULT;
index 739ea6d..45bda25 100644 (file)
@@ -1401,10 +1401,6 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
                break;
        }
 
-       /* Following cases refer to regs->gpr[], so we need all regs */
-       if (!FULL_REGS(regs))
-               return -1;
-
        rd = (word >> 21) & 0x1f;
        ra = (word >> 16) & 0x1f;
        rb = (word >> 11) & 0x1f;
index 2e94647..361534f 100644 (file)
@@ -1815,25 +1815,16 @@ static void prregs(struct pt_regs *fp)
        }
 
 #ifdef CONFIG_PPC64
-       if (FULL_REGS(fp)) {
-               for (n = 0; n < 16; ++n)
-                       printf("R%.2d = "REG"   R%.2d = "REG"\n",
-                              n, fp->gpr[n], n+16, fp->gpr[n+16]);
-       } else {
-               for (n = 0; n < 7; ++n)
-                       printf("R%.2d = "REG"   R%.2d = "REG"\n",
-                              n, fp->gpr[n], n+7, fp->gpr[n+7]);
-       }
+#define R_PER_LINE 2
 #else
+#define R_PER_LINE 4
+#endif
+
        for (n = 0; n < 32; ++n) {
-               printf("R%.2d = %.8lx%s", n, fp->gpr[n],
-                      (n & 3) == 3? "\n": "   ");
-               if (n == 12 && !FULL_REGS(fp)) {
-                       printf("\n");
-                       break;
-               }
+               printf("R%.2d = "REG"%s", n, fp->gpr[n],
+                       (n % R_PER_LINE) == R_PER_LINE - 1 ? "\n" : "   ");
        }
-#endif
+
        printf("pc  = ");
        xmon_print_symbol(fp->nip, " ", "\n");
        if (!trap_is_syscall(fp) && cpu_has_feature(CPU_FTR_CFAR)) {