new file mode 100644
@@ -0,0 +1,52 @@
+#include "fault_test.h"
+
+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)
+{
+ 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;
+
+ 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 {
+ 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;
+ }
+
+ 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("%s", passed, test->name);
+}
+
new file mode 100644
@@ -0,0 +1,42 @@
+#ifndef __FAULT_TEST__
+#define __FAULT_TEST__
+
+#include "x86/msr.h"
+#include "x86/processor.h"
+#include "x86/apic-defs.h"
+#include "x86/apic.h"
+#include "x86/desc.h"
+#include "x86/isr.h"
+#include "alloc.h"
+#include "setjmp.h"
+#include "usermode.h"
+
+#include "libcflat.h"
+#include <stdint.h>
+
+#define FAULT_TEST(nm, a) { .name = nm, .arg = a}
+
+struct fault_test_arg;
+
+typedef uint64_t (*test_fault_func)(uint64_t arg1, uint64_t arg2,
+ uint64_t arg3, uint64_t arg4);
+typedef bool (*test_fault_callback)(struct fault_test_arg *arg);
+
+struct fault_test_arg {
+ bool usermode;
+ unsigned int fault_vector;
+ bool should_fault;
+ uint64_t arg[4];
+ uint64_t retval;
+ test_fault_func func;
+ test_fault_callback callback;
+};
+
+struct fault_test {
+ const char *name;
+ struct fault_test_arg arg;
+};
+
+void test_run(struct fault_test *test);
+
+#endif
@@ -20,6 +20,7 @@ cflatobjs += lib/x86/isr.o
cflatobjs += lib/x86/acpi.o
cflatobjs += lib/x86/stack.o
cflatobjs += lib/x86/usermode.o
+cflatobjs += lib/x86/fault_test.o
OBJDIRS += lib/x86