VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
b24413180f560 (Greg Kroah-Hartman 2017-11-01 15:07:57 +0100   1) // SPDX-License-Identifier: GPL-2.0
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100   2) /*
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100   3)  *  NMI backtrace support
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100   4)  *
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100   5)  * Gratuitously copied from arch/x86/kernel/apic/hw_nmi.c by Russell King,
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100   6)  * with the following header:
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100   7)  *
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100   8)  *  HW NMI watchdog support
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100   9)  *
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  10)  *  started by Don Zickus, Copyright (C) 2010 Red Hat, Inc.
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  11)  *
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  12)  *  Arch specific calls to support NMI watchdog
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  13)  *
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  14)  *  Bits copied from original nmi.c file
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  15)  */
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  16) #include <linux/cpumask.h>
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  17) #include <linux/delay.h>
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  18) #include <linux/kprobes.h>
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  19) #include <linux/nmi.h>
6727ad9e206cc (Chris Metcalf      2016-10-07 17:02:55 -0700  20) #include <linux/cpu.h>
b17b01533b719 (Ingo Molnar        2017-02-08 18:51:35 +0100  21) #include <linux/sched/debug.h>
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  22) 
9a01c3ed5cdb3 (Chris Metcalf      2016-10-07 17:02:45 -0700  23) #ifdef arch_trigger_cpumask_backtrace
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  24) /* For reliability, we're prepared to waste bits here. */
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  25) static DECLARE_BITMAP(backtrace_mask, NR_CPUS) __read_mostly;
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  26) 
9a01c3ed5cdb3 (Chris Metcalf      2016-10-07 17:02:45 -0700  27) /* "in progress" flag of arch_trigger_cpumask_backtrace */
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  28) static unsigned long backtrace_flag;
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  29) 
0768330d46435 (Daniel Thompson    2015-09-22 17:12:10 +0100  30) /*
9a01c3ed5cdb3 (Chris Metcalf      2016-10-07 17:02:45 -0700  31)  * When raise() is called it will be passed a pointer to the
0768330d46435 (Daniel Thompson    2015-09-22 17:12:10 +0100  32)  * backtrace_mask. Architectures that call nmi_cpu_backtrace()
0768330d46435 (Daniel Thompson    2015-09-22 17:12:10 +0100  33)  * directly from their raise() functions may rely on the mask
0768330d46435 (Daniel Thompson    2015-09-22 17:12:10 +0100  34)  * they are passed being updated as a side effect of this call.
0768330d46435 (Daniel Thompson    2015-09-22 17:12:10 +0100  35)  */
9a01c3ed5cdb3 (Chris Metcalf      2016-10-07 17:02:45 -0700  36) void nmi_trigger_cpumask_backtrace(const cpumask_t *mask,
9a01c3ed5cdb3 (Chris Metcalf      2016-10-07 17:02:45 -0700  37) 				   bool exclude_self,
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  38) 				   void (*raise)(cpumask_t *mask))
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  39) {
42a0bb3f71383 (Petr Mladek        2016-05-20 17:00:33 -0700  40) 	int i, this_cpu = get_cpu();
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  41) 
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  42) 	if (test_and_set_bit(0, &backtrace_flag)) {
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  43) 		/*
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  44) 		 * If there is already a trigger_all_cpu_backtrace() in progress
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  45) 		 * (backtrace_flag == 1), don't output double cpu dump infos.
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  46) 		 */
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  47) 		put_cpu();
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  48) 		return;
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  49) 	}
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  50) 
9a01c3ed5cdb3 (Chris Metcalf      2016-10-07 17:02:45 -0700  51) 	cpumask_copy(to_cpumask(backtrace_mask), mask);
9a01c3ed5cdb3 (Chris Metcalf      2016-10-07 17:02:45 -0700  52) 	if (exclude_self)
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  53) 		cpumask_clear_cpu(this_cpu, to_cpumask(backtrace_mask));
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  54) 
6776648952782 (Chris Metcalf      2016-10-07 17:02:49 -0700  55) 	/*
6776648952782 (Chris Metcalf      2016-10-07 17:02:49 -0700  56) 	 * Don't try to send an NMI to this cpu; it may work on some
6776648952782 (Chris Metcalf      2016-10-07 17:02:49 -0700  57) 	 * architectures, but on others it may not, and we'll get
6776648952782 (Chris Metcalf      2016-10-07 17:02:49 -0700  58) 	 * information at least as useful just by doing a dump_stack() here.
6776648952782 (Chris Metcalf      2016-10-07 17:02:49 -0700  59) 	 * Note that nmi_cpu_backtrace(NULL) will clear the cpu bit.
6776648952782 (Chris Metcalf      2016-10-07 17:02:49 -0700  60) 	 */
6776648952782 (Chris Metcalf      2016-10-07 17:02:49 -0700  61) 	if (cpumask_test_cpu(this_cpu, to_cpumask(backtrace_mask)))
6776648952782 (Chris Metcalf      2016-10-07 17:02:49 -0700  62) 		nmi_cpu_backtrace(NULL);
6776648952782 (Chris Metcalf      2016-10-07 17:02:49 -0700  63) 
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  64) 	if (!cpumask_empty(to_cpumask(backtrace_mask))) {
9a01c3ed5cdb3 (Chris Metcalf      2016-10-07 17:02:45 -0700  65) 		pr_info("Sending NMI from CPU %d to CPUs %*pbl:\n",
9a01c3ed5cdb3 (Chris Metcalf      2016-10-07 17:02:45 -0700  66) 			this_cpu, nr_cpumask_bits, to_cpumask(backtrace_mask));
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  67) 		raise(to_cpumask(backtrace_mask));
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  68) 	}
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  69) 
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  70) 	/* Wait for up to 10 seconds for all CPUs to do the backtrace */
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  71) 	for (i = 0; i < 10 * 1000; i++) {
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  72) 		if (cpumask_empty(to_cpumask(backtrace_mask)))
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  73) 			break;
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  74) 		mdelay(1);
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  75) 		touch_softlockup_watchdog();
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  76) 	}
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  77) 
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  78) 	/*
42a0bb3f71383 (Petr Mladek        2016-05-20 17:00:33 -0700  79) 	 * Force flush any remote buffers that might be stuck in IRQ context
42a0bb3f71383 (Petr Mladek        2016-05-20 17:00:33 -0700  80) 	 * and therefore could not run their irq_work.
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  81) 	 */
f92bac3b141b8 (Sergey Senozhatsky 2016-12-27 23:16:05 +0900  82) 	printk_safe_flush();
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  83) 
42a0bb3f71383 (Petr Mladek        2016-05-20 17:00:33 -0700  84) 	clear_bit_unlock(0, &backtrace_flag);
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  85) 	put_cpu();
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  86) }
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  87) 
160c7ba34605d (Paul E. McKenney   2020-07-08 16:25:43 -0700  88) // Dump stacks even for idle CPUs.
160c7ba34605d (Paul E. McKenney   2020-07-08 16:25:43 -0700  89) static bool backtrace_idle;
160c7ba34605d (Paul E. McKenney   2020-07-08 16:25:43 -0700  90) module_param(backtrace_idle, bool, 0644);
160c7ba34605d (Paul E. McKenney   2020-07-08 16:25:43 -0700  91) 
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  92) bool nmi_cpu_backtrace(struct pt_regs *regs)
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  93) {
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  94) 	int cpu = smp_processor_id();
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  95) 
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100  96) 	if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) {
160c7ba34605d (Paul E. McKenney   2020-07-08 16:25:43 -0700  97) 		if (!READ_ONCE(backtrace_idle) && regs && cpu_in_idle(instruction_pointer(regs))) {
2f9b7e08cb27d (Liu, Changcheng    2017-11-17 15:28:20 -0800  98) 			pr_warn("NMI backtrace for cpu %d skipped: idling at %pS\n",
2f9b7e08cb27d (Liu, Changcheng    2017-11-17 15:28:20 -0800  99) 				cpu, (void *)instruction_pointer(regs));
6727ad9e206cc (Chris Metcalf      2016-10-07 17:02:55 -0700 100) 		} else {
6727ad9e206cc (Chris Metcalf      2016-10-07 17:02:55 -0700 101) 			pr_warn("NMI backtrace for cpu %d\n", cpu);
6727ad9e206cc (Chris Metcalf      2016-10-07 17:02:55 -0700 102) 			if (regs)
6727ad9e206cc (Chris Metcalf      2016-10-07 17:02:55 -0700 103) 				show_regs(regs);
6727ad9e206cc (Chris Metcalf      2016-10-07 17:02:55 -0700 104) 			else
6727ad9e206cc (Chris Metcalf      2016-10-07 17:02:55 -0700 105) 				dump_stack();
6727ad9e206cc (Chris Metcalf      2016-10-07 17:02:55 -0700 106) 		}
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100 107) 		cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100 108) 		return true;
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100 109) 	}
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100 110) 
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100 111) 	return false;
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100 112) }
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100 113) NOKPROBE_SYMBOL(nmi_cpu_backtrace);
b2c0b2cbb282f (Russell King       2014-09-03 23:57:13 +0100 114) #endif