#include <kdebug.h>
#include <kmalloc.h>
-/* Starts running the current TF, just using ret. */
-void pop_kernel_ctx(struct kernel_ctx *ctx)
-{
- struct sw_trapframe *tf = &ctx->sw_tf;
- /* We're starting at rbx's spot in the sw_tf */
- asm volatile ("movq %0, %%rsp; "
- "popq %%rbx; "
- "popq %%rbp; "
- "popq %%r12; "
- "popq %%r13; "
- "popq %%r14; "
- "popq %%r15; "
- "popq %%rax; " /* pop rip */
- "popq %%rsp; "
- "jmp *%%rax; " /* stored rip */
- : : "g"(&ctx->sw_tf.tf_rbx) : "memory");
- panic("ret failed");
-}
+static spinlock_t ptf_lock = SPINLOCK_INITIALIZER_IRQSAVE;
void print_trapframe(struct hw_trapframe *hw_tf)
{
- static spinlock_t ptf_lock = SPINLOCK_INITIALIZER_IRQSAVE;
-
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_depth_disabled++;
+ pcpui->__lock_checking_enabled--;
spin_lock_irqsave(&ptf_lock);
- printk("HW TRAP frame at %p on core %d\n", hw_tf, core_id());
+ 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(" rsp 0x%016lx\n", hw_tf->tf_rsp);
printk(" ss 0x------------%04x\n", hw_tf->tf_ss);
spin_unlock_irqsave(&ptf_lock);
- pcpui->__lock_depth_disabled--;
+ 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)
{
- static spinlock_t ptf_lock = SPINLOCK_INITIALIZER_IRQSAVE;
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
- pcpui->__lock_depth_disabled++;
+
+ pcpui->__lock_checking_enabled--;
spin_lock_irqsave(&ptf_lock);
- printk("SW TRAP frame at %p on core %d\n", sw_tf, core_id());
+ 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(" mxcsr 0x%08x\n", sw_tf->tf_mxcsr);
printk(" fpucw 0x%04x\n", sw_tf->tf_fpucw);
spin_unlock_irqsave(&ptf_lock);
- pcpui->__lock_depth_disabled--;
+ pcpui->__lock_checking_enabled++;
}
-void page_fault_handler(struct hw_trapframe *hw_tf)
+void print_vmtrapframe(struct vm_trapframe *vm_tf)
{
- uintptr_t fault_va = rcr2();
- int prot = hw_tf->tf_err & PF_ERROR_WRITE ? PROT_WRITE : PROT_READ;
- int err;
+ struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
- /* TODO - handle kernel page faults */
- if ((hw_tf->tf_cs & 3) == 0) {
- print_trapframe(hw_tf);
- backtrace_kframe(hw_tf);
- panic("Page Fault in the Kernel at 0x%08x!", fault_va);
- /* if we want to do something like kill a process or other code, be
- * aware we are in a sort of irq-like context, meaning the main kernel
- * code we 'interrupted' could be holding locks - even irqsave locks. */
- }
- /* safe to reenable after rcr2 */
- enable_irq();
- if ((err = handle_page_fault(current, fault_va, prot))) {
- /* Destroy the faulting process */
- printk("[%08x] user %s fault va %p ip %p on core %d with err %d\n",
- current->pid, prot & PROT_READ ? "READ" : "WRITE", fault_va,
- hw_tf->tf_rip, core_id(), err);
- print_trapframe(hw_tf);
- /* Turn this on to help debug bad function pointers */
- printd("rsp %p\n\t 0(rsp): %p\n\t 8(rsp): %p\n\t 16(rsp): %p\n"
- "\t24(rsp): %p\n", hw_tf->tf_rsp,
- *(uintptr_t*)(hw_tf->tf_rsp + 0),
- *(uintptr_t*)(hw_tf->tf_rsp + 8),
- *(uintptr_t*)(hw_tf->tf_rsp + 16),
- *(uintptr_t*)(hw_tf->tf_rsp + 24));
- proc_destroy(current);
- }
+ 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("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;
}