Merge branch 'fixes' into next
authorMichael Ellerman <mpe@ellerman.id.au>
Tue, 9 Oct 2018 05:51:05 +0000 (16:51 +1100)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 9 Oct 2018 05:51:05 +0000 (16:51 +1100)
Merge our fixes branch. It has a few important fixes that are needed for
futher testing and also some commits that will conflict with content in
next.

1  2 
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/process.c
arch/powerpc/kernel/tm.S
tools/testing/selftests/powerpc/ptrace/Makefile

index 301a6a86a20fc5c13d36e37114101511b2384d7e,2d8fc8c9da7a1f210816bd9734c3d8453d8fc04e..b9239dbf6d59ab28a9bc45f5969f650a6f47c741
@@@ -244,13 -244,14 +244,13 @@@ EXC_REAL_BEGIN(machine_check, 0x200, 0x
        SET_SCRATCH0(r13)               /* save r13 */
        EXCEPTION_PROLOG_0(PACA_EXMC)
  BEGIN_FTR_SECTION
 -      b       machine_check_powernv_early
 +      b       machine_check_common_early
  FTR_SECTION_ELSE
        b       machine_check_pSeries_0
  ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
  EXC_REAL_END(machine_check, 0x200, 0x100)
  EXC_VIRT_NONE(0x4200, 0x100)
 -TRAMP_REAL_BEGIN(machine_check_powernv_early)
 -BEGIN_FTR_SECTION
 +TRAMP_REAL_BEGIN(machine_check_common_early)
        EXCEPTION_PROLOG_1(PACA_EXMC, NOTEST, 0x200)
        /*
         * Register contents:
        /* Save r9 through r13 from EXMC save area to stack frame. */
        EXCEPTION_PROLOG_COMMON_2(PACA_EXMC)
        mfmsr   r11                     /* get MSR value */
 +BEGIN_FTR_SECTION
        ori     r11,r11,MSR_ME          /* turn on ME bit */
 +END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
        ori     r11,r11,MSR_RI          /* turn on RI bit */
        LOAD_HANDLER(r12, machine_check_handle_early)
  1:    mtspr   SPRN_SRR0,r12
        andc    r11,r11,r10             /* Turn off MSR_ME */
        b       1b
        b       .       /* prevent speculative execution */
 -END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
  
  TRAMP_REAL_BEGIN(machine_check_pSeries)
        .globl machine_check_fwnmi
  machine_check_fwnmi:
        SET_SCRATCH0(r13)               /* save r13 */
        EXCEPTION_PROLOG_0(PACA_EXMC)
 +BEGIN_FTR_SECTION
 +      b       machine_check_common_early
 +END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE)
  machine_check_pSeries_0:
        EXCEPTION_PROLOG_1(PACA_EXMC, KVMTEST_PR, 0x200)
        /*
@@@ -443,9 -440,6 +443,9 @@@ EXC_COMMON_BEGIN(machine_check_handle_e
        bl      machine_check_early
        std     r3,RESULT(r1)   /* Save result */
        ld      r12,_MSR(r1)
 +BEGIN_FTR_SECTION
 +      b       4f
 +END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE)
  
  #ifdef        CONFIG_PPC_P7_NAP
        /*
         */
        rldicl. r11,r12,4,63            /* See if MC hit while in HV mode. */
        beq     5f
 -      andi.   r11,r12,MSR_PR          /* See if coming from user. */
 +4:    andi.   r11,r12,MSR_PR          /* See if coming from user. */
        bne     9f                      /* continue in V mode if we are. */
  
  5:
  #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
 +BEGIN_FTR_SECTION
        /*
         * We are coming from kernel context. Check if we are coming from
         * guest. if yes, then we can continue. We will fall through
        lbz     r11,HSTATE_IN_GUEST(r13)
        cmpwi   r11,0                   /* Check if coming from guest */
        bne     9f                      /* continue if we are. */
 +END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
  #endif
        /*
         * At this point we are not sure about what context we come from.
        cmpdi   r3,0            /* see if we handled MCE successfully */
  
        beq     1b              /* if !handled then panic */
 +BEGIN_FTR_SECTION
        /*
         * Return from MC interrupt.
         * Queue up the MCE event so that we can log it later, while
        bl      machine_check_queue_event
        MACHINE_CHECK_HANDLER_WINDUP
        RFI_TO_USER_OR_KERNEL
 +FTR_SECTION_ELSE
 +      /*
 +       * pSeries: Return from MC interrupt. Before that stay on emergency
 +       * stack and call machine_check_exception to log the MCE event.
 +       */
 +      LOAD_HANDLER(r10,mce_return)
 +      mtspr   SPRN_SRR0,r10
 +      ld      r10,PACAKMSR(r13)
 +      mtspr   SPRN_SRR1,r10
 +      RFI_TO_KERNEL
 +      b       .
 +ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
  9:
        /* Deliver the machine check to host kernel in V mode. */
        MACHINE_CHECK_HANDLER_WINDUP
 -      b       machine_check_pSeries
 +      SET_SCRATCH0(r13)               /* save r13 */
 +      EXCEPTION_PROLOG_0(PACA_EXMC)
 +      b       machine_check_pSeries_0
  
  EXC_COMMON_BEGIN(unrecover_mce)
        /* Invoke machine_check_exception to print MCE event and panic. */
        bl      unrecoverable_exception
        b       1b
  
 +EXC_COMMON_BEGIN(mce_return)
 +      /* Invoke machine_check_exception to print MCE event and return. */
 +      addi    r3,r1,STACK_FRAME_OVERHEAD
 +      bl      machine_check_exception
 +      MACHINE_CHECK_HANDLER_WINDUP
 +      RFI_TO_KERNEL
 +      b       .
  
  EXC_REAL(data_access, 0x300, 0x80)
  EXC_VIRT(data_access, 0x4300, 0x80, 0x300)
@@@ -1344,9 -1314,7 +1344,7 @@@ EXC_REAL_BEGIN(denorm_exception_hv, 0x1
  
  #ifdef CONFIG_PPC_DENORMALISATION
        mfspr   r10,SPRN_HSRR1
-       mfspr   r11,SPRN_HSRR0          /* save HSRR0 */
        andis.  r10,r10,(HSRR1_DENORM)@h /* denorm? */
-       addi    r11,r11,-4              /* HSRR0 is next instruction */
        bne+    denorm_assist
  #endif
  
@@@ -1412,6 -1380,8 +1410,8 @@@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S
   */
        XVCPSGNDP32(32)
  denorm_done:
+       mfspr   r11,SPRN_HSRR0
+       subi    r11,r11,4
        mtspr   SPRN_HSRR0,r11
        mtcrf   0x80,r9
        ld      r9,PACA_EXGEN+EX_R9(r13)
index ec264a6f0eb3a2bbc9e584894f59581709d8579f,bb6ac471a784e70918d25a450e31ecba3f352881..d9d4eb2ea6c90c9edac48ad259281b81caecf1a2
@@@ -102,18 -102,24 +102,18 @@@ static void check_if_tm_restore_require
        }
  }
  
 -static inline bool msr_tm_active(unsigned long msr)
 -{
 -      return MSR_TM_ACTIVE(msr);
 -}
 -
  static bool tm_active_with_fp(struct task_struct *tsk)
  {
 -      return msr_tm_active(tsk->thread.regs->msr) &&
 +      return MSR_TM_ACTIVE(tsk->thread.regs->msr) &&
                (tsk->thread.ckpt_regs.msr & MSR_FP);
  }
  
  static bool tm_active_with_altivec(struct task_struct *tsk)
  {
 -      return msr_tm_active(tsk->thread.regs->msr) &&
 +      return MSR_TM_ACTIVE(tsk->thread.regs->msr) &&
                (tsk->thread.ckpt_regs.msr & MSR_VEC);
  }
  #else
 -static inline bool msr_tm_active(unsigned long msr) { return false; }
  static inline void check_if_tm_restore_required(struct task_struct *tsk) { }
  static inline bool tm_active_with_fp(struct task_struct *tsk) { return false; }
  static inline bool tm_active_with_altivec(struct task_struct *tsk) { return false; }
@@@ -241,8 -247,7 +241,8 @@@ void enable_kernel_fp(void
                 * giveup as this would save  to the 'live' structure not the
                 * checkpointed structure.
                 */
 -              if(!msr_tm_active(cpumsr) && msr_tm_active(current->thread.regs->msr))
 +              if (!MSR_TM_ACTIVE(cpumsr) &&
 +                   MSR_TM_ACTIVE(current->thread.regs->msr))
                        return;
                __giveup_fpu(current);
        }
@@@ -306,8 -311,7 +306,8 @@@ void enable_kernel_altivec(void
                 * giveup as this would save  to the 'live' structure not the
                 * checkpointed structure.
                 */
 -              if(!msr_tm_active(cpumsr) && msr_tm_active(current->thread.regs->msr))
 +              if (!MSR_TM_ACTIVE(cpumsr) &&
 +                   MSR_TM_ACTIVE(current->thread.regs->msr))
                        return;
                __giveup_altivec(current);
        }
@@@ -393,8 -397,7 +393,8 @@@ void enable_kernel_vsx(void
                 * giveup as this would save  to the 'live' structure not the
                 * checkpointed structure.
                 */
 -              if(!msr_tm_active(cpumsr) && msr_tm_active(current->thread.regs->msr))
 +              if (!MSR_TM_ACTIVE(cpumsr) &&
 +                   MSR_TM_ACTIVE(current->thread.regs->msr))
                        return;
                __giveup_vsx(current);
        }
@@@ -527,7 -530,7 +527,7 @@@ void restore_math(struct pt_regs *regs
  {
        unsigned long msr;
  
 -      if (!msr_tm_active(regs->msr) &&
 +      if (!MSR_TM_ACTIVE(regs->msr) &&
                !current->thread.load_fp && !loadvec(current->thread))
                return;
  
@@@ -1303,6 -1306,16 +1303,16 @@@ void show_user_instructions(struct pt_r
  
        pc = regs->nip - (instructions_to_print * 3 / 4 * sizeof(int));
  
+       /*
+        * Make sure the NIP points at userspace, not kernel text/data or
+        * elsewhere.
+        */
+       if (!__access_ok(pc, instructions_to_print * sizeof(int), USER_DS)) {
+               pr_info("%s[%d]: Bad NIP, not dumping instructions.\n",
+                       current->comm, current->pid);
+               return;
+       }
        pr_info("%s[%d]: code: ", current->comm, current->pid);
  
        for (i = 0; i < instructions_to_print; i++) {
diff --combined arch/powerpc/kernel/tm.S
index e6b527e5c90cd1f50d683cb3bc69694ee9ccd2d9,7716374786bd97c7e56390ea587e967d75c68a2e..9fabdce255cdbb6c286de7d05af98e72a6b64015
@@@ -92,14 -92,13 +92,14 @@@ _GLOBAL(tm_abort
        blr
  EXPORT_SYMBOL_GPL(tm_abort);
  
 -/* void tm_reclaim(struct thread_struct *thread,
 +/*
 + * void tm_reclaim(struct thread_struct *thread,
   *               uint8_t cause)
   *
   *    - Performs a full reclaim.  This destroys outstanding
 - *      transactions and updates thread->regs.tm_ckpt_* with the
 - *      original checkpointed state.  Note that thread->regs is
 - *      unchanged.
 + *      transactions and updates thread.ckpt_regs, thread.ckfp_state and
 + *      thread.ckvr_state with the original checkpointed state.  Note that
 + *      thread->regs is unchanged.
   *
   * Purpose is to both abort transactions of, and preserve the state of,
   * a transactions at a context switch. We preserve/restore both sets of process
@@@ -164,22 -163,35 +164,36 @@@ _GLOBAL(tm_reclaim
         */
        TRECLAIM(R4)                            /* Cause in r4 */
  
 -      /* ******************** GPRs ******************** */
 -      /* Stash the checkpointed r13 away in the scratch SPR and get the real
 -       *  paca
 +      /*
 +       * ******************** GPRs ********************
 +       * Stash the checkpointed r13 in the scratch SPR and get the real paca.
         */
        SET_SCRATCH0(r13)
        GET_PACA(r13)
  
 -      /* Stash the checkpointed r1 away in paca tm_scratch and get the real
 -       * stack pointer back
 +      /*
 +       * Stash the checkpointed r1 away in paca->tm_scratch and get the real
 +       * stack pointer back into r1.
         */
        std     r1, PACATMSCRATCH(r13)
        ld      r1, PACAR1(r13)
  
        std     r11, GPR11(r1)                  /* Temporary stash */
  
+       /*
+        * Move the saved user r1 to the kernel stack in case PACATMSCRATCH is
+        * clobbered by an exception once we turn on MSR_RI below.
+        */
+       ld      r11, PACATMSCRATCH(r13)
+       std     r11, GPR1(r1)
+       /*
+        * Store r13 away so we can free up the scratch SPR for the SLB fault
+        * handler (needed once we start accessing the thread_struct).
+        */
+       GET_SCRATCH0(r11)
+       std     r11, GPR13(r1)
        /* Reset MSR RI so we can take SLB faults again */
        li      r11, MSR_RI
        mtmsrd  r11, 1
  
        addi    r7, r12, PT_CKPT_REGS           /* Thread's ckpt_regs */
  
 -      /* Make r7 look like an exception frame so that we
 -       * can use the neat GPRx(n) macros.  r7 is NOT a pt_regs ptr!
 +      /*
 +       * Make r7 look like an exception frame so that we can use the neat
 +       * GPRx(n) macros. r7 is NOT a pt_regs ptr!
         */
        subi    r7, r7, STACK_FRAME_OVERHEAD
  
        /* Sync the userland GPRs 2-12, 14-31 to thread->regs: */
        SAVE_GPR(0, r7)                         /* user r0 */
 -      SAVE_GPR(2, r7)                 /* user r2 */
 +      SAVE_GPR(2, r7)                         /* user r2 */
        SAVE_4GPRS(3, r7)                       /* user r3-r6 */
        SAVE_GPR(8, r7)                         /* user r8 */
        SAVE_GPR(9, r7)                         /* user r9 */
        SAVE_GPR(10, r7)                        /* user r10 */
-       ld      r3, PACATMSCRATCH(r13)          /* user r1 */
+       ld      r3, GPR1(r1)                    /* user r1 */
        ld      r4, GPR7(r1)                    /* user r7 */
        ld      r5, GPR11(r1)                   /* user r11 */
        ld      r6, GPR12(r1)                   /* user r12 */
-       GET_SCRATCH0(8)                         /* user r13 */
+       ld      r8, GPR13(r1)                   /* user r13 */
        std     r3, GPR1(r7)
        std     r4, GPR7(r7)
        std     r5, GPR11(r7)
        /* ******************** NIP ******************** */
        mfspr   r3, SPRN_TFHAR
        std     r3, _NIP(r7)                    /* Returns to failhandler */
 -      /* The checkpointed NIP is ignored when rescheduling/rechkpting,
 +      /*
 +       * The checkpointed NIP is ignored when rescheduling/rechkpting,
         * but is used in signal return to 'wind back' to the abort handler.
         */
  
        std     r3, THREAD_TM_TAR(r12)
        std     r4, THREAD_TM_DSCR(r12)
  
 -      /* MSR and flags:  We don't change CRs, and we don't need to alter
 -       * MSR.
 +      /*
 +       * MSR and flags: We don't change CRs, and we don't need to alter MSR.
         */
  
  
 -      /* ******************** FPR/VR/VSRs ************
 +      /*
 +       * ******************** FPR/VR/VSRs ************
         * After reclaiming, capture the checkpointed FPRs/VRs.
         *
         * We enabled VEC/FP/VSX in the msr above, so we can execute these
  
        /* Altivec (VEC/VMX/VR)*/
        addi    r7, r3, THREAD_CKVRSTATE
 -      SAVE_32VRS(0, r6, r7)   /* r6 scratch, r7 transact vr state */
 +      SAVE_32VRS(0, r6, r7)   /* r6 scratch, r7 ckvr_state */
        mfvscr  v0
        li      r6, VRSTATE_VSCR
        stvx    v0, r7, r6
  
        /* Floating Point (FP) */
        addi    r7, r3, THREAD_CKFPSTATE
 -      SAVE_32FPRS_VSRS(0, R6, R7)     /* r6 scratch, r7 transact fp state */
 +      SAVE_32FPRS_VSRS(0, R6, R7)     /* r6 scratch, r7 ckfp_state */
        mffs    fr0
        stfd    fr0,FPSTATE_FPSCR(r7)
  
  
 -      /* TM regs, incl TEXASR -- these live in thread_struct.  Note they've
 +      /*
 +       * TM regs, incl TEXASR -- these live in thread_struct.  Note they've
         * been updated by the treclaim, to explain to userland the failure
         * cause (aborted).
         */
        blr
  
  
 -       /*
 +      /*
         * void __tm_recheckpoint(struct thread_struct *thread)
         *      - Restore the checkpointed register state saved by tm_reclaim
         *        when we switch_to a process.
@@@ -335,8 -343,7 +349,8 @@@ _GLOBAL(__tm_recheckpoint
        std     r2, STK_GOT(r1)
        stdu    r1, -TM_FRAME_SIZE(r1)
  
 -      /* We've a struct pt_regs at [r1+STACK_FRAME_OVERHEAD].
 +      /*
 +       * We've a struct pt_regs at [r1+STACK_FRAME_OVERHEAD].
         * This is used for backing up the NVGPRs:
         */
        SAVE_NVGPRS(r1)
  
        addi    r7, r3, PT_CKPT_REGS            /* Thread's ckpt_regs */
  
 -      /* Make r7 look like an exception frame so that we
 -       * can use the neat GPRx(n) macros.  r7 is now NOT a pt_regs ptr!
 +      /*
 +       * Make r7 look like an exception frame so that we can use the neat
 +       * GPRx(n) macros. r7 is now NOT a pt_regs ptr!
         */
        subi    r7, r7, STACK_FRAME_OVERHEAD
  
@@@ -415,15 -421,14 +429,15 @@@ restore_gprs
  
        REST_NVGPRS(r7)                         /* GPR14-31 */
  
 -      /* Load up PPR and DSCR here so we don't run with user values for long
 -       */
 +      /* Load up PPR and DSCR here so we don't run with user values for long */
        mtspr   SPRN_DSCR, r5
        mtspr   SPRN_PPR, r6
  
 -      /* Do final sanity check on TEXASR to make sure FS is set.  Do this
 +      /*
 +       * Do final sanity check on TEXASR to make sure FS is set. Do this
         * here before we load up the userspace r1 so any bugs we hit will get
 -       * a call chain */
 +       * a call chain.
 +       */
        mfspr   r5, SPRN_TEXASR
        srdi    r5, r5, 16
        li      r6, (TEXASR_FS)@h
  1:    tdeqi   r6, 0
        EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0
  
 -      /* Do final sanity check on MSR to make sure we are not transactional
 -       * or suspended
 +      /*
 +       * Do final sanity check on MSR to make sure we are not transactional
 +       * or suspended.
         */
        mfmsr   r6
        li      r5, (MSR_TS_MASK)@higher
        REST_GPR(6, r7)
  
        /*
 -       * Store r1 and r5 on the stack so that we can access them
 -       * after we clear MSR RI.
 +       * Store r1 and r5 on the stack so that we can access them after we
 +       * clear MSR RI.
         */
  
        REST_GPR(5, r7)
  
        HMT_MEDIUM
  
 -      /* Our transactional state has now changed.
 +      /*
 +       * Our transactional state has now changed.
         *
         * Now just get out of here.  Transactional (current) state will be
         * updated once restore is called on the return path in the _switch-ed
index 1ee59978508ddb24795f2b7f8441b7f9191178cc,923d531265f8c22d3adf2442e0a48fc7c1fffb5d..9b35ca8e8f13d4bbe77ba24d3e061031071c39c3
@@@ -2,8 -2,9 +2,9 @@@
  TEST_PROGS := ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \
                ptrace-tar ptrace-tm-tar ptrace-tm-spd-tar ptrace-vsx ptrace-tm-vsx \
                ptrace-tm-spd-vsx ptrace-tm-spr ptrace-hwbreak ptrace-pkey core-pkey \
 -              perf-hwbreak
 +              perf-hwbreak ptrace-syscall
  
+ top_srcdir = ../../../../..
  include ../../lib.mk
  
  all: $(TEST_PROGS)