xref: /kvm-unit-tests/lib/x86/fault_test.c (revision ebc1b903f12dab0921c055712131a54b7e37eea1)
1 #include "fault_test.h"
2 
3 jmp_buf jmpbuf;
4 
5 static void restore_exec_to_jmpbuf(void)
6 {
7 	longjmp(jmpbuf, 1);
8 }
9 
10 static void fault_test_fault(struct ex_regs *regs)
11 {
12 	regs->rip = (unsigned long)&restore_exec_to_jmpbuf;
13 }
14 
15 static bool fault_test(struct fault_test_arg *arg)
16 {
17 	volatile uint64_t val;
18 	bool raised_vector = false;
19 	test_fault_func func = (test_fault_func) arg->func;
20 	/* Init as success in case there isn't callback */
21 	bool callback_success = true;
22 
23 	if (arg->usermode) {
24 		val = run_in_user((usermode_func) func, arg->fault_vector,
25 				arg->arg[0], arg->arg[1], arg->arg[2],
26 				arg->arg[3], &raised_vector);
27 	} else {
28 		handle_exception(arg->fault_vector, fault_test_fault);
29 		if (setjmp(jmpbuf) == 0)
30 			val = func(arg->arg[0], arg->arg[1], arg->arg[2],
31 					arg->arg[3]);
32 		else
33 			raised_vector = true;
34 	}
35 
36 	if (!raised_vector) {
37 		arg->retval = val;
38 		if (arg->callback != NULL)
39 			callback_success = arg->callback(arg);
40 	}
41 
42 	return arg->should_fault ?
43 		raised_vector : (!raised_vector && callback_success);
44 }
45 
46 void test_run(struct fault_test *test)
47 {
48 	bool passed = fault_test(&(test->arg));
49 
50 	report("%s", passed, test->name);
51 }
52 
53