Merge branch 'nmi' of git://ftp.arm.linux.org.uk/~rmk/linux-arm
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 8 Sep 2015 19:28:10 +0000 (12:28 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 8 Sep 2015 19:28:10 +0000 (12:28 -0700)
Pull NMI backtrace update from Russell King:
 "These changes convert the x86 NMI handling to be a library
  implementation which other architectures can make use of.  Thomas
  Gleixner has reviewed and tested these changes, and wishes me to send
  these rather than taking them through the tip tree.

  The final patch in the set adds an initial implementation using this
  infrastructure to ARM, even though it doesn't send the IPI at "NMI"
  level.  Patches are in progress to add the ARM equivalent of NMI, but
  we still need the IRQ-level fallback for systems where the "NMI" isn't
  available due to secure firmware denying access to it"

* 'nmi' of git://ftp.arm.linux.org.uk/~rmk/linux-arm:
  ARM: add basic support for on-demand backtrace of other CPUs
  nmi: x86: convert to generic nmi handler
  nmi: create generic NMI backtrace implementation

1  2 
arch/arm/kernel/smp.c
include/linux/nmi.h
lib/Makefile

diff --combined arch/arm/kernel/smp.c
@@@ -21,6 -21,7 +21,7 @@@
  #include <linux/cpu.h>
  #include <linux/seq_file.h>
  #include <linux/irq.h>
+ #include <linux/nmi.h>
  #include <linux/percpu.h>
  #include <linux/clockchips.h>
  #include <linux/completion.h>
@@@ -72,6 -73,7 +73,7 @@@ enum ipi_msg_type 
        IPI_CPU_STOP,
        IPI_IRQ_WORK,
        IPI_COMPLETION,
+       IPI_CPU_BACKTRACE = 15,
  };
  
  static DECLARE_COMPLETION(cpu_running);
@@@ -175,26 -177,13 +177,26 @@@ static int platform_cpu_disable(unsigne
        if (smp_ops.cpu_disable)
                return smp_ops.cpu_disable(cpu);
  
 +      return 0;
 +}
 +
 +int platform_can_hotplug_cpu(unsigned int cpu)
 +{
 +      /* cpu_die must be specified to support hotplug */
 +      if (!smp_ops.cpu_die)
 +              return 0;
 +
 +      if (smp_ops.cpu_can_disable)
 +              return smp_ops.cpu_can_disable(cpu);
 +
        /*
         * By default, allow disabling all CPUs except the first one,
         * since this is special on a lot of platforms, e.g. because
         * of clock tick interrupts.
         */
 -      return cpu == 0 ? -EPERM : 0;
 +      return cpu != 0;
  }
 +
  /*
   * __cpu_disable runs on the processor to be shutdown.
   */
@@@ -266,7 -255,7 +268,7 @@@ void __cpu_die(unsigned int cpu
   * of the other hotplug-cpu capable cores, so presumably coming
   * out of idle fixes this.
   */
 -void __ref cpu_die(void)
 +void arch_cpu_idle_dead(void)
  {
        unsigned int cpu = smp_processor_id();
  
@@@ -591,7 -580,7 +593,7 @@@ void handle_IPI(int ipinr, struct pt_re
        struct pt_regs *old_regs = set_irq_regs(regs);
  
        if ((unsigned)ipinr < NR_IPI) {
 -              trace_ipi_entry(ipi_types[ipinr]);
 +              trace_ipi_entry_rcuidle(ipi_types[ipinr]);
                __inc_irq_stat(cpu, ipi_irqs[ipinr]);
        }
  
                irq_exit();
                break;
  
+       case IPI_CPU_BACKTRACE:
+               irq_enter();
+               nmi_cpu_backtrace(regs);
+               irq_exit();
+               break;
        default:
                pr_crit("CPU%u: Unknown IPI message 0x%x\n",
                        cpu, ipinr);
        }
  
        if ((unsigned)ipinr < NR_IPI)
 -              trace_ipi_exit(ipi_types[ipinr]);
 +              trace_ipi_exit_rcuidle(ipi_types[ipinr]);
        set_irq_regs(old_regs);
  }
  
@@@ -737,3 -732,13 +745,13 @@@ static int __init register_cpufreq_noti
  core_initcall(register_cpufreq_notifier);
  
  #endif
+ static void raise_nmi(cpumask_t *mask)
+ {
+       smp_cross_call(mask, IPI_CPU_BACKTRACE);
+ }
+ void arch_trigger_all_cpu_backtrace(bool include_self)
+ {
+       nmi_trigger_all_cpu_backtrace(include_self, raise_nmi);
+ }
diff --combined include/linux/nmi.h
@@@ -27,7 -27,9 +27,7 @@@ static inline void touch_nmi_watchdog(v
  #if defined(CONFIG_HARDLOCKUP_DETECTOR)
  extern void hardlockup_detector_disable(void);
  #else
 -static inline void hardlockup_detector_disable(void)
 -{
 -}
 +static inline void hardlockup_detector_disable(void) {}
  #endif
  
  /*
@@@ -47,6 -49,12 +47,12 @@@ static inline bool trigger_allbutself_c
        arch_trigger_all_cpu_backtrace(false);
        return true;
  }
+ /* generic implementation */
+ void nmi_trigger_all_cpu_backtrace(bool include_self,
+                                  void (*raise)(cpumask_t *mask));
+ bool nmi_cpu_backtrace(struct pt_regs *regs);
  #else
  static inline bool trigger_all_cpu_backtrace(void)
  {
@@@ -78,17 -86,6 +84,17 @@@ extern int proc_watchdog_thresh(struct 
                                void __user *, size_t *, loff_t *);
  extern int proc_watchdog_cpumask(struct ctl_table *, int,
                                 void __user *, size_t *, loff_t *);
 +extern int lockup_detector_suspend(void);
 +extern void lockup_detector_resume(void);
 +#else
 +static inline int lockup_detector_suspend(void)
 +{
 +      return 0;
 +}
 +
 +static inline void lockup_detector_resume(void)
 +{
 +}
  #endif
  
  #ifdef CONFIG_HAVE_ACPI_APEI_NMI
diff --combined lib/Makefile
@@@ -13,7 -13,7 +13,7 @@@ lib-y := ctype.o string.o vsprintf.o cm
         sha1.o md5.o irq_regs.o argv_split.o \
         proportions.o flex_proportions.o ratelimit.o show_mem.o \
         is_single_threaded.o plist.o decompress.o kobject_uevent.o \
-        earlycpio.o seq_buf.o
+        earlycpio.o seq_buf.o nmi_backtrace.o
  
  obj-$(CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS) += usercopy.o
  lib-$(CONFIG_MMU) += ioremap.o
@@@ -39,8 -39,6 +39,8 @@@ obj-$(CONFIG_TEST_KSTRTOX) += test-kstr
  obj-$(CONFIG_TEST_LKM) += test_module.o
  obj-$(CONFIG_TEST_RHASHTABLE) += test_rhashtable.o
  obj-$(CONFIG_TEST_USER_COPY) += test_user_copy.o
 +obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_keys.o
 +obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_key_base.o
  
  ifeq ($(CONFIG_DEBUG_KOBJECT),y)
  CFLAGS_kobject.o += -DDEBUG
@@@ -140,6 -138,8 +140,6 @@@ obj-$(CONFIG_GENERIC_ATOMIC64) += atomi
  
  obj-$(CONFIG_ATOMIC64_SELFTEST) += atomic64_test.o
  
 -obj-$(CONFIG_AVERAGE) += average.o
 -
  obj-$(CONFIG_CPU_RMAP) += cpu_rmap.o
  
  obj-$(CONFIG_CORDIC) += cordic.o
@@@ -160,7 -160,6 +160,7 @@@ obj-$(CONFIG_GENERIC_STRNLEN_USER) += s
  
  obj-$(CONFIG_GENERIC_NET_UTILS) += net_utils.o
  
 +obj-$(CONFIG_SG_SPLIT) += sg_split.o
  obj-$(CONFIG_STMP_DEVICE) += stmp_device.o
  
  libfdt_files = fdt.o fdt_ro.o fdt_wip.o fdt_rw.o fdt_sw.o fdt_strerror.o \