#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)
-#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;
{
register_console_callback(xen_console_write);
+ init_hypercalls();
+
setup_pv_console();
}
--- /dev/null
+#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:
+ */
{
if ( nr_cons_cb < ARRAY_SIZE(output_fns) )
output_fns[nr_cons_cb++] = fn;
+ else
+ panic("Too many console callbacks\n");
}
/*
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);
}
--- /dev/null
+#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:
+ */
# 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
--- /dev/null
+#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:
+ */
#define XTF_HYPERCALL_H
#include <xtf/types.h>
+#include <arch/x86/page.h>
#if defined(__x86_64__)
# 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>
#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 */
/*
--- /dev/null
+#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:
+ */