0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/smp.h>
0014 #include <linux/cpumask.h>
0015 #include <linux/delay.h>
0016 #include <linux/init.h>
0017 #include <linux/percpu.h>
0018
0019 #include <asm/apic.h>
0020 #include <asm/nmi.h>
0021
0022 #define SUCCESS 0
0023 #define FAILURE 1
0024 #define TIMEOUT 2
0025
0026 static int __initdata nmi_fail;
0027
0028
0029 static DECLARE_BITMAP(nmi_ipi_mask, NR_CPUS) __initdata;
0030
0031 static int __initdata testcase_total;
0032 static int __initdata testcase_successes;
0033 static int __initdata expected_testcase_failures;
0034 static int __initdata unexpected_testcase_failures;
0035 static int __initdata unexpected_testcase_unknowns;
0036
0037 static int __init nmi_unk_cb(unsigned int val, struct pt_regs *regs)
0038 {
0039 unexpected_testcase_unknowns++;
0040 return NMI_HANDLED;
0041 }
0042
0043 static void __init init_nmi_testsuite(void)
0044 {
0045
0046 register_nmi_handler(NMI_UNKNOWN, nmi_unk_cb, 0, "nmi_selftest_unk",
0047 __initdata);
0048 }
0049
0050 static void __init cleanup_nmi_testsuite(void)
0051 {
0052 unregister_nmi_handler(NMI_UNKNOWN, "nmi_selftest_unk");
0053 }
0054
0055 static int __init test_nmi_ipi_callback(unsigned int val, struct pt_regs *regs)
0056 {
0057 int cpu = raw_smp_processor_id();
0058
0059 if (cpumask_test_and_clear_cpu(cpu, to_cpumask(nmi_ipi_mask)))
0060 return NMI_HANDLED;
0061
0062 return NMI_DONE;
0063 }
0064
0065 static void __init test_nmi_ipi(struct cpumask *mask)
0066 {
0067 unsigned long timeout;
0068
0069 if (register_nmi_handler(NMI_LOCAL, test_nmi_ipi_callback,
0070 NMI_FLAG_FIRST, "nmi_selftest", __initdata)) {
0071 nmi_fail = FAILURE;
0072 return;
0073 }
0074
0075
0076 wmb();
0077
0078 apic->send_IPI_mask(mask, NMI_VECTOR);
0079
0080
0081 timeout = USEC_PER_SEC;
0082 while (!cpumask_empty(mask) && --timeout)
0083 udelay(1);
0084
0085
0086 unregister_nmi_handler(NMI_LOCAL, "nmi_selftest");
0087
0088 if (!timeout)
0089 nmi_fail = TIMEOUT;
0090 return;
0091 }
0092
0093 static void __init remote_ipi(void)
0094 {
0095 cpumask_copy(to_cpumask(nmi_ipi_mask), cpu_online_mask);
0096 cpumask_clear_cpu(smp_processor_id(), to_cpumask(nmi_ipi_mask));
0097 if (!cpumask_empty(to_cpumask(nmi_ipi_mask)))
0098 test_nmi_ipi(to_cpumask(nmi_ipi_mask));
0099 }
0100
0101 static void __init local_ipi(void)
0102 {
0103 cpumask_clear(to_cpumask(nmi_ipi_mask));
0104 cpumask_set_cpu(smp_processor_id(), to_cpumask(nmi_ipi_mask));
0105 test_nmi_ipi(to_cpumask(nmi_ipi_mask));
0106 }
0107
0108 static void __init reset_nmi(void)
0109 {
0110 nmi_fail = 0;
0111 }
0112
0113 static void __init dotest(void (*testcase_fn)(void), int expected)
0114 {
0115 testcase_fn();
0116
0117
0118
0119 if (nmi_fail != expected) {
0120 unexpected_testcase_failures++;
0121
0122 if (nmi_fail == FAILURE)
0123 printk(KERN_CONT "FAILED |");
0124 else if (nmi_fail == TIMEOUT)
0125 printk(KERN_CONT "TIMEOUT|");
0126 else
0127 printk(KERN_CONT "ERROR |");
0128 dump_stack();
0129 } else {
0130 testcase_successes++;
0131 printk(KERN_CONT " ok |");
0132 }
0133 testcase_total++;
0134
0135 reset_nmi();
0136 }
0137
0138 static inline void __init print_testname(const char *testname)
0139 {
0140 printk("%12s:", testname);
0141 }
0142
0143 void __init nmi_selftest(void)
0144 {
0145 init_nmi_testsuite();
0146
0147
0148
0149
0150 printk("----------------\n");
0151 printk("| NMI testsuite:\n");
0152 printk("--------------------\n");
0153
0154 print_testname("remote IPI");
0155 dotest(remote_ipi, SUCCESS);
0156 printk(KERN_CONT "\n");
0157 print_testname("local IPI");
0158 dotest(local_ipi, SUCCESS);
0159 printk(KERN_CONT "\n");
0160
0161 cleanup_nmi_testsuite();
0162
0163 if (unexpected_testcase_failures) {
0164 printk("--------------------\n");
0165 printk("BUG: %3d unexpected failures (out of %3d) - debugging disabled! |\n",
0166 unexpected_testcase_failures, testcase_total);
0167 printk("-----------------------------------------------------------------\n");
0168 } else if (expected_testcase_failures && testcase_successes) {
0169 printk("--------------------\n");
0170 printk("%3d out of %3d testcases failed, as expected. |\n",
0171 expected_testcase_failures, testcase_total);
0172 printk("----------------------------------------------------\n");
0173 } else if (expected_testcase_failures && !testcase_successes) {
0174 printk("--------------------\n");
0175 printk("All %3d testcases failed, as expected. |\n",
0176 expected_testcase_failures);
0177 printk("----------------------------------------\n");
0178 } else {
0179 printk("--------------------\n");
0180 printk("Good, all %3d testcases passed! |\n",
0181 testcase_successes);
0182 printk("---------------------------------\n");
0183 }
0184 }