18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * NMI backtrace support 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Gratuitously copied from arch/x86/kernel/apic/hw_nmi.c by Russell King, 68c2ecf20Sopenharmony_ci * with the following header: 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * HW NMI watchdog support 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * started by Don Zickus, Copyright (C) 2010 Red Hat, Inc. 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * Arch specific calls to support NMI watchdog 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * Bits copied from original nmi.c file 158c2ecf20Sopenharmony_ci */ 168c2ecf20Sopenharmony_ci#include <linux/cpumask.h> 178c2ecf20Sopenharmony_ci#include <linux/delay.h> 188c2ecf20Sopenharmony_ci#include <linux/kprobes.h> 198c2ecf20Sopenharmony_ci#include <linux/nmi.h> 208c2ecf20Sopenharmony_ci#include <linux/cpu.h> 218c2ecf20Sopenharmony_ci#include <linux/sched/debug.h> 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#ifdef arch_trigger_cpumask_backtrace 248c2ecf20Sopenharmony_ci/* For reliability, we're prepared to waste bits here. */ 258c2ecf20Sopenharmony_cistatic DECLARE_BITMAP(backtrace_mask, NR_CPUS) __read_mostly; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci/* "in progress" flag of arch_trigger_cpumask_backtrace */ 288c2ecf20Sopenharmony_cistatic unsigned long backtrace_flag; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci/* 318c2ecf20Sopenharmony_ci * When raise() is called it will be passed a pointer to the 328c2ecf20Sopenharmony_ci * backtrace_mask. Architectures that call nmi_cpu_backtrace() 338c2ecf20Sopenharmony_ci * directly from their raise() functions may rely on the mask 348c2ecf20Sopenharmony_ci * they are passed being updated as a side effect of this call. 358c2ecf20Sopenharmony_ci */ 368c2ecf20Sopenharmony_civoid nmi_trigger_cpumask_backtrace(const cpumask_t *mask, 378c2ecf20Sopenharmony_ci bool exclude_self, 388c2ecf20Sopenharmony_ci void (*raise)(cpumask_t *mask)) 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci int i, this_cpu = get_cpu(); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci if (test_and_set_bit(0, &backtrace_flag)) { 438c2ecf20Sopenharmony_ci /* 448c2ecf20Sopenharmony_ci * If there is already a trigger_all_cpu_backtrace() in progress 458c2ecf20Sopenharmony_ci * (backtrace_flag == 1), don't output double cpu dump infos. 468c2ecf20Sopenharmony_ci */ 478c2ecf20Sopenharmony_ci put_cpu(); 488c2ecf20Sopenharmony_ci return; 498c2ecf20Sopenharmony_ci } 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci cpumask_copy(to_cpumask(backtrace_mask), mask); 528c2ecf20Sopenharmony_ci if (exclude_self) 538c2ecf20Sopenharmony_ci cpumask_clear_cpu(this_cpu, to_cpumask(backtrace_mask)); 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci /* 568c2ecf20Sopenharmony_ci * Don't try to send an NMI to this cpu; it may work on some 578c2ecf20Sopenharmony_ci * architectures, but on others it may not, and we'll get 588c2ecf20Sopenharmony_ci * information at least as useful just by doing a dump_stack() here. 598c2ecf20Sopenharmony_ci * Note that nmi_cpu_backtrace(NULL) will clear the cpu bit. 608c2ecf20Sopenharmony_ci */ 618c2ecf20Sopenharmony_ci if (cpumask_test_cpu(this_cpu, to_cpumask(backtrace_mask))) 628c2ecf20Sopenharmony_ci nmi_cpu_backtrace(NULL); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci if (!cpumask_empty(to_cpumask(backtrace_mask))) { 658c2ecf20Sopenharmony_ci pr_info("Sending NMI from CPU %d to CPUs %*pbl:\n", 668c2ecf20Sopenharmony_ci this_cpu, nr_cpumask_bits, to_cpumask(backtrace_mask)); 678c2ecf20Sopenharmony_ci raise(to_cpumask(backtrace_mask)); 688c2ecf20Sopenharmony_ci } 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci /* Wait for up to 10 seconds for all CPUs to do the backtrace */ 718c2ecf20Sopenharmony_ci for (i = 0; i < 10 * 1000; i++) { 728c2ecf20Sopenharmony_ci if (cpumask_empty(to_cpumask(backtrace_mask))) 738c2ecf20Sopenharmony_ci break; 748c2ecf20Sopenharmony_ci mdelay(1); 758c2ecf20Sopenharmony_ci touch_softlockup_watchdog(); 768c2ecf20Sopenharmony_ci } 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci /* 798c2ecf20Sopenharmony_ci * Force flush any remote buffers that might be stuck in IRQ context 808c2ecf20Sopenharmony_ci * and therefore could not run their irq_work. 818c2ecf20Sopenharmony_ci */ 828c2ecf20Sopenharmony_ci printk_safe_flush(); 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci clear_bit_unlock(0, &backtrace_flag); 858c2ecf20Sopenharmony_ci put_cpu(); 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci// Dump stacks even for idle CPUs. 898c2ecf20Sopenharmony_cistatic bool backtrace_idle; 908c2ecf20Sopenharmony_cimodule_param(backtrace_idle, bool, 0644); 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_cibool nmi_cpu_backtrace(struct pt_regs *regs) 938c2ecf20Sopenharmony_ci{ 948c2ecf20Sopenharmony_ci int cpu = smp_processor_id(); 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) { 978c2ecf20Sopenharmony_ci if (!READ_ONCE(backtrace_idle) && regs && cpu_in_idle(instruction_pointer(regs))) { 988c2ecf20Sopenharmony_ci pr_warn("NMI backtrace for cpu %d skipped: idling at %pS\n", 998c2ecf20Sopenharmony_ci cpu, (void *)instruction_pointer(regs)); 1008c2ecf20Sopenharmony_ci } else { 1018c2ecf20Sopenharmony_ci pr_warn("NMI backtrace for cpu %d\n", cpu); 1028c2ecf20Sopenharmony_ci if (regs) 1038c2ecf20Sopenharmony_ci show_regs(regs); 1048c2ecf20Sopenharmony_ci else 1058c2ecf20Sopenharmony_ci dump_stack(); 1068c2ecf20Sopenharmony_ci } 1078c2ecf20Sopenharmony_ci cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask)); 1088c2ecf20Sopenharmony_ci return true; 1098c2ecf20Sopenharmony_ci } 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci return false; 1128c2ecf20Sopenharmony_ci} 1138c2ecf20Sopenharmony_ciNOKPROBE_SYMBOL(nmi_cpu_backtrace); 1148c2ecf20Sopenharmony_ci#endif 115