]> xenbits.xensource.com Git - people/royger/xen-test-framework.git/commitdiff
Allow tests to provide their own custom unhandled exception handler
authorAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 11 Jan 2016 19:21:54 +0000 (19:21 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 12 Jan 2016 18:12:25 +0000 (18:12 +0000)
Useful for non-standard fixup, or for logging something more helpful than the
plain panic() message.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
arch/x86/traps.c
include/xtf/traps.h
tests/selftest/main.c

index 9557bdee574f348fa43138efe6dd744ef4c271d9..8906e4729729329a15c72daca8c9b412d797f4e4 100644 (file)
@@ -4,6 +4,8 @@
 
 #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
@@ -69,6 +71,13 @@ void do_exception(struct cpu_regs *regs)
         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));
index 7f3ba30830643afc19692c027006a807255e7c19..3b261cb3a5cc141ba409dad98bde2edff1531c3c 100644 (file)
@@ -5,6 +5,14 @@
 
 #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 */
 
 /*
index 83f7281b8ea1c058c71263369250eb2fbe632b05..e33df9a0a5f5aa45df94d2f4e3f1ba606912756c 100644 (file)
@@ -184,6 +184,33 @@ static void test_NULL_unmapped(void)
     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");
@@ -193,6 +220,7 @@ void test_main(void)
     test_exlog();
     test_exec_user();
     test_NULL_unmapped();
+    test_unhandled_exception_hook();
 
     xtf_success();
 }