• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Verify MCA grading engine against some examples.
3  */
4 #include <sys/types.h>
5 #include <stdio.h>
6 #define __KERNEL__ 1
7 #include <asm/types.h>
8 #include <asm/mce.h>
9 #include <errno.h>
10 
11 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(*(x)))
12 
13 typedef unsigned long long u64;
14 
15 #define MCI_STATUS_S	 (1ULL<<56)  /* Signaled machine check */
16 #define MCI_STATUS_AR	 (1ULL<<55)  /* Action required */
17 
18 int mce_ser = 1;
19 int tolerant = 1;
20 int panic_on_oops = 0;
21 
22 #include "mce-severity.c"
23 
24 char *resname[] = {
25 #define R(x) [MCE_ ## x ## _SEVERITY] = #x
26 	R(NO),
27 	R(KEEP),
28 	R(SOME),
29 	R(AO),
30 	R(AR),
31 	R(PANIC),
32 };
33 #define VAL MCI_STATUS_VAL
34 #define EN MCI_STATUS_EN
35 #define PCC MCI_STATUS_PCC
36 #define S MCI_STATUS_S
37 #define AR MCI_STATUS_AR
38 #define UC MCI_STATUS_UC
39 
40 int ring = 3;
41 int fail;
42 
test2(u64 flag,char * flagname,u64 mcg,char * mcgname,int result)43 void test2(u64 flag, char *flagname, u64 mcg, char *mcgname, int result)
44 {
45 	struct mce m = {
46 		.ip = 1,
47 		.cs = ring,
48 		.status = flag,
49 		.mcgstatus = mcg,
50 	};
51 	int r;
52 	char *msg;
53 
54 	if ((r = mce_severity(&m, tolerant, &msg)) != result) {
55 		printf("%s %s expected %s got %s msg %s\n",
56 		       flagname, mcgname, resname[result], resname[r], msg);
57 		fail++;
58 	}
59 }
60 
61 
62 #define TEST(flag, result) \
63 	test2(flag, #flag, MCG_STATUS_MCIP|MCG_STATUS_RIPV, "mcip,ripv", \
64 		MCE_ ## result ## _SEVERITY)
65 
test(void)66 void test(void)
67 {
68 	// corrected
69 	TEST(VAL|EN, KEEP);
70 
71 	// uncorrected fatal
72 	TEST(VAL|UC|PCC|EN|S|AR, PANIC);
73 	TEST(VAL|UC|PCC|EN|S, PANIC);
74 	TEST(VAL|UC|PCC|EN, PANIC);
75 
76 	// SW recoverable action required
77 	// unknown mcacod -> panic
78 	TEST(VAL|UC|EN|S|AR, PANIC);
79 
80 	// SW recoverable action optional
81 	TEST(VAL|UC|EN|S|0xc0, AO);
82 	// unknown mcacod
83 	TEST(VAL|UC|EN|S|1, SOME);
84 
85 	// UCNA
86 	TEST(VAL|UC|EN, KEEP);
87 	TEST(VAL|UC, NO);	// linux clears. correct?
88 }
89 
main(void)90 int main(void)
91 {
92 	ring = 3;
93 	test();
94 	ring = 0;
95 	test();
96 	if (fail == 0)
97 		printf("SUCCESS\n");
98 	else
99 		printf("%d FAILURES\n", fail);
100 	return fail;
101 }
102