From: Andrew Cooper Date: Sat, 2 May 2015 10:52:29 +0000 (+0100) Subject: Introduce panic() and use it to cover some exceptional cases X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=aecf2aabc72a52923002f7880e3b9466f8e90b10;p=people%2Froyger%2Fxen-test-framework.git Introduce panic() and use it to cover some exceptional cases Signed-off-by: Andrew Cooper --- diff --git a/arch/x86/boot/head_pv.S b/arch/x86/boot/head_pv.S index 42c60d0..8ba502c 100644 --- a/arch/x86/boot/head_pv.S +++ b/arch/x86/boot/head_pv.S @@ -33,5 +33,17 @@ GLOBAL(_start) #endif call xtf_main - ud2 + + /* panic() if xtf_main manages to return. */ +#ifdef __x86_64__ + lea main_err_msg(%rip), %rdi +#else + push $main_err_msg +#endif + call panic SIZE(_start) + +.section .rodata.str1, "aMS", @progbits, 1 + +main_err_msg: .asciz "xtf_main() returned\n" +SIZE(main_err_msg) diff --git a/arch/x86/setup.c b/arch/x86/setup.c index a8f9138..faf2dc8 100644 --- a/arch/x86/setup.c +++ b/arch/x86/setup.c @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -10,6 +10,21 @@ start_info_t *start_info = NULL; #endif +/* + * PV guests should have hypercalls set up by the domain builder, due to the + * HYPERCALL_PAGE ELFNOTE being filled. + */ +static void init_hypercalls(void) +{ + /* + * Confirm that the `ret` poision has been overwritten with a real + * hypercall page. At the time of writing, a legitimate hypercall page + * should start with `movl $0, %eax` or `0xb8 imm32`. + */ + if ( hypercall_page[0] == 0xc3 ) + panic("Hypercall page not initialised correctly\n"); +} + static void setup_pv_console(void) { xencons_interface_t *cons_ring; @@ -32,6 +47,8 @@ void arch_setup(void) { register_console_callback(xen_console_write); + init_hypercalls(); + setup_pv_console(); } diff --git a/arch/x86/traps.c b/arch/x86/traps.c new file mode 100644 index 0000000..289368a --- /dev/null +++ b/arch/x86/traps.c @@ -0,0 +1,44 @@ +#include + + +/* + * Getting called means that a shutdown(crash) hypercall has not succeeded. + * Attempt more extreme measures to try and force a crash, and fall into an + * infinite loop if all else fails. + */ +void __noreturn arch_crash_hard(void) +{ +#if defined(CONFIG_ENV_pv32) + /* + * 32bit PV - put the stack in the Xen read-only M2P mappings and attempt + * to use it. + */ + asm volatile("mov %0, %%esp; pushf" + :: "i" (0xfbadc0deUL) : "memory"); + +#elif defined(CONFIG_ENV_pv64) + /* + * 64bit PV - put the stack in the middle of the non-canonical region, and + * attempt to use it. + */ + asm volatile("movabs %0, %%rsp; pushf" + :: "i" (0x800000000badc0deUL) : "memory"); + +#endif + + /* + * Attempt to crash failed. Give up and sit in a loop. + */ + asm volatile("1: hlt; rep; nop; jmp 1b" ::: "memory"); + unreachable(); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/common/console.c b/common/console.c index 34cb89d..d163864 100644 --- a/common/console.c +++ b/common/console.c @@ -22,6 +22,8 @@ void register_console_callback(cons_output_cb fn) { if ( nr_cons_cb < ARRAY_SIZE(output_fns) ) output_fns[nr_cons_cb++] = fn; + else + panic("Too many console callbacks\n"); } /* @@ -89,6 +91,9 @@ void vprintk(const char *fmt, va_list args) rc = vsnprintf(buf, sizeof(buf), fmt, args); + if ( rc > (int)sizeof(buf) ) + panic("vprintk() buffer overflow\n"); + for ( i = 0; i < nr_cons_cb; ++i ) output_fns[i](buf, rc); } diff --git a/common/lib.c b/common/lib.c new file mode 100644 index 0000000..f380f5d --- /dev/null +++ b/common/lib.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include + +void __noreturn panic(const char *fmt, ...) +{ + va_list args; + + printk("******************************\n"); + + printk("PANIC: "); + va_start(args, fmt); + vprintk(fmt, args); + va_end(args); + + printk("******************************\n"); + + hypercall_shutdown(SHUTDOWN_crash); + arch_crash_hard(); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/config/files.mk b/config/files.mk index 89575cd..0e4921f 100644 --- a/config/files.mk +++ b/config/files.mk @@ -5,11 +5,13 @@ # obj-$(env) are objects unique to a specific environment obj-perarch += $(ROOT)/common/console.o +obj-perarch += $(ROOT)/common/lib.o obj-perarch += $(ROOT)/common/libc/string.o obj-perarch += $(ROOT)/common/libc/vsnprintf.o obj-perarch += $(ROOT)/common/setup.o obj-perenv += $(ROOT)/arch/x86/setup.o +obj-perenv += $(ROOT)/arch/x86/traps.o # Always link hypercall_page.S last as it is a page of data replaced by the hyperisor obj-perenv += $(ROOT)/arch/x86/hypercall_page.o diff --git a/include/arch/x86/traps.h b/include/arch/x86/traps.h new file mode 100644 index 0000000..fc89d17 --- /dev/null +++ b/include/arch/x86/traps.h @@ -0,0 +1,18 @@ +#ifndef XTF_X86_TRAPS_H +#define XTF_X86_TRAPS_H + +#include + +void __noreturn arch_crash_hard(void); + +#endif /* XTF_X86_TRAPS_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/xtf/hypercall.h b/include/xtf/hypercall.h index 0de3ebf..6aa8b68 100644 --- a/include/xtf/hypercall.h +++ b/include/xtf/hypercall.h @@ -2,6 +2,7 @@ #define XTF_HYPERCALL_H #include +#include #if defined(__x86_64__) @@ -19,6 +20,8 @@ # error Bad architecture for hypercalls #endif +extern uint8_t hypercall_page[PAGE_SIZE]; + /* All Xen ABI for includers convenience .*/ #include #include diff --git a/include/xtf/lib.h b/include/xtf/lib.h index 512e954..232f010 100644 --- a/include/xtf/lib.h +++ b/include/xtf/lib.h @@ -2,11 +2,14 @@ #define XTF_LIB_H #include +#include #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a)) #define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x)) +void __noreturn panic(const char *fmt, ...) __printf(1, 2); + #endif /* XTF_LIB_H */ /* diff --git a/include/xtf/traps.h b/include/xtf/traps.h new file mode 100644 index 0000000..38108b8 --- /dev/null +++ b/include/xtf/traps.h @@ -0,0 +1,16 @@ +#ifndef XTF_TRAPS_H +#define XTF_TRAPS_H + +#include + +#endif /* XTF_TRAPS_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */