1 #include "fault_test.h"
2
3 static jmp_buf jmpbuf;
4
restore_exec_to_jmpbuf(void)5 static void restore_exec_to_jmpbuf(void)
6 {
7 longjmp(jmpbuf, 1);
8 }
9
fault_test_fault(struct ex_regs * regs)10 static void fault_test_fault(struct ex_regs *regs)
11 {
12 regs->rip = (unsigned long)&restore_exec_to_jmpbuf;
13 }
14
fault_test(struct fault_test_arg * arg)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 handler old;
23
24 if (arg->usermode) {
25 val = run_in_user((usermode_func) func, arg->fault_vector,
26 arg->arg[0], arg->arg[1], arg->arg[2],
27 arg->arg[3], &raised_vector);
28 } else {
29 old = handle_exception(arg->fault_vector, fault_test_fault);
30 if (setjmp(jmpbuf) == 0)
31 val = func(arg->arg[0], arg->arg[1], arg->arg[2],
32 arg->arg[3]);
33 else
34 raised_vector = true;
35 handle_exception(arg->fault_vector, old);
36 }
37
38 if (!raised_vector) {
39 arg->retval = val;
40 if (arg->callback != NULL)
41 callback_success = arg->callback(arg);
42 }
43
44 return arg->should_fault ?
45 raised_vector : (!raised_vector && callback_success);
46 }
47
test_run(struct fault_test * test)48 void test_run(struct fault_test *test)
49 {
50 bool passed = fault_test(&(test->arg));
51
52 report(passed, "%s", test->name);
53 }
54
55