[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.cifneq (,$(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.Sindex 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_callback2hypervisor_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_SCHEDENTRY(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, ÷_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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |