[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Minios-devel] [UNIKRAFT PATCH 07/17] plat/common: Common x86 traps definitions and functions



Reviewed-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>

On 04.04.2018 15:53, Costin Lupu wrote:
Current changes introduce common x86 traps definitions and functions for both
Xen and KVM platforms. Trap names are enforced by the helper macros which
should be used when defining a new trap function. Whenever a platform needs to
add new traps it should define the trap number in
'plat/name/include/arch/traps.h' and the C trap handler in
'plat/name/arch/traps.c'. The assembly stub name should also follow the
convention specified in 'plat/common/include/x86/traps.h'.
The Xen specific traps work as an example for this rule.

Other changes:
* HVM traps updates for conforming with the new traps and segment descriptors
definitions
* 'os.h' cleanup; the goal is to get rid of this header
* minor change in 'plat/xen/x86/arch_time.c'

Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
---
  plat/common/include/x86/traps.h  | 115 +++++++++++++++++
  plat/common/x86/traps.c          | 116 +++++++++++++++++
  plat/xen/Makefile.uk             |   1 +
  plat/xen/include/xen-x86/os.h    |  34 -----
  plat/xen/include/xen-x86/traps.h |  23 ++--
  plat/xen/x86/arch_time.c         |   2 +-
  plat/xen/x86/entry64.S           | 108 ++++++----------
  plat/xen/x86/setup.c             |   2 +-
  plat/xen/x86/traps.c             | 263 +++++++++------------------------------
  9 files changed, 340 insertions(+), 324 deletions(-)
  create mode 100644 plat/common/include/x86/traps.h
  create mode 100644 plat/common/x86/traps.c

diff --git a/plat/common/include/x86/traps.h b/plat/common/include/x86/traps.h
new file mode 100644
index 0000000..b217b34
--- /dev/null
+++ b/plat/common/include/x86/traps.h
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Authors: Costin Lupu <costin.lupu@xxxxxxxxx>
+ *
+ * Copyright (c) 2018, NEC Europe Ltd., NEC Corporation. All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
+ */
+/* Ported from Mini-OS */
+
+#ifndef __UKARCH_TRAPS_X86_64_H__
+#define __UKARCH_TRAPS_X86_64_H__
+
+#include <x86/regs.h>
+
+#define TRAP_divide_error        0
+#define TRAP_debug               1
+#define TRAP_nmi                 2
+#define TRAP_int3                3
+#define TRAP_overflow            4
+#define TRAP_bounds              5
+#define TRAP_invalid_op          6
+#define TRAP_no_device           7
+#define TRAP_double_fault        8
+#define TRAP_invalid_tss         10
+#define TRAP_no_segment          11
+#define TRAP_stack_error         12
+#define TRAP_gp_fault            13
+#define TRAP_page_fault          14
+#define TRAP_coproc_error        16
+#define TRAP_alignment_check     17
+#define TRAP_machine_check       18
+#define TRAP_simd_error          19
+#define TRAP_virt_error          20
+#define TRAP_security_error      30
+
+#define ASM_TRAP_SYM(trapname)   asm_trap_##trapname
+
+#ifndef __ASSEMBLY__
+
+#define DECLARE_ASM_TRAP(trapname) \
+       void ASM_TRAP_SYM(trapname)(void)
+
+/*
+ * These are assembler stubs in entry.S.
+ * They are the actual entry points for virtual exceptions.
+ */
+DECLARE_ASM_TRAP(divide_error);
+DECLARE_ASM_TRAP(debug);
+DECLARE_ASM_TRAP(nmi);
+DECLARE_ASM_TRAP(int3);
+DECLARE_ASM_TRAP(overflow);
+DECLARE_ASM_TRAP(bounds);
+DECLARE_ASM_TRAP(invalid_op);
+DECLARE_ASM_TRAP(no_device);
+DECLARE_ASM_TRAP(double_fault);
+DECLARE_ASM_TRAP(invalid_tss);
+DECLARE_ASM_TRAP(no_segment);
+DECLARE_ASM_TRAP(stack_error);
+DECLARE_ASM_TRAP(gp_fault);
+DECLARE_ASM_TRAP(page_fault);
+DECLARE_ASM_TRAP(coproc_error);
+DECLARE_ASM_TRAP(alignment_check);
+DECLARE_ASM_TRAP(machine_check);
+DECLARE_ASM_TRAP(simd_error);
+DECLARE_ASM_TRAP(virt_error);
+
+
+void do_unhandled_trap(int trapnr, char *str, struct __regs *regs,
+               unsigned long error_code);
+
+#define DECLARE_TRAP(name, str) \
+void do_##name(struct __regs *regs) \
+{ \
+       do_unhandled_trap(TRAP_##name, str, regs, 0); \
+}
+
+#define DECLARE_TRAP_EC(name, str) \
+void do_##name(struct __regs *regs, unsigned long error_code) \
+{ \
+       do_unhandled_trap(TRAP_##name, str, regs, error_code); \
+}
+
+
+void traps_init(void);
+void traps_fini(void);
+
+#endif
+
+#endif /* __UKARCH_TRAPS_X86_64_H__ */
diff --git a/plat/common/x86/traps.c b/plat/common/x86/traps.c
new file mode 100644
index 0000000..434577f
--- /dev/null
+++ b/plat/common/x86/traps.c
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Authors: Costin Lupu <costin.lupu@xxxxxxxxx>
+ *
+ * Copyright (c) 2018, NEC Europe Ltd., NEC Corporation. All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
+ */
+/* Ported from Mini-OS */
+
+#include <uk/arch/lcpu.h>
+#include <trace.h>
+#include <x86/cpu.h>
+#include <x86/traps.h>
+#include <uk/print.h>
+#include <uk/assert.h>
+
+/* Traps handled on both Xen and KVM */
+
+DECLARE_TRAP_EC(divide_error,      "divide error")
+DECLARE_TRAP   (debug,             "debug exception")
+DECLARE_TRAP_EC(int3,              "int3")
+DECLARE_TRAP_EC(overflow,          "overflow")
+DECLARE_TRAP_EC(bounds,            "bounds")
+DECLARE_TRAP_EC(invalid_op,        "invalid opcode")
+DECLARE_TRAP_EC(no_device,         "device not available")
+DECLARE_TRAP_EC(invalid_tss,       "invalid TSS")
+DECLARE_TRAP_EC(no_segment,        "segment not present")
+DECLARE_TRAP_EC(stack_error,       "stack segment")
+DECLARE_TRAP   (coproc_error,      "coprocessor error")
+DECLARE_TRAP_EC(alignment_check,   "alignment check")
+DECLARE_TRAP_EC(machine_check,     "machine check")
+DECLARE_TRAP   (simd_error,        "SIMD coprocessor error")
+
+
+void do_unhandled_trap(int trapnr, char *str, struct __regs *regs,
+               unsigned long error_code)
+{
+       uk_printd(DLVL_CRIT, "Unhandled Trap %d (%s), error code=0x%lx\n",
+                       trapnr, str, error_code);
+       uk_printk("Regs address %p\n", regs);
+       /* TODO revisit when UK_CRASH will also dump the registers */
+       dump_regs(regs);
+       UK_CRASH("Crashing\n");
+}
+
+static int handling_fault;
+
+static void fault_prologue(void)
+{
+       /* If we are already handling a page fault, and got another one
+        * that means we faulted in pagetable walk. Continuing here would cause
+        * a recursive fault
+        */
+       if (handling_fault == 1) {
+               UK_CRASH("Page fault in pagetable walk "
+                               "(access to invalid memory?).\n");
+       }
+       handling_fault++;
+       barrier();
+}
+
+void do_gp_fault(struct __regs *regs, long error_code)
+{
+       fault_prologue();
+       uk_printd(DLVL_CRIT, "GPF rip: %lx, error_code=%lx\n",
+                       regs->rip, error_code);
+       dump_regs(regs);
+       stack_walk_for_frame(regs->rbp);
+       dump_mem(regs->rsp);
+       dump_mem(regs->rbp);
+       dump_mem(regs->rip);
+       UK_CRASH("Crashing\n");
+}
+
+void do_page_fault(struct __regs *regs, unsigned long error_code)
+{
+       unsigned long addr = read_cr2();
+
+       fault_prologue();
+       uk_printd(DLVL_CRIT, "Page fault at linear address %lx, rip %lx, "
+                       "regs %p, sp %lx, our_sp %p, code %lx\n",
+                       addr, regs->rip, regs, regs->rsp, &addr, error_code);
+
+       dump_regs(regs);
+       stack_walk_for_frame(regs->rbp);
+       dump_mem(regs->rsp);
+       dump_mem(regs->rbp);
+       dump_mem(regs->rip);
+       UK_CRASH("Crashing\n");
+}
diff --git a/plat/xen/Makefile.uk b/plat/xen/Makefile.uk
index 49c4352..55ba50c 100644
--- a/plat/xen/Makefile.uk
+++ b/plat/xen/Makefile.uk
@@ -30,6 +30,7 @@ LIBXENPLAT_SRCS-y              += $(LIBXENPLAT_BASE)/memory.c
ifneq (,$(filter x86_32 x86_64,$(UK_ARCH)))
  LIBXENPLAT_SRCS-$(ARCH_X86_64) += $(UK_PLAT_COMMON_BASE)/x86/trace.c|common
+LIBXENPLAT_SRCS-$(ARCH_X86_64) += $(UK_PLAT_COMMON_BASE)/x86/traps.c|common
  LIBXENPLAT_SRCS-y              += $(LIBXENPLAT_BASE)/x86/setup.c
  LIBXENPLAT_SRCS-y              += $(LIBXENPLAT_BASE)/x86/traps.c
  LIBXENPLAT_SRCS-$(ARCH_X86_32) += $(LIBXENPLAT_BASE)/x86/entry32.S
diff --git a/plat/xen/include/xen-x86/os.h b/plat/xen/include/xen-x86/os.h
index 6fa4fa0..308d91a 100644
--- a/plat/xen/include/xen-x86/os.h
+++ b/plat/xen/include/xen-x86/os.h
@@ -62,32 +62,6 @@ typedef unsigned long u_long;
#include <x86/cpu_defs.h> -#define __KERNEL_CS FLAT_KERNEL_CS
-#define __KERNEL_DS     FLAT_KERNEL_DS
-#define __KERNEL_SS     FLAT_KERNEL_SS
-
-#define TRAP_divide_error      0
-#define TRAP_debug             1
-#define TRAP_nmi               2
-#define TRAP_int3              3
-#define TRAP_overflow          4
-#define TRAP_bounds            5
-#define TRAP_invalid_op        6
-#define TRAP_no_device         7
-#define TRAP_double_fault      8
-#define TRAP_copro_seg         9
-#define TRAP_invalid_tss      10
-#define TRAP_no_segment       11
-#define TRAP_stack_error      12
-#define TRAP_gp_fault         13
-#define TRAP_page_fault       14
-#define TRAP_spurious_int     15
-#define TRAP_copro_error      16
-#define TRAP_alignment_check  17
-#define TRAP_machine_check    18
-#define TRAP_simd_error       19
-#define TRAP_deferred_nmi     31
-#define TRAP_xen_callback     32
#define LOCK_PREFIX ""
  #define ADDR (*(volatile long *)addr)
@@ -97,8 +71,6 @@ typedef unsigned long u_long;
extern shared_info_t *HYPERVISOR_shared_info; -void arch_fini(void);
-
  #include <xen-x86/irq.h>
@@ -112,12 +84,6 @@ typedef struct {
  } atomic_t;
-/********************* common i386 and x86_64 ****************************/
-#define xen_mb() mb()
-#define xen_rmb() rmb()
-#define xen_wmb() wmb()
-#define xen_barrier() asm volatile("" : : : "memory")
-
  void block_domain(__snsec until);
#endif /* not assembly */
diff --git a/plat/xen/include/xen-x86/traps.h b/plat/xen/include/xen-x86/traps.h
index 498af76..c585a6e 100644
--- a/plat/xen/include/xen-x86/traps.h
+++ b/plat/xen/include/xen-x86/traps.h
@@ -35,18 +35,23 @@
  #ifndef _TRAPS_H_
  #define _TRAPS_H_
-#include <x86/regs.h>
+#include <stdint.h>
+#include <x86/traps.h>
-#define pt_regs __regs
+#include <xen/xen.h>
-void dump_regs(struct pt_regs *regs);
-void stack_walk(void);
+#define TRAP_coproc_seg_overrun  9
+#define TRAP_spurious_int        15
+#define TRAP_xen_callback        32
-#define TRAP_PF_PROT 0x1
-#define TRAP_PF_WRITE  0x2
-#define TRAP_PF_USER   0x4
+/* Assembler stubs */
+DECLARE_ASM_TRAP(coproc_seg_overrun);
+DECLARE_ASM_TRAP(spurious_int);
+DECLARE_ASM_TRAP(hypervisor_callback);
+void asm_failsafe_callback(void);
-void trap_init(void);
-void trap_fini(void);
+#define __KERNEL_CS     FLAT_KERNEL_CS
+#define __KERNEL_DS     FLAT_KERNEL_DS
+#define __KERNEL_SS     FLAT_KERNEL_SS
#endif /* _TRAPS_H_ */
diff --git a/plat/xen/x86/arch_time.c b/plat/xen/x86/arch_time.c
index 9e9f1bf..0621d90 100644
--- a/plat/xen/x86/arch_time.c
+++ b/plat/xen/x86/arch_time.c
@@ -235,7 +235,7 @@ void block_domain(__snsec until)
  }
static void timer_handler(evtchn_port_t ev __unused,
-               struct pt_regs *regs __unused, void *ign __unused)
+               struct __regs *regs __unused, void *ign __unused)
  {
        __nsec until = ukplat_monotonic_clock() + ukarch_time_msec_to_nsec(1);
diff --git a/plat/xen/x86/entry64.S b/plat/xen/x86/entry64.S
index 8109ccb..db9c615 100644
--- a/plat/xen/x86/entry64.S
+++ b/plat/xen/x86/entry64.S
@@ -25,7 +25,7 @@
#include <uk/arch/types.h>
  #include <uk/arch/limits.h>
-#include <x86/regs.h>
+#include <x86/traps.h>
  #include <uk/config.h>
  #include <xen/xen.h>
  #include <xen/elfnote.h>
@@ -115,6 +115,15 @@ KERNEL_CS_MASK = 0xfc
        jmp error_entry
  .endm
+.macro TRAP_ENTRY trapname, has_ec
+ENTRY(ASM_TRAP_SYM(\trapname))
+.if \has_ec
+       errorentry do_\trapname
+.else
+       zeroentry  do_\trapname
+.endif
+.endm
+
  .macro RESTORE_ALL
        movq OFFSETOF_REGS_R15(%rsp), %r15
        movq OFFSETOF_REGS_R14(%rsp), %r14
@@ -194,7 +203,7 @@ error_entry:
  /*
   * Xen event (virtual interrupt) entry point.
   */
-ENTRY(hypervisor_callback)
+ENTRY(ASM_TRAP_SYM(hypervisor_callback))
        zeroentry hypervisor_callback2
hypervisor_callback2:
@@ -250,7 +259,7 @@ ecrit:  /**** END OF CRITICAL REGION ****/
  hypervisor_prologue:
        pushq %r11
        pushq %rcx
-       jmp hypervisor_callback
+       jmp ASM_TRAP_SYM(hypervisor_callback)
# [How we do the fixup]. We want to merge the current stack frame with the
  # just-interrupted frame. How we do this depends on where in the critical
@@ -297,13 +306,10 @@ error_exit:
  /*
   * Xen event (virtual interrupt) entry point.
   */
-ENTRY(hypervisor_callback)
-       zeroentry do_hypervisor_callback
-
-
+TRAP_ENTRY hypervisor_callback, 0
  #endif
-ENTRY(failsafe_callback)
+ENTRY(asm_failsafe_callback)
  #ifdef CONFIG_PARAVIRT
          popq  %rcx
          popq  %r11
@@ -311,72 +317,28 @@ ENTRY(failsafe_callback)
          iretq
-ENTRY(coprocessor_error)
-        zeroentry do_coprocessor_error
-
-
-ENTRY(simd_coprocessor_error)
-        zeroentry do_simd_coprocessor_error
-
-
-ENTRY(device_not_available)
-        zeroentry do_device_not_available
-
-
-ENTRY(debug)
-        zeroentry do_debug
-
-
-ENTRY(int3)
-        zeroentry do_int3
-
-ENTRY(overflow)
-        zeroentry do_overflow
-
-
-ENTRY(bounds)
-        zeroentry do_bounds
-
-
-ENTRY(invalid_op)
-        zeroentry do_invalid_op
-
-
-ENTRY(coprocessor_segment_overrun)
-        zeroentry do_coprocessor_segment_overrun
-
-
-ENTRY(invalid_TSS)
-        errorentry do_invalid_TSS
-
-
-ENTRY(segment_not_present)
-        errorentry do_segment_not_present
-
-
-/* runs on exception stack */
-ENTRY(stack_segment)
-        errorentry do_stack_segment
-
-
-ENTRY(general_protection)
-        errorentry do_general_protection
-
-
-ENTRY(alignment_check)
-        errorentry do_alignment_check
-
-
-ENTRY(divide_error)
-        zeroentry do_divide_error
-
-
-ENTRY(spurious_interrupt_bug)
-        zeroentry do_spurious_interrupt_bug
-
+TRAP_ENTRY divide_error,        0
+TRAP_ENTRY debug,               0
+/* no NMI */
+TRAP_ENTRY int3,                0
+TRAP_ENTRY overflow,            0
+TRAP_ENTRY bounds,              0
+TRAP_ENTRY invalid_op,          0
+TRAP_ENTRY no_device,           0
+/* no Double Fault */
+TRAP_ENTRY coproc_seg_overrun,  0
+TRAP_ENTRY invalid_tss,         1
+TRAP_ENTRY no_segment,          1
+TRAP_ENTRY stack_error,         1 /* runs on exception stack */
+TRAP_ENTRY gp_fault,            1
+TRAP_ENTRY page_fault,          1
+TRAP_ENTRY spurious_int,        1
+TRAP_ENTRY coproc_error,        0
+TRAP_ENTRY alignment_check,     1
+/* no Machine Check */
+TRAP_ENTRY simd_error,          0
+/* no Virtualization Exception */
-ENTRY(page_fault)
-        errorentry do_page_fault
#if HAVE_SCHED
  ENTRY(thread_starter)
diff --git a/plat/xen/x86/setup.c b/plat/xen/x86/setup.c
index 21e4786..10f939d 100644
--- a/plat/xen/x86/setup.c
+++ b/plat/xen/x86/setup.c
@@ -113,7 +113,7 @@ struct ukplat_memregion_desc 
_libxenplat_mrd[UKPLAT_MEMRD_MAX_ENTRIES];
static inline void _init_traps(void)
  {
-       trap_init();
+       traps_init();
  }
static inline void _init_cpufeatures(void)
diff --git a/plat/xen/x86/traps.c b/plat/xen/x86/traps.c
index da3ca9a..bba3c42 100644
--- a/plat/xen/x86/traps.c
+++ b/plat/xen/x86/traps.c
@@ -23,172 +23,22 @@
   */
  /* Taken from Mini-OS */
+#include <stddef.h>
  #include <xen-x86/traps.h>
-#include <xen-x86/os.h>
+#include <xen-x86/hypercall.h>
  #include <uk/print.h>
-/*
- * These are assembler stubs in entry.S.
- * They are the actual entry points for virtual exceptions.
- */
-void divide_error(void);
-void debug(void);
-void int3(void);
-void overflow(void);
-void bounds(void);
-void invalid_op(void);
-void device_not_available(void);
-void coprocessor_segment_overrun(void);
-void invalid_TSS(void);
-void segment_not_present(void);
-void stack_segment(void);
-void general_protection(void);
-void page_fault(void);
-void coprocessor_error(void);
-void simd_coprocessor_error(void);
-void alignment_check(void);
-void spurious_interrupt_bug(void);
-void machine_check(void);
+/* Traps used only on Xen */
-#define do_exit() \
-       for (;;) {                                                             \
-       }
+DECLARE_TRAP_EC(coproc_seg_overrun, "coprocessor segment overrun")
+DECLARE_TRAP   (spurious_int,       "spurious interrupt bug")
-static void do_trap(int trapnr, char *str, struct __regs *regs,
-                   unsigned long error_code)
-{
-       uk_printk("FATAL:  Unhandled Trap %d (%s), error code=0x%lx\n", trapnr,
-                 str, error_code);
-       uk_printk("Regs address %p\n", regs);
-       dump_regs(regs);
-}
-
-#define DO_ERROR(trapnr, str, name)                                            
\
-       void do_##name(struct __regs *regs, unsigned long error_code)          \
-       {                                                                      \
-               do_trap(trapnr, str, regs, error_code);                        \
-       }
-
-#define DO_ERROR_INFO(trapnr, str, name, sicode, siaddr)                       
\
-       void do_##name(struct __regs *regs, unsigned long error_code)          \
-       {                                                                      \
-               do_trap(trapnr, str, regs, error_code);                        \
-       }
-
-DO_ERROR_INFO(0, "divide error", divide_error, FPE_INTDIV, regs->eip)
-DO_ERROR(3, "int3", int3)
-DO_ERROR(4, "overflow", overflow)
-DO_ERROR(5, "bounds", bounds)
-DO_ERROR_INFO(6, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
-DO_ERROR(7, "device not available", device_not_available)
-DO_ERROR(9, "coprocessor segment overrun", coprocessor_segment_overrun)
-DO_ERROR(10, "invalid TSS", invalid_TSS)
-DO_ERROR(11, "segment not present", segment_not_present)
-DO_ERROR(12, "stack segment", stack_segment)
-DO_ERROR_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0)
-DO_ERROR(18, "machine check", machine_check)
-
-static int handling_pg_fault;
-
-void do_page_fault(struct __regs *regs, unsigned long error_code)
-{
-       unsigned long addr = read_cr2();
-       struct sched_shutdown sched_shutdown = {.reason = SHUTDOWN_crash};
- /* If we are already handling a page fault, and got another one
-        * that means we faulted in pagetable walk. Continuing here would cause
-        * a recursive fault
-        */
-       if (handling_pg_fault == 1) {
-               uk_printk("Page fault in pagetable walk (access to invalid 
memory?).\n");
-               HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
-       }
-       handling_pg_fault++;
-       barrier();
-
-#ifdef __X86_64__
-       uk_printk("Page fault at linear address %lx, rip %lx, regs %p, sp %lx, 
our_sp %p, code %lx\n",
-                 addr, regs->rip, regs, regs->rsp, &addr, error_code);
-#else
-       uk_printk("Page fault at linear address %lx, eip %lx, regs %p, sp %lx, 
our_sp %p, code %lx\n",
-                 addr, regs->eip, regs, regs->esp, &addr, error_code);
-#endif
-
-       dump_regs(regs);
-#ifdef __X86_64__
-       stack_walk_for_frame(regs->rbp);
-       dump_mem(regs->rsp);
-       dump_mem(regs->rbp);
-       dump_mem(regs->rip);
-#else
-       do_stack_walk(regs->ebp);
-       dump_mem(regs->esp);
-       dump_mem(regs->ebp);
-       dump_mem(regs->eip);
-#endif
-       HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
-       /* We should never get here ... but still */
-       handling_pg_fault--;
-}
-
-void do_general_protection(struct __regs *regs, long error_code)
-{
-       struct sched_shutdown sched_shutdown = {.reason = SHUTDOWN_crash};
-#ifdef __X86_64__
-       uk_printk("GPF rip: %lx, error_code=%lx\n", regs->rip, error_code);
-#else
-       uk_printk("GPF eip: %lx, error_code=%lx\n", regs->eip, error_code);
-#endif
-       dump_regs(regs);
-#ifdef __X86_64__
-       stack_walk_for_frame(regs->rbp);
-       dump_mem(regs->rsp);
-       dump_mem(regs->rbp);
-       dump_mem(regs->rip);
-#else
-       do_stack_walk(regs->ebp);
-       dump_mem(regs->esp);
-       dump_mem(regs->ebp);
-       dump_mem(regs->eip);
-#endif
-       HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
-}
-
-void do_debug(struct __regs *regs)
-{
-       uk_printk("Debug exception\n");
-#define TF_MASK 0x100
-       regs->eflags &= ~TF_MASK;
-       dump_regs(regs);
-       do_exit();
-}
-
-void do_coprocessor_error(struct __regs *regs)
-{
-       uk_printk("Copro error\n");
-       dump_regs(regs);
-       do_exit();
-}
-
-void simd_math_error(void *eip __unused)
-{
-       uk_printk("SIMD error\n");
-}
-
-void do_simd_coprocessor_error(struct __regs *regs __unused)
-{
-       uk_printk("SIMD copro error\n");
-}
-
-void do_spurious_interrupt_bug(struct __regs *regs __unused)
-{
-}
+#ifdef CONFIG_PARAVIRT
-/* Assembler interface fns in entry.S. */
-void hypervisor_callback(void);
-void failsafe_callback(void);
+#define TRAP_TABLE_ENTRY(trapname, pl) \
+       { TRAP_##trapname, pl, __KERNEL_CS, (unsigned long) 
ASM_TRAP_SYM(trapname) }
-#ifdef CONFIG_PARAVIRT
  /*
   * Submit a virtual IDT to teh hypervisor. This consists of tuples
   * (interrupt vector, privilege ring, CS:EIP of handler).
@@ -196,41 +46,41 @@ void failsafe_callback(void);
   * can trap to that vector using a software-interrupt instruction (INT).
   */
  static trap_info_t trap_table[] = {
-       {  0, 0, __KERNEL_CS, (unsigned long)divide_error                },
-       {  1, 0, __KERNEL_CS, (unsigned long)debug                       },
-       {  3, 3, __KERNEL_CS, (unsigned long)int3                        },
-       {  4, 3, __KERNEL_CS, (unsigned long)overflow                    },
-       {  5, 3, __KERNEL_CS, (unsigned long)bounds                      },
-       {  6, 0, __KERNEL_CS, (unsigned long)invalid_op                  },
-       {  7, 0, __KERNEL_CS, (unsigned long)device_not_available        },
-       {  9, 0, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun },
-       { 10, 0, __KERNEL_CS, (unsigned long)invalid_TSS                 },
-       { 11, 0, __KERNEL_CS, (unsigned long)segment_not_present         },
-       { 12, 0, __KERNEL_CS, (unsigned long)stack_segment               },
-       { 13, 0, __KERNEL_CS, (unsigned long)general_protection          },
-       { 14, 0, __KERNEL_CS, (unsigned long)page_fault                  },
-       { 15, 0, __KERNEL_CS, (unsigned long)spurious_interrupt_bug      },
-       { 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error           },
-       { 17, 0, __KERNEL_CS, (unsigned long)alignment_check             },
-       { 19, 0, __KERNEL_CS, (unsigned long)simd_coprocessor_error      },
-       {  0, 0,           0, 0                                          }
+       TRAP_TABLE_ENTRY(divide_error,        0),
+       TRAP_TABLE_ENTRY(debug,               0),
+       TRAP_TABLE_ENTRY(int3,                3),
+       TRAP_TABLE_ENTRY(overflow,            3),
+       TRAP_TABLE_ENTRY(bounds,              3),
+       TRAP_TABLE_ENTRY(invalid_op,          0),
+       TRAP_TABLE_ENTRY(no_device,           0),
+       TRAP_TABLE_ENTRY(coproc_seg_overrun,  0),
+       TRAP_TABLE_ENTRY(invalid_tss,         0),
+       TRAP_TABLE_ENTRY(no_segment,          0),
+       TRAP_TABLE_ENTRY(stack_error,         0),
+       TRAP_TABLE_ENTRY(gp_fault,            0),
+       TRAP_TABLE_ENTRY(page_fault,          0),
+       TRAP_TABLE_ENTRY(spurious_int,        0),
+       TRAP_TABLE_ENTRY(coproc_error,        0),
+       TRAP_TABLE_ENTRY(alignment_check,     0),
+       TRAP_TABLE_ENTRY(simd_error,          0),
+       { 0, 0, 0, 0 }
  };
-void trap_init(void)
+void traps_init(void)
  {
        HYPERVISOR_set_trap_table(trap_table);
#ifdef __i386__
        HYPERVISOR_set_callbacks(__KERNEL_CS,
-                                (unsigned long)hypervisor_callback,
-                                __KERNEL_CS, (unsigned long)failsafe_callback);
+                                (unsigned long) asm_trap_hypervisor_callback,
+                                __KERNEL_CS, (unsigned long) 
asm_failsafe_callback);
  #else
-       HYPERVISOR_set_callbacks((unsigned long)hypervisor_callback,
-                                (unsigned long)failsafe_callback, 0);
+       HYPERVISOR_set_callbacks((unsigned long) asm_trap_hypervisor_callback,
+                                (unsigned long) asm_failsafe_callback, 0);
  #endif
  }
-void trap_fini(void)
+void traps_fini(void)
  {
        HYPERVISOR_set_trap_table(NULL);
  }
@@ -241,12 +91,12 @@ static uint8_t intr_stack[INTR_STACK_SIZE] 
__attribute__((aligned(16)));
hw_tss tss __attribute__((aligned(16))) = {
  #ifdef __X86_64__
-       .rsp0 = (unsigned long)&intr_stack[INTR_STACK_SIZE],
+       .rsp[0] = (unsigned long)&intr_stack[INTR_STACK_SIZE],
  #else
        .esp0 = (unsigned long)&intr_stack[INTR_STACK_SIZE],
        .ss0 = __KERN_DS,
  #endif
-       .iopb = X86_TSS_INVALID_IO_BITMAP,
+       .iomap_base = X86_TSS_INVALID_IO_BITMAP,
  };
static void setup_gate(unsigned int entry, void *addr, unsigned int dpl)
@@ -265,26 +115,28 @@ static void setup_gate(unsigned int entry, void *addr, 
unsigned int dpl)
  #endif
  }
-void trap_init(void)
+void traps_init(void)
  {
-       setup_gate(TRAP_divide_error, &divide_error, 0);
-       setup_gate(TRAP_debug, &debug, 0);
-       setup_gate(TRAP_int3, &int3, 3);
-       setup_gate(TRAP_overflow, &overflow, 3);
-       setup_gate(TRAP_bounds, &bounds, 0);
-       setup_gate(TRAP_invalid_op, &invalid_op, 0);
-       setup_gate(TRAP_no_device, &device_not_available, 0);
-       setup_gate(TRAP_copro_seg, &coprocessor_segment_overrun, 0);
-       setup_gate(TRAP_invalid_tss, &invalid_TSS, 0);
-       setup_gate(TRAP_no_segment, &segment_not_present, 0);
-       setup_gate(TRAP_stack_error, &stack_segment, 0);
-       setup_gate(TRAP_gp_fault, &general_protection, 0);
-       setup_gate(TRAP_page_fault, &page_fault, 0);
-       setup_gate(TRAP_spurious_int, &spurious_interrupt_bug, 0);
-       setup_gate(TRAP_copro_error, &coprocessor_error, 0);
-       setup_gate(TRAP_alignment_check, &alignment_check, 0);
-       setup_gate(TRAP_simd_error, &simd_coprocessor_error, 0);
-       setup_gate(TRAP_xen_callback, hypervisor_callback, 0);
+#define SETUP_TRAP_GATE(trapname, dpl) \
+       setup_gate(TRAP_##trapname, &ASM_TRAP_SYM(trapname), dpl)
+       SETUP_TRAP_GATE(divide_error, 0);
+       SETUP_TRAP_GATE(debug, 0);
+       SETUP_TRAP_GATE(int3, 3);
+       SETUP_TRAP_GATE(overflow, 3);
+       SETUP_TRAP_GATE(bounds, 0);
+       SETUP_TRAP_GATE(invalid_op, 0);
+       SETUP_TRAP_GATE(no_device, 0);
+       SETUP_TRAP_GATE(coproc_seg_overrun, 0);
+       SETUP_TRAP_GATE(invalid_tss, 0);
+       SETUP_TRAP_GATE(no_segment, 0);
+       SETUP_TRAP_GATE(stack_error, 0);
+       SETUP_TRAP_GATE(gp_fault, 0);
+       SETUP_TRAP_GATE(page_fault, 0);
+       SETUP_TRAP_GATE(spurious_int, 0);
+       SETUP_TRAP_GATE(coproc_error, 0);
+       SETUP_TRAP_GATE(alignment_check, 0);
+       SETUP_TRAP_GATE(simd_error, 0);
+       setup_gate(TRAP_xen_callback, ASM_TRAP_SYM(hypervisor_callback), 0);
asm volatile("lidt idt_ptr"); @@ -294,12 +146,11 @@ void trap_init(void) if (hvm_set_parameter(HVM_PARAM_CALLBACK_IRQ,
                              (2ULL << 56) | TRAP_xen_callback)) {
-               uk_printk("Request for Xen HVM callback vector failed\n");
-               do_exit();
+               UK_CRASH("Request for Xen HVM callback vector failed\n");
        }
  }
-void trap_fini(void)
+void traps_fini(void)
  {
  }
  #endif


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.