From: Andrew Cooper Date: Mon, 11 Jan 2016 19:21:54 +0000 (+0000) Subject: Allow tests to provide their own custom unhandled exception handler X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=a13e9b4056d168cd441a8413402e4a156f9989f7;p=people%2Froyger%2Fxen-test-framework.git Allow tests to provide their own custom unhandled exception handler Useful for non-standard fixup, or for logging something more helpful than the plain panic() message. Signed-off-by: Andrew Cooper --- diff --git a/arch/x86/traps.c b/arch/x86/traps.c index 9557bde..8906e47 100644 --- a/arch/x86/traps.c +++ b/arch/x86/traps.c @@ -4,6 +4,8 @@ #include +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)); diff --git a/include/xtf/traps.h b/include/xtf/traps.h index 7f3ba30..3b261cb 100644 --- a/include/xtf/traps.h +++ b/include/xtf/traps.h @@ -5,6 +5,14 @@ #include +/** + * 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 */ /* diff --git a/tests/selftest/main.c b/tests/selftest/main.c index 83f7281..e33df9a 100644 --- a/tests/selftest/main.c +++ b/tests/selftest/main.c @@ -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(); }