Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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