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]>
---

Changes in v2:
 - reorder state setting and exception dumping

 inmates/lib/x86/Makefile         |   2 +-
 inmates/lib/x86/excp.c           | 169 +++++++++++++++++++++++++++++++++++++++
 inmates/lib/x86/include/inmate.h |   2 +
 3 files changed, 172 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..88c48389
--- /dev/null
+++ b/inmates/lib/x86/excp.c
@@ -0,0 +1,169 @@
+/*
+ * 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)
+{
+       /*
+        * Set the state first, in case enter an endless loop while reporting.
+        */
+       comm_region->cell_state = JAILHOUSE_CELL_FAILED;
+
+       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
+
+       stop();
+}
+
+asm(
+".macro excp_prologue vector\n\t"
+       "push $0\n\t"
+       "excp_error_prologue vector\n\t"
+".endm\n"
+
+".macro excp_error_prologue vector\n\t"
+#ifdef __x86_64__
+       "push %rdi\n\t"
+       "mov $vector,%rdi\n\t"
+#else
+       "push %ecx\n\t"
+       "mov $vector,%ecx\n\t"
+#endif
+       "jmp excp_common\n"
+       ".balign 16\n\t"
+".endm\n\t"
+
+       ".global excp_entry\n\t"
+       ".balign 16\n"
+"excp_entry:\n"
+"vector=0\n"
+".rept 8\n"
+       "excp_prologue vector\n\t"
+       "vector=vector+1\n\t"
+".endr\n"
+       "excp_error_prologue 8 \n\t"
+       "excp_prologue 9\n\t"
+"vector=10\n"
+".rept 5\n"
+       "excp_error_prologue vector\n\t"
+       "vector=vector+1\n\t"
+".endr\n"
+       "excp_prologue 15\n\t"
+       "excp_prologue 16\n\t"
+       "excp_error_prologue 17\n\t"
+       "excp_prologue 18\n\t"
+       "excp_prologue 19\n\t"
+       "excp_prologue 20\n\t"
+
+"excp_common:\n\t"
+#ifdef __x86_64__
+       "push %rcx\n\t"
+       "push %r15\n\t"
+       "push %r14\n\t"
+       "push %r13\n\t"
+       "push %r12\n\t"
+       "push %r11\n\t"
+       "push %r10\n\t"
+       "push %r9\n\t"
+       "push %r8\n\t"
+       "push %rax\n\t"
+       "push %rbx\n\t"
+       "push %rdx\n\t"
+       "push %rsi\n\t"
+       "push %rbp\n\t"
+       "mov %rsp,%rsi\n\t"
+#else
+       "push %edi\n\t"
+       "push %eax\n\t"
+       "push %ebx\n\t"
+       "push %edx\n\t"
+       "push %esi\n\t"
+       "push %ebp\n\t"
+       "mov %esp,%edx\n\t"
+#endif
+
+       "jmp exception_handler\n\t"
+);
diff --git a/inmates/lib/x86/include/inmate.h b/inmates/lib/x86/include/inmate.h
index 07a6275b..7664570d 100644
--- a/inmates/lib/x86/include/inmate.h
+++ b/inmates/lib/x86/include/inmate.h
@@ -222,6 +222,8 @@ static inline unsigned int cpu_id(void)
 
 extern unsigned long idt[];
 
+void excp_reporting_init(void);
+
 typedef void(*int_handler_t)(void);
 
 void int_init(void);
-- 
2.16.4

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/ed86a547-55fe-4a9e-1c77-4c6e62b1fc08%40siemens.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to