/*
 * 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 <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");
}

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")) {
		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("FAILED |");
		else if (nmi_fail == TIMEOUT)
			printk("TIMEOUT|");
		else
			printk("ERROR  |");
		dump_stack();
	} else {
		testcase_successes++;
		printk("  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("\n");
	print_testname("local IPI");
	dotest(local_ipi, SUCCESS);
	printk("\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");
	}
}
