// SPDX-License-Identifier: GPL-2.0
/*
 * arch/x86/kernel/nmi-selftest.c
 *
 * Testsuite for NMI: IPIs
 *
 * Started by Don Zickus:
 * (using lib/locking-selftest.c as a guide)
 *
 *   Copyright (C) 2011 Red Hat, Inc., Don Zickus <dzickus@redhat.com>
 */

#include <linux/smp.h>
#include <linux/cpumask.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/percpu.h>

#include <asm/apic.h>
#include <asm/nmi.h>

#define SUCCESS		0
#define FAILURE		1
#define TIMEOUT		2

static int __initdata nmi_fail;

/* check to see if NMI IPIs work on this machine */
static DECLARE_BITMAP(nmi_ipi_mask, NR_CPUS) __initdata;

static int __initdata testcase_total;
static int __initdata testcase_successes;
static int __initdata expected_testcase_failures;
static int __initdata unexpected_testcase_failures;
static int __initdata unexpected_testcase_unknowns;

static int __init nmi_unk_cb(unsigned int val, struct pt_regs *regs)
{
	unexpected_testcase_unknowns++;
	return NMI_HANDLED;
}

static void __init init_nmi_testsuite(void)
{
	/* trap all the unknown NMIs we may generate */
	register_nmi_handler(NMI_UNKNOWN, nmi_unk_cb, 0, "nmi_selftest_unk",
			__initdata);
}

static void __init cleanup_nmi_testsuite(void)
{
	unregister_nmi_handler(NMI_UNKNOWN, "nmi_selftest_unk");
}

static int __init test_nmi_ipi_callback(unsigned int val, struct pt_regs *regs)
{
        int cpu = raw_smp_processor_id();

        if (cpumask_test_and_clear_cpu(cpu, to_cpumask(nmi_ipi_mask)))
                return NMI_HANDLED;

        return NMI_DONE;
}

static void __init test_nmi_ipi(struct cpumask *mask)
{
	unsigned long timeout;

	if (register_nmi_handler(NMI_LOCAL, test_nmi_ipi_callback,
				 NMI_FLAG_FIRST, "nmi_selftest", __initdata)) {
		nmi_fail = FAILURE;
		return;
	}

	/* sync above data before sending NMI */
	wmb();

	__apic_send_IPI_mask(mask, NMI_VECTOR);

	/* Don't wait longer than a second */
	timeout = USEC_PER_SEC;
	while (!cpumask_empty(mask) && --timeout)
	        udelay(1);

	/* What happens if we timeout, do we still unregister?? */
	unregister_nmi_handler(NMI_LOCAL, "nmi_selftest");

	if (!timeout)
		nmi_fail = TIMEOUT;
	return;
}

static void __init remote_ipi(void)
{
	cpumask_copy(to_cpumask(nmi_ipi_mask), cpu_online_mask);
	cpumask_clear_cpu(smp_processor_id(), to_cpumask(nmi_ipi_mask));
	if (!cpumask_empty(to_cpumask(nmi_ipi_mask)))
		test_nmi_ipi(to_cpumask(nmi_ipi_mask));
}

static void __init local_ipi(void)
{
	cpumask_clear(to_cpumask(nmi_ipi_mask));
	cpumask_set_cpu(smp_processor_id(), to_cpumask(nmi_ipi_mask));
	test_nmi_ipi(to_cpumask(nmi_ipi_mask));
}

static void __init reset_nmi(void)
{
	nmi_fail = 0;
}

static void __init dotest(void (*testcase_fn)(void), int expected)
{
	testcase_fn();
	/*
	 * Filter out expected failures:
	 */
	if (nmi_fail != expected) {
		unexpected_testcase_failures++;

		if (nmi_fail == FAILURE)
			printk(KERN_CONT "FAILED |");
		else if (nmi_fail == TIMEOUT)
			printk(KERN_CONT "TIMEOUT|");
		else
			printk(KERN_CONT "ERROR  |");
		dump_stack();
	} else {
		testcase_successes++;
		printk(KERN_CONT "  ok  |");
	}
	testcase_total++;

	reset_nmi();
}

static inline void __init print_testname(const char *testname)
{
	printk("%12s:", testname);
}

void __init nmi_selftest(void)
{
	init_nmi_testsuite();

        /*
	 * Run the testsuite:
	 */
	printk("----------------\n");
	printk("| NMI testsuite:\n");
	printk("--------------------\n");

	print_testname("remote IPI");
	dotest(remote_ipi, SUCCESS);
	printk(KERN_CONT "\n");
	print_testname("local IPI");
	dotest(local_ipi, SUCCESS);
	printk(KERN_CONT "\n");

	cleanup_nmi_testsuite();

	if (unexpected_testcase_failures) {
		printk("--------------------\n");
		printk("BUG: %3d unexpected failures (out of %3d) - debugging disabled! |\n",
			unexpected_testcase_failures, testcase_total);
		printk("-----------------------------------------------------------------\n");
	} else if (expected_testcase_failures && testcase_successes) {
		printk("--------------------\n");
		printk("%3d out of %3d testcases failed, as expected. |\n",
			expected_testcase_failures, testcase_total);
		printk("----------------------------------------------------\n");
	} else if (expected_testcase_failures && !testcase_successes) {
		printk("--------------------\n");
		printk("All %3d testcases failed, as expected. |\n",
			expected_testcase_failures);
		printk("----------------------------------------\n");
	} else {
		printk("--------------------\n");
		printk("Good, all %3d testcases passed! |\n",
			testcase_successes);
		printk("---------------------------------\n");
	}
}
