From: Jan Kiszka <[email protected]>
Add basic reporting of exceptions that are triggered by an inmate so
that we stop translating all of them into hypervisor-caught triple
faults. Reporting is optional and need to be enabled explicitly by an
inmate via excp_reporting_init().
Signed-off-by: Jan Kiszka <[email protected]>
---
inmates/lib/x86/Makefile | 2 +-
inmates/lib/x86/excp.c | 165 +++++++++++++++++++++++++++++++++++++++
inmates/lib/x86/include/inmate.h | 2 +
3 files changed, 168 insertions(+), 1 deletion(-)
create mode 100644 inmates/lib/x86/excp.c
diff --git a/inmates/lib/x86/Makefile b/inmates/lib/x86/Makefile
index dc017b90..258eed18 100644
--- a/inmates/lib/x86/Makefile
+++ b/inmates/lib/x86/Makefile
@@ -40,7 +40,7 @@ include $(INMATES_LIB)/Makefile.lib
always := lib.a lib32.a
-TARGETS := header.o ioapic.o printk.o setup.o smp.o uart.o int.o
+TARGETS := header.o ioapic.o printk.o setup.o smp.o uart.o int.o excp.o
TARGETS += ../alloc.o ../pci.o ../string.o ../cmdline.o ../setup.o
TARGETS += ../uart-8250.o ../printk.o
TARGETS_64_ONLY := mem.o pci.o timing.o
diff --git a/inmates/lib/x86/excp.c b/inmates/lib/x86/excp.c
new file mode 100644
index 00000000..d26300a4
--- /dev/null
+++ b/inmates/lib/x86/excp.c
@@ -0,0 +1,165 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) Siemens AG, 2019
+ *
+ * Authors:
+ * Jan Kiszka <[email protected]>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ * Alternatively, you can use or redistribute this file under the following
+ * BSD license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <inmate.h>
+
+struct stack_frame {
+ unsigned long bp, si, dx, bx, ax;
+#ifdef __x86_64__
+ unsigned long r8, r9, r10, r11, r12, r13, r14, r15;
+ unsigned long cx, di;
+#else
+ unsigned long di, cx;
+#endif
+ unsigned long error_code, ip, cs, flags;
+#ifdef __x86_64__
+ unsigned long sp, ss;
+#endif
+};
+
+extern u8 excp_entry[];
+
+void excp_reporting_init(void)
+{
+ unsigned int vector;
+ u64 entry;
+
+ for (vector = 0; vector < 21; vector++) {
+ entry = (unsigned long)excp_entry + vector * 16;
+
+ idt[vector * 2] = (entry & 0xffff) | (INMATE_CS64 << 16) |
+ ((0x8e00 | (entry & 0xffff0000)) << 32);
+ idt[vector * 2 + 1] = entry >> 32;
+ }
+}
+
+static void __attribute__((used))
+exception_handler(unsigned int vector, struct stack_frame *frame)
+{
+ printk("--- EXCEPTION %d ---\n", vector);
+ if (vector >= 10 && vector <= 14)
+ printk(" Error code: 0x%08lx\n", frame->error_code);
+ printk(" CS: 0x%04lx IP: %p flags: 0x%08lx\n",
+ frame->cs, (void *)frame->ip, frame->flags);
+ printk(" SP: %p BP: %p\n", frame + 1, (void *)frame->bp);
+ printk(" AX: %p BX: %p CX: %p\n",
+ (void *)frame->ax, (void *)frame->bx, (void *)frame->bx);
+ printk(" DX: %p SI: %p DI: %p\n",
+ (void *)frame->dx, (void *)frame->si, (void *)frame->di);
+#ifdef __x86_64__
+ printk(" R8: %p R9: %p R10: %p\n",
+ (void *)frame->r8, (void *)frame->r9, (void *)frame->r10);
+ printk(" R11: %p R12: %p R13: %p\n",
+ (void *)frame->r11, (void *)frame->r12, (void *)frame->r13);
+ printk(" R14: %p R15: %p\n",
+ (void *)frame->r14, (void *)frame->r15);
+#endif
+
+ comm_region->cell_state = JAILHOUSE_CELL_FAILED;