parlib: Improve panic() and assert()
[akaros.git] / kern / arch / x86 / trap.c
index 2a6134c..6b365d5 100644 (file)
@@ -162,10 +162,6 @@ void idt_init(void)
        x86_sysenter_init();
        set_stack_top((uintptr_t)bootstacktop);
 
-#ifdef CONFIG_KTHREAD_POISON
-       *kstack_bottom_addr((uintptr_t)bootstacktop) = 0xdeadbeef;
-#endif /* CONFIG_KTHREAD_POISON */
-
        /* Initialize the TSS field of the gdt.  The size of the TSS desc differs
         * between 64 and 32 bit, hence the pointer acrobatics */
        syssegdesc_t *ts_slot = (syssegdesc_t*)&gdt[GD_TSS >> 3];
@@ -557,9 +553,10 @@ static void trap_dispatch(struct hw_trapframe *hw_tf)
        // Handle processor exceptions.
        switch(hw_tf->tf_trapno) {
                case T_BRKPT:
-                       enable_irq();
-                       monitor(hw_tf);
-                       disable_irq();
+                       if (!in_kernel(hw_tf))
+                               backtrace_user_ctx(current, current_ctx);
+                       else
+                               monitor(hw_tf);
                        handled = TRUE;
                        break;
                case T_ILLOP:
@@ -887,6 +884,9 @@ static bool handle_vmexit_cpuid(struct vm_trapframe *tf)
 {
        uint32_t eax, ebx, ecx, edx;
 
+       if (tf->tf_rax == 0x0B)
+               return FALSE;   // Handle in userspace.
+
        cpuid(tf->tf_rax, tf->tf_rcx, &eax, &ebx, &ecx, &edx);
        switch (tf->tf_rax) {
                case 0x01:
@@ -898,6 +898,11 @@ static bool handle_vmexit_cpuid(struct vm_trapframe *tf)
                        /* Unset the perf capability bit so that the guest does not try
                         * to turn it on. */
                        ecx &= ~(1 << 15);
+
+                       /* Set the guest pcore id into the apic ID field in CPUID. */
+                       ebx &= 0x0000ffff;
+                       ebx |= (current->vmm.nr_guest_pcores & 0xff) << 16;
+                       ebx |= (tf->tf_guest_pcoreid & 0xff) << 24;
                        break;
                case 0x0A:
                        eax = 0;
@@ -962,7 +967,7 @@ bool handle_vmexit_msr(struct vm_trapframe *tf)
 {
        bool ret;
 
-       ret = vmm_emulate_msr(&tf->tf_rcx, &tf->tf_rdx, &tf->tf_rax,
+       ret = vmm_emulate_msr(tf,
                              (tf->tf_exit_reason == EXIT_REASON_MSR_READ
                                                   ? VMM_MSR_EMU_READ : VMM_MSR_EMU_WRITE));
        if (ret)
@@ -1056,7 +1061,8 @@ static void vmexit_dispatch(struct vm_trapframe *tf)
         * do it for external IRQs - the irq_dispatch code will handle it. */
        switch (tf->tf_exit_reason) {
        case EXIT_REASON_VMCALL:
-               if (current->vmm.flags & VMM_VMCALL_PRINTF) {
+               if (current->vmm.flags & VMM_VMCALL_PRINTF &&
+                   tf->tf_rax == VMCALL_PRINTC) {
                        printk("%c", tf->tf_rdi);
                        tf->tf_rip += 3;
                        handled = TRUE;
@@ -1132,16 +1138,16 @@ void handle_vmexit(struct vm_trapframe *tf)
  * loaded with the current GS (the kernel's). */
 static void x86_finalize_hwtf(struct hw_trapframe *tf)
 {
-       tf->tf_gsbase = read_msr(MSR_KERNEL_GS_BASE);
-       write_msr(MSR_KERNEL_GS_BASE, read_gsbase());
+       tf->tf_gsbase = read_kern_gsbase();
+       write_kern_gsbase(read_gsbase());
        tf->tf_fsbase = read_fsbase();
        x86_hwtf_clear_partial(tf);
 }
 
 static void x86_finalize_swtf(struct sw_trapframe *tf)
 {
-       tf->tf_gsbase = read_msr(MSR_KERNEL_GS_BASE);
-       write_msr(MSR_KERNEL_GS_BASE, read_gsbase());
+       tf->tf_gsbase = read_kern_gsbase();
+       write_kern_gsbase(read_gsbase());
        tf->tf_fsbase = read_fsbase();
        x86_swtf_clear_partial(tf);
 }
@@ -1151,7 +1157,7 @@ static void x86_finalize_vmtf(struct vm_trapframe *tf)
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
 
        x86_vmtf_clear_partial(tf);
-       unload_guest_pcore(pcpui->cur_proc, pcpui->guest_pcoreid);
+       unload_guest_pcore(pcpui->owning_proc, pcpui->guest_pcoreid);
 }
 
 /* Makes sure that the user context is fully saved into ctx and not split across