#include <arch/x86/processor.h>
+bool (*xtf_unhandled_exception_hook)(struct cpu_regs *regs);
+
/*
* Evaluate whether this exception is a trap or an interrupt. i.e. whether it
* save to just return at the current %eip, or whether further action is
safe = true;
}
+ /*
+ * If the test has installed an unhandled exception hook, call it in the
+ * hope that it can resolve the exception.
+ */
+ if ( !safe && xtf_unhandled_exception_hook )
+ safe = xtf_unhandled_exception_hook(regs);
+
if ( !safe )
panic("Unhandled exception: vec %u at %04x:%p\n",
regs->entry_vector, regs->cs, _p(regs->ip));
#include <arch/x86/traps.h>
+/**
+ * Function pointer to allow tests to install an unhandled exception hook.
+ *
+ * Must only return true if action has been taken resolve the exception.
+ * i.e. that it is now safe to iret back. If not, a panic() will occur.
+ */
+extern bool (*xtf_unhandled_exception_hook)(struct cpu_regs *regs);
+
#endif /* XTF_TRAPS_H */
/*
xtf_exlog_stop();
}
+static bool local_unhandled_exception_hook(struct cpu_regs *regs)
+{
+ extern unsigned long hook_fault[], hook_fixup[];
+
+ if ( _p(regs->ip) != hook_fault )
+ {
+ xtf_failure("Fail: Expected fault at %p, got %p\n",
+ hook_fault, _p(regs->ip));
+ return false;
+ }
+
+ regs->ip = (unsigned long)hook_fixup;
+ return true;
+}
+
+static void test_unhandled_exception_hook(void)
+{
+ printk("Test: Unhandled Exception Hook\n");
+
+ /* Check that the hook catches the exception, and fix it up. */
+ xtf_unhandled_exception_hook = local_unhandled_exception_hook;
+
+ asm volatile ("hook_fault: ud2a; hook_fixup:" ::: "memory");
+
+ xtf_unhandled_exception_hook = NULL;
+}
+
void test_main(void)
{
printk("XTF Selftests\n");
test_exlog();
test_exec_user();
test_NULL_unmapped();
+ test_unhandled_exception_hook();
xtf_success();
}