blob: 614bdcb425354c0c4a303ae9694d608b2bbbc9e9 [file] [log] [blame]
#include "fault_test.h"
static jmp_buf jmpbuf;
static void restore_exec_to_jmpbuf(void)
{
longjmp(jmpbuf, 1);
}
static void fault_test_fault(struct ex_regs *regs)
{
regs->rip = (unsigned long)&restore_exec_to_jmpbuf;
}
static bool fault_test(struct fault_test_arg *arg)
{
volatile uint64_t val;
bool raised_vector = false;
test_fault_func func = (test_fault_func) arg->func;
/* Init as success in case there isn't callback */
bool callback_success = true;
handler old;
if (arg->usermode) {
val = run_in_user((usermode_func) func, arg->fault_vector,
arg->arg[0], arg->arg[1], arg->arg[2],
arg->arg[3], &raised_vector);
} else {
old = handle_exception(arg->fault_vector, fault_test_fault);
if (setjmp(jmpbuf) == 0)
val = func(arg->arg[0], arg->arg[1], arg->arg[2],
arg->arg[3]);
else
raised_vector = true;
handle_exception(arg->fault_vector, old);
}
if (!raised_vector) {
arg->retval = val;
if (arg->callback != NULL)
callback_success = arg->callback(arg);
}
return arg->should_fault ?
raised_vector : (!raised_vector && callback_success);
}
void test_run(struct fault_test *test)
{
bool passed = fault_test(&(test->arg));
report(passed, "%s", test->name);
}