Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * arch/x86/kernel/nmi-selftest.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Testsuite for NMI: IPIs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Started by Don Zickus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * (using lib/locking-selftest.c as a guide)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *   Copyright (C) 2011 Red Hat, Inc., Don Zickus <dzickus@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/cpumask.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/percpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <asm/apic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <asm/nmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define SUCCESS		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define FAILURE		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define TIMEOUT		2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) static int __initdata nmi_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) /* check to see if NMI IPIs work on this machine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) static DECLARE_BITMAP(nmi_ipi_mask, NR_CPUS) __initdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) static int __initdata testcase_total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) static int __initdata testcase_successes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) static int __initdata expected_testcase_failures;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) static int __initdata unexpected_testcase_failures;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) static int __initdata unexpected_testcase_unknowns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) static int __init nmi_unk_cb(unsigned int val, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	unexpected_testcase_unknowns++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	return NMI_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) static void __init init_nmi_testsuite(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	/* trap all the unknown NMIs we may generate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	register_nmi_handler(NMI_UNKNOWN, nmi_unk_cb, 0, "nmi_selftest_unk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 			__initdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) static void __init cleanup_nmi_testsuite(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	unregister_nmi_handler(NMI_UNKNOWN, "nmi_selftest_unk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) static int __init test_nmi_ipi_callback(unsigned int val, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)         int cpu = raw_smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)         if (cpumask_test_and_clear_cpu(cpu, to_cpumask(nmi_ipi_mask)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)                 return NMI_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)         return NMI_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) static void __init test_nmi_ipi(struct cpumask *mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	if (register_nmi_handler(NMI_LOCAL, test_nmi_ipi_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 				 NMI_FLAG_FIRST, "nmi_selftest", __initdata)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		nmi_fail = FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	/* sync above data before sending NMI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	apic->send_IPI_mask(mask, NMI_VECTOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	/* Don't wait longer than a second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	timeout = USEC_PER_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	while (!cpumask_empty(mask) && --timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	        udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	/* What happens if we timeout, do we still unregister?? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	unregister_nmi_handler(NMI_LOCAL, "nmi_selftest");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	if (!timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		nmi_fail = TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) static void __init remote_ipi(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	cpumask_copy(to_cpumask(nmi_ipi_mask), cpu_online_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	cpumask_clear_cpu(smp_processor_id(), to_cpumask(nmi_ipi_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	if (!cpumask_empty(to_cpumask(nmi_ipi_mask)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		test_nmi_ipi(to_cpumask(nmi_ipi_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static void __init local_ipi(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	cpumask_clear(to_cpumask(nmi_ipi_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	cpumask_set_cpu(smp_processor_id(), to_cpumask(nmi_ipi_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	test_nmi_ipi(to_cpumask(nmi_ipi_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static void __init reset_nmi(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	nmi_fail = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static void __init dotest(void (*testcase_fn)(void), int expected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	testcase_fn();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	 * Filter out expected failures:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	if (nmi_fail != expected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		unexpected_testcase_failures++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		if (nmi_fail == FAILURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			printk(KERN_CONT "FAILED |");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		else if (nmi_fail == TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 			printk(KERN_CONT "TIMEOUT|");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 			printk(KERN_CONT "ERROR  |");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		dump_stack();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		testcase_successes++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		printk(KERN_CONT "  ok  |");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	testcase_total++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	reset_nmi();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static inline void __init print_testname(const char *testname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	printk("%12s:", testname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) void __init nmi_selftest(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	init_nmi_testsuite();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)         /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	 * Run the testsuite:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	printk("----------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	printk("| NMI testsuite:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	printk("--------------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	print_testname("remote IPI");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	dotest(remote_ipi, SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	printk(KERN_CONT "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	print_testname("local IPI");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	dotest(local_ipi, SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	printk(KERN_CONT "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	cleanup_nmi_testsuite();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	if (unexpected_testcase_failures) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		printk("--------------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		printk("BUG: %3d unexpected failures (out of %3d) - debugging disabled! |\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			unexpected_testcase_failures, testcase_total);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		printk("-----------------------------------------------------------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	} else if (expected_testcase_failures && testcase_successes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		printk("--------------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		printk("%3d out of %3d testcases failed, as expected. |\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			expected_testcase_failures, testcase_total);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		printk("----------------------------------------------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	} else if (expected_testcase_failures && !testcase_successes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		printk("--------------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		printk("All %3d testcases failed, as expected. |\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 			expected_testcase_failures);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		printk("----------------------------------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		printk("--------------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		printk("Good, all %3d testcases passed! |\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 			testcase_successes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		printk("---------------------------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }