xref: /kvm-unit-tests/riscv/selftest.c (revision 48d5952451de62a4db23cf73024f702cf1a64fc3)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Test the framework itself. These tests confirm that setup works.
4  *
5  * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
6  */
7 #include <libcflat.h>
8 #include <cpumask.h>
9 #include <on-cpus.h>
10 #include <asm/processor.h>
11 #include <asm/setup.h>
12 #include <asm/smp.h>
13 
check_cpus(void)14 static void check_cpus(void)
15 {
16 	int cpu;
17 
18 	for_each_present_cpu(cpu)
19 		report_info("CPU%3d: hartid=%08lx", cpu, cpus[cpu].hartid);
20 }
21 
22 static bool exceptions_work;
23 
handler(struct pt_regs * regs)24 static void handler(struct pt_regs *regs)
25 {
26 	exceptions_work = true;
27 	regs->epc += 2;
28 }
29 
check_exceptions(void)30 static void check_exceptions(void)
31 {
32 	install_exception_handler(EXC_INST_ILLEGAL, handler);
33 	asm volatile(".4byte 0");
34 	install_exception_handler(EXC_INST_ILLEGAL, NULL);
35 	report(exceptions_work, "exceptions");
36 }
37 
38 static cpumask_t cpus_alive;
39 
check_secondary(void * data)40 static void check_secondary(void *data)
41 {
42 	cpumask_set_cpu(smp_processor_id(), &cpus_alive);
43 }
44 
check_smp(void)45 static void check_smp(void)
46 {
47 	int cpu, me = smp_processor_id();
48 	bool fail = false;
49 
50 	on_cpus(check_secondary, NULL);
51 
52 	report(cpumask_full(&cpu_online_mask), "Brought up all cpus");
53 	report(cpumask_full(&cpus_alive), "check_secondary");
54 
55 	for_each_present_cpu(cpu) {
56 		if (cpu == me)
57 			continue;
58 		if (!cpu_idle(cpu)) {
59 			fail = true;
60 			break;
61 		}
62 	}
63 	report(!fail, "All secondaries are idle");
64 }
65 
main(int argc,char ** argv)66 int main(int argc, char **argv)
67 {
68 	bool r;
69 
70 	report_prefix_push("selftest");
71 
72 	report(!strncmp(argv[0], "selftest", 8), "program name");
73 
74 	if (argc > 1) {
75 		r = !strcmp(argv[1], "foo");
76 		if (argc > 2)
77 			r &= !strcmp(argv[2], "bar");
78 		if (argc > 3)
79 			r &= !strcmp(argv[3], "baz");
80 		report_info("matched %d command line parameters", argc - 1);
81 		report(r, "command line parsing");
82 	} else {
83 		report_skip("command line parsing");
84 	}
85 
86 	if (getenv("FOO")) {
87 		r = !strcmp(getenv("FOO"), "foo");
88 		r &= !strcmp(getenv("BAR"), "bar");
89 		r &= !strcmp(getenv("BAZ"), "baz");
90 		report(r, "environ parsing");
91 	} else {
92 		report_skip("environ parsing");
93 	}
94 
95 	check_exceptions();
96 	check_cpus();
97 	check_smp();
98 
99 	return report_summary();
100 }
101