0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/thread_info.h>
0013 #include <asm/apic.h>
0014 #include <asm/nmi.h>
0015
0016 #include <linux/cpumask.h>
0017 #include <linux/kdebug.h>
0018 #include <linux/notifier.h>
0019 #include <linux/kprobes.h>
0020 #include <linux/nmi.h>
0021 #include <linux/init.h>
0022 #include <linux/delay.h>
0023
0024 #ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF
0025 u64 hw_nmi_get_sample_period(int watchdog_thresh)
0026 {
0027 return (u64)(cpu_khz) * 1000 * watchdog_thresh;
0028 }
0029 #endif
0030
0031 #ifdef arch_trigger_cpumask_backtrace
0032 static void nmi_raise_cpu_backtrace(cpumask_t *mask)
0033 {
0034 apic->send_IPI_mask(mask, NMI_VECTOR);
0035 }
0036
0037 void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self)
0038 {
0039 nmi_trigger_cpumask_backtrace(mask, exclude_self,
0040 nmi_raise_cpu_backtrace);
0041 }
0042
0043 static int nmi_cpu_backtrace_handler(unsigned int cmd, struct pt_regs *regs)
0044 {
0045 if (nmi_cpu_backtrace(regs))
0046 return NMI_HANDLED;
0047
0048 return NMI_DONE;
0049 }
0050 NOKPROBE_SYMBOL(nmi_cpu_backtrace_handler);
0051
0052 static int __init register_nmi_cpu_backtrace_handler(void)
0053 {
0054 register_nmi_handler(NMI_LOCAL, nmi_cpu_backtrace_handler,
0055 0, "arch_bt");
0056 return 0;
0057 }
0058 early_initcall(register_nmi_cpu_backtrace_handler);
0059 #endif