Release 4.14 arch/x86/kernel/nmi_selftest.c
// 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;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Don Zickus | 21 | 95.45% | 1 | 50.00% |
Jan Beulich | 1 | 4.55% | 1 | 50.00% |
Total | 22 | 100.00% | 2 | 100.00% |
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);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Don Zickus | 19 | 82.61% | 1 | 33.33% |
Li Zhong | 3 | 13.04% | 1 | 33.33% |
Jan Beulich | 1 | 4.35% | 1 | 33.33% |
Total | 23 | 100.00% | 3 | 100.00% |
static void __init cleanup_nmi_testsuite(void)
{
unregister_nmi_handler(NMI_UNKNOWN, "nmi_selftest_unk");
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Don Zickus | 15 | 93.75% | 1 | 50.00% |
Jan Beulich | 1 | 6.25% | 1 | 50.00% |
Total | 16 | 100.00% | 2 | 100.00% |
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;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Don Zickus | 39 | 97.50% | 1 | 50.00% |
Jan Beulich | 1 | 2.50% | 1 | 50.00% |
Total | 40 | 100.00% | 2 | 100.00% |
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;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Don Zickus | 85 | 94.44% | 1 | 25.00% |
Li Zhong | 3 | 3.33% | 1 | 25.00% |
Jan Beulich | 1 | 1.11% | 1 | 25.00% |
Dan Carpenter | 1 | 1.11% | 1 | 25.00% |
Total | 90 | 100.00% | 4 | 100.00% |
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));
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Don Zickus | 45 | 91.84% | 2 | 50.00% |
Dan Carpenter | 3 | 6.12% | 1 | 25.00% |
Jan Beulich | 1 | 2.04% | 1 | 25.00% |
Total | 49 | 100.00% | 4 | 100.00% |
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));
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Don Zickus | 35 | 97.22% | 1 | 50.00% |
Jan Beulich | 1 | 2.78% | 1 | 50.00% |
Total | 36 | 100.00% | 2 | 100.00% |
static void __init reset_nmi(void)
{
nmi_fail = 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Don Zickus | 12 | 92.31% | 1 | 50.00% |
Jan Beulich | 1 | 7.69% | 1 | 50.00% |
Total | 13 | 100.00% | 2 | 100.00% |
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();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Don Zickus | 82 | 94.25% | 1 | 33.33% |
Sasha Levin | 4 | 4.60% | 1 | 33.33% |
Jan Beulich | 1 | 1.15% | 1 | 33.33% |
Total | 87 | 100.00% | 3 | 100.00% |
static inline void __init print_testname(const char *testname)
{
printk("%12s:", testname);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Don Zickus | 19 | 95.00% | 1 | 50.00% |
Jan Beulich | 1 | 5.00% | 1 | 50.00% |
Total | 20 | 100.00% | 2 | 100.00% |
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");
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Don Zickus | 163 | 98.19% | 1 | 33.33% |
Sasha Levin | 2 | 1.20% | 1 | 33.33% |
Jan Beulich | 1 | 0.60% | 1 | 33.33% |
Total | 166 | 100.00% | 3 | 100.00% |
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Don Zickus | 596 | 93.56% | 2 | 22.22% |
Jan Beulich | 21 | 3.30% | 1 | 11.11% |
Li Zhong | 6 | 0.94% | 1 | 11.11% |
Sasha Levin | 6 | 0.94% | 1 | 11.11% |
Dan Carpenter | 4 | 0.63% | 2 | 22.22% |
Alex Shi | 3 | 0.47% | 1 | 11.11% |
Greg Kroah-Hartman | 1 | 0.16% | 1 | 11.11% |
Total | 637 | 100.00% | 9 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.