| /* Copyright (c) 2009-13 The Regents of the University of California |
| * Barret Rhoden <brho@cs.berkeley.edu> |
| * See LICENSE for details. |
| * |
| * x86 trap.c bit-specific functions. */ |
| |
| #include <arch/mmu.h> |
| #include <arch/x86.h> |
| #include <arch/arch.h> |
| #include <arch/console.h> |
| #include <arch/apic.h> |
| #include <ros/common.h> |
| #include <smp.h> |
| #include <assert.h> |
| #include <pmap.h> |
| #include <trap.h> |
| #include <monitor.h> |
| #include <process.h> |
| #include <mm.h> |
| #include <stdio.h> |
| #include <slab.h> |
| #include <syscall.h> |
| #include <kdebug.h> |
| #include <kmalloc.h> |
| |
| static spinlock_t ptf_lock = SPINLOCK_INITIALIZER_IRQSAVE; |
| |
| void print_trapframe(struct hw_trapframe *hw_tf) |
| { |
| struct per_cpu_info *pcpui = &per_cpu_info[core_id()]; |
| |
| /* This is only called in debug scenarios, and often when the kernel |
| * trapped and needs to tell us about it. Disable the lock checker so |
| * it doesn't go nuts when we print/panic */ |
| pcpui->__lock_checking_enabled--; |
| spin_lock_irqsave(&ptf_lock); |
| printk("HW TRAP frame %sat %p on core %d\n", |
| x86_hwtf_is_partial(hw_tf) ? "(partial) " : "", |
| hw_tf, core_id()); |
| printk(" rax 0x%016lx\n", hw_tf->tf_rax); |
| printk(" rbx 0x%016lx\n", hw_tf->tf_rbx); |
| printk(" rcx 0x%016lx\n", hw_tf->tf_rcx); |
| printk(" rdx 0x%016lx\n", hw_tf->tf_rdx); |
| printk(" rbp 0x%016lx\n", hw_tf->tf_rbp); |
| printk(" rsi 0x%016lx\n", hw_tf->tf_rsi); |
| printk(" rdi 0x%016lx\n", hw_tf->tf_rdi); |
| printk(" r8 0x%016lx\n", hw_tf->tf_r8); |
| printk(" r9 0x%016lx\n", hw_tf->tf_r9); |
| printk(" r10 0x%016lx\n", hw_tf->tf_r10); |
| printk(" r11 0x%016lx\n", hw_tf->tf_r11); |
| printk(" r12 0x%016lx\n", hw_tf->tf_r12); |
| printk(" r13 0x%016lx\n", hw_tf->tf_r13); |
| printk(" r14 0x%016lx\n", hw_tf->tf_r14); |
| printk(" r15 0x%016lx\n", hw_tf->tf_r15); |
| printk(" trap 0x%08x %s\n", hw_tf->tf_trapno, |
| x86_trapname(hw_tf->tf_trapno)); |
| /* FYI: these aren't physically adjacent to trap and err */ |
| if (hw_tf->tf_cs == GD_KT) |
| printk(" gsbs 0x%016lx\n", read_gsbase()); |
| else |
| printk(" gsbs 0x%016lx\n", hw_tf->tf_gsbase); |
| printk(" fsbs 0x%016lx\n", hw_tf->tf_fsbase); |
| printk(" err 0x--------%08x\n", hw_tf->tf_err); |
| printk(" rip 0x%016lx\n", hw_tf->tf_rip); |
| printk(" cs 0x------------%04x\n", hw_tf->tf_cs); |
| printk(" flag 0x%016lx\n", hw_tf->tf_rflags); |
| printk(" rsp 0x%016lx\n", hw_tf->tf_rsp); |
| printk(" ss 0x------------%04x\n", hw_tf->tf_ss); |
| spin_unlock_irqsave(&ptf_lock); |
| pcpui->__lock_checking_enabled++; |
| |
| /* Used in trapentry64.S */ |
| static_assert(offsetof(struct hw_trapframe, tf_cs) - |
| offsetof(struct hw_trapframe, tf_rax) == 0x90); |
| static_assert(offsetof(struct hw_trapframe, tf_padding0) - |
| offsetof(struct hw_trapframe, tf_rax) == 0xac); |
| /* Used in trap64.h */ |
| static_assert(offsetof(struct per_cpu_info, stacktop) == 0); |
| } |
| |
| void print_swtrapframe(struct sw_trapframe *sw_tf) |
| { |
| struct per_cpu_info *pcpui = &per_cpu_info[core_id()]; |
| |
| pcpui->__lock_checking_enabled--; |
| spin_lock_irqsave(&ptf_lock); |
| printk("SW TRAP frame %sat %p on core %d\n", |
| x86_swtf_is_partial(sw_tf) ? "(partial) " : "", |
| sw_tf, core_id()); |
| printk(" rbx 0x%016lx\n", sw_tf->tf_rbx); |
| printk(" rbp 0x%016lx\n", sw_tf->tf_rbp); |
| printk(" r12 0x%016lx\n", sw_tf->tf_r12); |
| printk(" r13 0x%016lx\n", sw_tf->tf_r13); |
| printk(" r14 0x%016lx\n", sw_tf->tf_r14); |
| printk(" r15 0x%016lx\n", sw_tf->tf_r15); |
| printk(" gsbs 0x%016lx\n", sw_tf->tf_gsbase); |
| printk(" fsbs 0x%016lx\n", sw_tf->tf_fsbase); |
| printk(" rip 0x%016lx\n", sw_tf->tf_rip); |
| printk(" rsp 0x%016lx\n", sw_tf->tf_rsp); |
| printk(" mxcsr 0x%08x\n", sw_tf->tf_mxcsr); |
| printk(" fpucw 0x%04x\n", sw_tf->tf_fpucw); |
| spin_unlock_irqsave(&ptf_lock); |
| pcpui->__lock_checking_enabled++; |
| } |
| |
| void print_vmtrapframe(struct vm_trapframe *vm_tf) |
| { |
| struct per_cpu_info *pcpui = &per_cpu_info[core_id()]; |
| |
| pcpui->__lock_checking_enabled--; |
| spin_lock_irqsave(&ptf_lock); |
| printk("VM Trapframe %sat %p on core %d\n", |
| x86_vmtf_is_partial(vm_tf) ? "(partial) " : "", |
| vm_tf, core_id()); |
| printk(" rax 0x%016lx\n", vm_tf->tf_rax); |
| printk(" rbx 0x%016lx\n", vm_tf->tf_rbx); |
| printk(" rcx 0x%016lx\n", vm_tf->tf_rcx); |
| printk(" rdx 0x%016lx\n", vm_tf->tf_rdx); |
| printk(" rbp 0x%016lx\n", vm_tf->tf_rbp); |
| printk(" rsi 0x%016lx\n", vm_tf->tf_rsi); |
| printk(" rdi 0x%016lx\n", vm_tf->tf_rdi); |
| printk(" r8 0x%016lx\n", vm_tf->tf_r8); |
| printk(" r9 0x%016lx\n", vm_tf->tf_r9); |
| printk(" r10 0x%016lx\n", vm_tf->tf_r10); |
| printk(" r11 0x%016lx\n", vm_tf->tf_r11); |
| printk(" r12 0x%016lx\n", vm_tf->tf_r12); |
| printk(" r13 0x%016lx\n", vm_tf->tf_r13); |
| printk(" r14 0x%016lx\n", vm_tf->tf_r14); |
| printk(" r15 0x%016lx\n", vm_tf->tf_r15); |
| printk(" rip 0x%016lx\n", vm_tf->tf_rip); |
| printk(" rflg 0x%016lx\n", vm_tf->tf_rflags); |
| printk(" rsp 0x%016lx\n", vm_tf->tf_rsp); |
| printk(" cr2 0x%016lx\n", vm_tf->tf_cr2); |
| printk(" cr3 0x%016lx\n", vm_tf->tf_cr3); |
| printk("Gpcore 0x%08x\n", vm_tf->tf_guest_pcoreid); |
| printk("Flags 0x%08x\n", vm_tf->tf_flags); |
| printk("Inject 0x%08x\n", vm_tf->tf_trap_inject); |
| printk("ExitRs 0x%08x\n", vm_tf->tf_exit_reason); |
| printk("ExitQl 0x%08x\n", vm_tf->tf_exit_qual); |
| printk("Intr1 0x%016lx\n", vm_tf->tf_intrinfo1); |
| printk("Intr2 0x%016lx\n", vm_tf->tf_intrinfo2); |
| printk("GIntr 0x----%04x\n", vm_tf->tf_guest_intr_status); |
| printk("GVA 0x%016lx\n", vm_tf->tf_guest_va); |
| printk("GPA 0x%016lx\n", vm_tf->tf_guest_pa); |
| spin_unlock_irqsave(&ptf_lock); |
| pcpui->__lock_checking_enabled++; |
| } |
| |
| void __arch_reflect_trap_hwtf(struct hw_trapframe *hw_tf, unsigned int trap_nr, |
| unsigned int err, unsigned long aux) |
| { |
| hw_tf->tf_trapno = trap_nr; |
| /* this can be necessary, since hw_tf is the pcpui one, and the err that |
| * came in probably came from the kernel stack's hw_tf. */ |
| hw_tf->tf_err = err; |
| hw_tf->tf_padding4 = (uint32_t)(aux); |
| hw_tf->tf_padding5 = (uint32_t)(aux >> 32); |
| hw_tf->tf_padding3 = ROS_ARCH_REFL_ID; |
| } |