[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH 07/17] plat/common: Common x86 traps definitions and functions
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, ÷_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 -- 2.1.4 _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |