]> xenbits.xensource.com Git - people/royger/xen-test-framework.git/commitdiff
Introduce panic() and use it to cover some exceptional cases
authorAndrew Cooper <andrew.cooper3@citrix.com>
Sat, 2 May 2015 10:52:29 +0000 (11:52 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 28 Sep 2015 13:54:42 +0000 (14:54 +0100)
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
arch/x86/boot/head_pv.S
arch/x86/setup.c
arch/x86/traps.c [new file with mode: 0644]
common/console.c
common/lib.c [new file with mode: 0644]
config/files.mk
include/arch/x86/traps.h [new file with mode: 0644]
include/xtf/hypercall.h
include/xtf/lib.h
include/xtf/traps.h [new file with mode: 0644]

index 42c60d049af5317a3f628e830a0780a16e187f8d..8ba502c6c9b897be9b223a78300df9154e840b90 100644 (file)
@@ -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)
index a8f9138c2ab9c3d6becbc707f6815df3d14a01cb..faf2dc8d15c7f8347808daa21d4376316b66f72d 100644 (file)
@@ -1,4 +1,4 @@
-#include <xtf/types.h>
+#include <xtf/lib.h>
 #include <xtf/console.h>
 #include <xtf/hypercall.h>
 
 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 (file)
index 0000000..289368a
--- /dev/null
@@ -0,0 +1,44 @@
+#include <xtf/traps.h>
+
+
+/*
+ * 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:
+ */
index 34cb89d77255ec38607c27543049913dbc4a4acc..d163864d4cec61a444fdf6deb234f5f38b844176 100644 (file)
@@ -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 (file)
index 0000000..f380f5d
--- /dev/null
@@ -0,0 +1,31 @@
+#include <xtf/lib.h>
+#include <xtf/traps.h>
+#include <xtf/console.h>
+#include <xtf/hypercall.h>
+
+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:
+ */
index 89575cd4523e2c98fead1a64ec8dbc86c69df6fb..0e4921ff64c2b7bed1a490f1d358689931f645f9 100644 (file)
@@ -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 (file)
index 0000000..fc89d17
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef XTF_X86_TRAPS_H
+#define XTF_X86_TRAPS_H
+
+#include <xtf/compiler.h>
+
+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:
+ */
index 0de3ebf1b5e06e8fc34b320760a8e908d0bdb152..6aa8b68697f9e115c617826d28b56d82b49dce79 100644 (file)
@@ -2,6 +2,7 @@
 #define XTF_HYPERCALL_H
 
 #include <xtf/types.h>
+#include <arch/x86/page.h>
 
 #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 <xen/xen.h>
 #include <xen/sched.h>
index 512e954cb701ddf1f6337f8195a40557f31691fb..232f010dc6aaa36be6c65cdd7c2dbfbcc182de63 100644 (file)
@@ -2,11 +2,14 @@
 #define XTF_LIB_H
 
 #include <xtf/types.h>
+#include <xtf/compiler.h>
 
 #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 (file)
index 0000000..38108b8
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef XTF_TRAPS_H
+#define XTF_TRAPS_H
+
+#include <arch/x86/traps.h>
+
+#endif /* XTF_TRAPS_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */