Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux...
authorMichael Ellerman <mpe@ellerman.id.au>
Wed, 20 Sep 2017 10:05:24 +0000 (20:05 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 20 Sep 2017 10:05:24 +0000 (20:05 +1000)
Merge one commit from Scott which I missed while away.

1  2 
arch/powerpc/kernel/traps.c

index ec74e203ee04e5b8e7e307df28c133b6226cd487,410352acfa38318403c9080514942cc1e86ee85d..13c9dcdcba6922e32d4c00267201f47e9498f805
@@@ -114,28 -114,6 +114,28 @@@ static void pmac_backlight_unblank(void
  static inline void pmac_backlight_unblank(void) { }
  #endif
  
 +/*
 + * If oops/die is expected to crash the machine, return true here.
 + *
 + * This should not be expected to be 100% accurate, there may be
 + * notifiers registered or other unexpected conditions that may bring
 + * down the kernel. Or if the current process in the kernel is holding
 + * locks or has other critical state, the kernel may become effectively
 + * unusable anyway.
 + */
 +bool die_will_crash(void)
 +{
 +      if (should_fadump_crash())
 +              return true;
 +      if (kexec_should_crash(current))
 +              return true;
 +      if (in_interrupt() || panic_on_oops ||
 +                      !current->pid || is_global_init(current))
 +              return true;
 +
 +      return false;
 +}
 +
  static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;
  static int die_owner = -1;
  static unsigned int die_nest_count;
@@@ -184,9 -162,21 +184,9 @@@ static void oops_end(unsigned long flag
  
        crash_fadump(regs, "die oops");
  
 -      /*
 -       * A system reset (0x100) is a request to dump, so we always send
 -       * it through the crashdump code.
 -       */
 -      if (kexec_should_crash(current) || (TRAP(regs) == 0x100)) {
 +      if (kexec_should_crash(current))
                crash_kexec(regs);
  
 -              /*
 -               * We aren't the primary crash CPU. We need to send it
 -               * to a holding pattern to avoid it ending up in the panic
 -               * code.
 -               */
 -              crash_kexec_secondary(regs);
 -      }
 -
        if (!signr)
                return;
  
@@@ -212,25 -202,18 +212,25 @@@ NOKPROBE_SYMBOL(oops_end)
  static int __die(const char *str, struct pt_regs *regs, long err)
  {
        printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
 -#ifdef CONFIG_PREEMPT
 -      printk("PREEMPT ");
 -#endif
 -#ifdef CONFIG_SMP
 -      printk("SMP NR_CPUS=%d ", NR_CPUS);
 -#endif
 +
 +      if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN))
 +              printk("LE ");
 +      else
 +              printk("BE ");
 +
 +      if (IS_ENABLED(CONFIG_PREEMPT))
 +              pr_cont("PREEMPT ");
 +
 +      if (IS_ENABLED(CONFIG_SMP))
 +              pr_cont("SMP NR_CPUS=%d ", NR_CPUS);
 +
        if (debug_pagealloc_enabled())
 -              printk("DEBUG_PAGEALLOC ");
 -#ifdef CONFIG_NUMA
 -      printk("NUMA ");
 -#endif
 -      printk("%s\n", ppc_md.name ? ppc_md.name : "");
 +              pr_cont("DEBUG_PAGEALLOC ");
 +
 +      if (IS_ENABLED(CONFIG_NUMA))
 +              pr_cont("NUMA ");
 +
 +      pr_cont("%s\n", ppc_md.name ? ppc_md.name : "");
  
        if (notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV) == NOTIFY_STOP)
                return 1;
@@@ -313,44 -296,17 +313,44 @@@ void system_reset_exception(struct pt_r
                        goto out;
        }
  
 -      die("System Reset", regs, SIGABRT);
 +      if (debugger(regs))
 +              goto out;
 +
 +      /*
 +       * A system reset is a request to dump, so we always send
 +       * it through the crashdump code (if fadump or kdump are
 +       * registered).
 +       */
 +      crash_fadump(regs, "System Reset");
 +
 +      crash_kexec(regs);
 +
 +      /*
 +       * We aren't the primary crash CPU. We need to send it
 +       * to a holding pattern to avoid it ending up in the panic
 +       * code.
 +       */
 +      crash_kexec_secondary(regs);
 +
 +      /*
 +       * No debugger or crash dump registered, print logs then
 +       * panic.
 +       */
 +      __die("System Reset", regs, SIGABRT);
 +
 +      mdelay(2*MSEC_PER_SEC); /* Wait a little while for others to print */
 +      add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
 +      nmi_panic(regs, "System Reset");
  
  out:
  #ifdef CONFIG_PPC_BOOK3S_64
        BUG_ON(get_paca()->in_nmi == 0);
        if (get_paca()->in_nmi > 1)
 -              panic("Unrecoverable nested System Reset");
 +              nmi_panic(regs, "Unrecoverable nested System Reset");
  #endif
        /* Must die if the interrupt is not recoverable */
        if (!(regs->msr & MSR_RI))
 -              panic("Unrecoverable System Reset");
 +              nmi_panic(regs, "Unrecoverable System Reset");
  
        if (!nested)
                nmi_exit();
@@@ -437,6 -393,7 +437,7 @@@ static inline int check_io_access(struc
  int machine_check_e500mc(struct pt_regs *regs)
  {
        unsigned long mcsr = mfspr(SPRN_MCSR);
+       unsigned long pvr = mfspr(SPRN_PVR);
        unsigned long reason = mcsr;
        int recoverable = 1;
  
                 * may still get logged and cause a machine check.  We should
                 * only treat the non-write shadow case as non-recoverable.
                 */
-               if (!(mfspr(SPRN_L1CSR2) & L1CSR2_DCWS))
-                       recoverable = 0;
+               /* On e6500 core, L1 DCWS (Data cache write shadow mode) bit
+                * is not implemented but L1 data cache always runs in write
+                * shadow mode. Hence on data cache parity errors HW will
+                * automatically invalidate the L1 Data Cache.
+                */
+               if (PVR_VER(pvr) != PVR_VER_E6500) {
+                       if (!(mfspr(SPRN_L1CSR2) & L1CSR2_DCWS))
+                               recoverable = 0;
+               }
        }
  
        if (reason & MCSR_L2MMU_MHIT) {
@@@ -644,10 -608,8 +652,10 @@@ int machine_check_generic(struct pt_reg
  
  void machine_check_exception(struct pt_regs *regs)
  {
 -      enum ctx_state prev_state = exception_enter();
        int recover = 0;
 +      bool nested = in_nmi();
 +      if (!nested)
 +              nmi_enter();
  
        /* 64s accounts the mce in machine_check_early when in HVMODE */
        if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64) || !cpu_has_feature(CPU_FTR_HVMODE))
  
        /* Must die if the interrupt is not recoverable */
        if (!(regs->msr & MSR_RI))
 -              panic("Unrecoverable Machine check");
 +              nmi_panic(regs, "Unrecoverable Machine check");
  
  bail:
 -      exception_exit(prev_state);
 +      if (!nested)
 +              nmi_exit();
  }
  
  void SMIException(struct pt_regs *regs)