162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *  HW NMI watchdog support
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci *  started by Don Zickus, Copyright (C) 2010 Red Hat, Inc.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci *  Arch specific calls to support NMI watchdog
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci *  Bits copied from original nmi.c file
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci */
1262306a36Sopenharmony_ci#include <linux/thread_info.h>
1362306a36Sopenharmony_ci#include <asm/apic.h>
1462306a36Sopenharmony_ci#include <asm/nmi.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include <linux/cpumask.h>
1762306a36Sopenharmony_ci#include <linux/kdebug.h>
1862306a36Sopenharmony_ci#include <linux/notifier.h>
1962306a36Sopenharmony_ci#include <linux/kprobes.h>
2062306a36Sopenharmony_ci#include <linux/nmi.h>
2162306a36Sopenharmony_ci#include <linux/init.h>
2262306a36Sopenharmony_ci#include <linux/delay.h>
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#include "local.h"
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF
2762306a36Sopenharmony_ciu64 hw_nmi_get_sample_period(int watchdog_thresh)
2862306a36Sopenharmony_ci{
2962306a36Sopenharmony_ci	return (u64)(cpu_khz) * 1000 * watchdog_thresh;
3062306a36Sopenharmony_ci}
3162306a36Sopenharmony_ci#endif
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#ifdef arch_trigger_cpumask_backtrace
3462306a36Sopenharmony_cistatic void nmi_raise_cpu_backtrace(cpumask_t *mask)
3562306a36Sopenharmony_ci{
3662306a36Sopenharmony_ci	__apic_send_IPI_mask(mask, NMI_VECTOR);
3762306a36Sopenharmony_ci}
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_civoid arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu)
4062306a36Sopenharmony_ci{
4162306a36Sopenharmony_ci	nmi_trigger_cpumask_backtrace(mask, exclude_cpu,
4262306a36Sopenharmony_ci				      nmi_raise_cpu_backtrace);
4362306a36Sopenharmony_ci}
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cistatic int nmi_cpu_backtrace_handler(unsigned int cmd, struct pt_regs *regs)
4662306a36Sopenharmony_ci{
4762306a36Sopenharmony_ci	if (nmi_cpu_backtrace(regs))
4862306a36Sopenharmony_ci		return NMI_HANDLED;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	return NMI_DONE;
5162306a36Sopenharmony_ci}
5262306a36Sopenharmony_ciNOKPROBE_SYMBOL(nmi_cpu_backtrace_handler);
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_cistatic int __init register_nmi_cpu_backtrace_handler(void)
5562306a36Sopenharmony_ci{
5662306a36Sopenharmony_ci	register_nmi_handler(NMI_LOCAL, nmi_cpu_backtrace_handler,
5762306a36Sopenharmony_ci				0, "arch_bt");
5862306a36Sopenharmony_ci	return 0;
5962306a36Sopenharmony_ci}
6062306a36Sopenharmony_ciearly_initcall(register_nmi_cpu_backtrace_handler);
6162306a36Sopenharmony_ci#endif
62