diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -277,8 +277,10 @@ */ if (TRAPF_USERMODE(frame)) { uprintf( - "pid %ld (%s): trap %d with interrupts disabled\n", - (long)curproc->p_pid, curthread->td_name, type); + "pid %ld (%s): trap %d (%s) " + "with interrupts disabled\n", + (long)curproc->p_pid, curthread->td_name, type, + trap_msg[type]); } else { switch (type) { case T_NMI: @@ -626,11 +628,11 @@ ksi.ksi_trapno = type; ksi.ksi_addr = (void *)addr; if (uprintf_signal) { - uprintf("pid %d comm %s: signal %d err %lx code %d type %d " - "addr 0x%lx rsp 0x%lx rip 0x%lx " + uprintf("pid %d comm %s: signal %d err %#lx code %d type %d " + "addr %#lx rsp %#lx rip %#lx rax %#lx" "<%02x %02x %02x %02x %02x %02x %02x %02x>\n", p->p_pid, p->p_comm, signo, frame->tf_err, ucode, type, - addr, frame->tf_rsp, frame->tf_rip, + addr, frame->tf_rsp, frame->tf_rip, frame->tf_rax, fubyte((void *)(frame->tf_rip + 0)), fubyte((void *)(frame->tf_rip + 1)), fubyte((void *)(frame->tf_rip + 2)), diff --git a/sys/i386/i386/copyout_fast.s b/sys/i386/i386/copyout_fast.s --- a/sys/i386/i386/copyout_fast.s +++ b/sys/i386/i386/copyout_fast.s @@ -93,7 +93,7 @@ popl %ecx popl %edi popl %esi - rep; movsb +pf_x1: rep; movsb movl %ebx,%cr3 movl %eax,%esp @@ -150,7 +150,7 @@ popl %ecx popl %edi popl %esi - rep; movsb +pf_x2: rep; movsb movl %ebx,%cr3 @@ -197,7 +197,7 @@ cli movl PCPU(TRAMPSTK),%esp movl %eax,%cr3 - movl (%ecx),%eax +pf_x3: movl (%ecx),%eax movl %ebx,%cr3 movl %esi,%esp sti @@ -226,7 +226,7 @@ cli movl PCPU(TRAMPSTK),%esp movl %eax,%cr3 - movzwl (%ecx),%eax +pf_x4: movzwl (%ecx),%eax movl %ebx,%cr3 movl %esi,%esp sti @@ -252,7 +252,7 @@ cli movl PCPU(TRAMPSTK),%esp movl %eax,%cr3 - movzbl (%ecx),%eax +pf_x5: movzbl (%ecx),%eax movl %ebx,%cr3 movl %esi,%esp sti @@ -291,7 +291,7 @@ cli movl PCPU(TRAMPSTK),%esp movl %eax,%cr3 - movl %edi,(%ecx) +pf_x6: movl %edi,(%ecx) movl %ebx,%cr3 movl %esi,%esp sti @@ -319,7 +319,7 @@ cli movl PCPU(TRAMPSTK),%esp movl %eax,%cr3 - movw %di,(%ecx) +pf_x7: movw %di,(%ecx) movl %ebx,%cr3 movl %esi,%esp sti @@ -348,7 +348,7 @@ movl PCPU(TRAMPSTK),%esp movl %eax,%cr3 movl %edi,%eax - movb %al,(%ecx) +pf_x8: movb %al,(%ecx) movl %ebx,%cr3 movl %esi,%esp sti diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s --- a/sys/i386/i386/exception.s +++ b/sys/i386/i386/exception.s @@ -130,17 +130,41 @@ jmp irettraps IDTVEC(page) testl $PSL_VM, TF_EFLAGS-TF_ERR(%esp) - jnz 1f + jnz 4f testb $SEL_RPL_MASK, TF_CS-TF_ERR(%esp) - jnz 1f + jnz 4f cmpl $PMAP_TRM_MIN_ADDRESS, TF_EIP-TF_ERR(%esp) - jb 1f + jb 4f + pushl %eax + movl TF_EIP-TF_ERR+4(%esp), %eax + addl $1f, %eax + call 5f +1: cmpl $pf_x1, %eax + je 2f + cmpl $pf_x2, %eax + je 2f + cmpl $pf_x3, %eax + je 2f + cmpl $pf_x4, %eax + je 2f + cmpl $pf_x5, %eax + je 2f + cmpl $pf_x6, %eax + je 2f + cmpl $pf_x7, %eax + je 2f + cmpl $pf_x8, %eax + jne 3f +2: popl %eax movl %ebx, %cr3 movl %edx, TF_EIP-TF_ERR(%esp) addl $4, %esp iret -1: pushl $T_PAGEFLT +3: popl %eax +4: pushl $T_PAGEFLT jmp alltraps +5: subl (%esp), %eax + retl IDTVEC(rsvd_pti) IDTVEC(rsvd) pushl $0; TRAP(T_RESERVED) @@ -205,27 +229,25 @@ leal (doreti_iret - 1b)(%ebx), %edx cmpl %edx, TF_EIP(%esp) jne 2f - movl $(2 * TF_SZ - TF_EIP), %ecx - jmp 6f + /* -8 because exception did not switch ring */ + movl $(2 * TF_SZ - TF_EIP - 8), %ecx + jmp 5f 2: leal (doreti_popl_ds - 1b)(%ebx), %edx cmpl %edx, TF_EIP(%esp) jne 3f - movl $(2 * TF_SZ - TF_DS), %ecx - jmp 6f + movl $(2 * TF_SZ - TF_DS - 8), %ecx + jmp 5f 3: leal (doreti_popl_es - 1b)(%ebx), %edx cmpl %edx, TF_EIP(%esp) jne 4f - movl $(2 * TF_SZ - TF_ES), %ecx - jmp 6f + movl $(2 * TF_SZ - TF_ES - 8), %ecx + jmp 5f 4: leal (doreti_popl_fs - 1b)(%ebx), %edx cmpl %edx, TF_EIP(%esp) - jne 5f - movl $(2 * TF_SZ - TF_FS), %ecx - jmp 6f - /* kernel mode, normal */ -5: jmp calltrap -6: cmpl $PMAP_TRM_MIN_ADDRESS, %esp /* trampoline stack ? */ - jb 5b /* if not, no need to change stacks */ + jne calltrap + movl $(2 * TF_SZ - TF_FS - 8), %ecx +5: cmpl $PMAP_TRM_MIN_ADDRESS, %esp /* trampoline stack ? */ + jb calltrap /* if not, no need to change stacks */ movl (tramp_idleptd - 1b)(%ebx), %eax movl %eax, %cr3 movl PCPU(KESP0), %edx @@ -234,6 +256,7 @@ movl %esp, %esi rep; movsb movl %edx, %esp + /* kernel mode, normal */ jmp calltrap /* @@ -493,22 +516,21 @@ je doreti_iret_nmi cmpl $T_TRCTRAP, TF_TRAPNO(%esp) je doreti_iret_nmi - movl $TF_SZ, %ecx testl $PSL_VM,TF_EFLAGS(%esp) - jz 1f /* PCB_VM86CALL is not set */ - addl $VM86_STACK_SPACE, %ecx - jmp 2f -1: testl $SEL_RPL_MASK, TF_CS(%esp) + jnz 1f /* PCB_VM86CALL is not set */ + testl $SEL_RPL_MASK, TF_CS(%esp) jz doreti_popl_fs -2: movl $handle_ibrs_exit,%eax - pushl %ecx /* preserve enough call-used regs */ +1: movl $handle_ibrs_exit,%eax call *%eax movl mds_handler,%eax call *%eax - popl %ecx movl %esp, %esi movl PCPU(TRAMPSTK), %edx - subl %ecx, %edx + movl $TF_SZ, %ecx + testl $PSL_VM,TF_EFLAGS(%esp) + jz 2f /* PCB_VM86CALL is not set */ + addl $VM86_STACK_SPACE, %ecx +2: subl $TF_SZ, %edx movl %edx, %edi rep; movsb movl %edx, %esp diff --git a/sys/i386/i386/exec_machdep.c b/sys/i386/i386/exec_machdep.c --- a/sys/i386/i386/exec_machdep.c +++ b/sys/i386/i386/exec_machdep.c @@ -640,6 +640,7 @@ regs->tf_esp = scp->sc_sp; regs->tf_eip = scp->sc_pc; regs->tf_eflags = eflags; + regs->tf_trapno = T_RESERVED; #if defined(COMPAT_43) if (scp->sc_onstack & 1) @@ -739,6 +740,7 @@ bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs)); } + regs->tf_trapno = T_RESERVED; #if defined(COMPAT_43) if (ucp->uc_mcontext.mc_onstack & 1) @@ -873,6 +875,7 @@ return (ret); bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs)); } + regs->tf_trapno = T_RESERVED; #if defined(COMPAT_43) if (ucp->uc_mcontext.mc_onstack & 1) diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -283,8 +283,10 @@ */ if ((frame->tf_eflags & PSL_I) == 0 && TRAPF_USERMODE(frame) && (curpcb->pcb_flags & PCB_VM86CALL) == 0) - uprintf("pid %ld (%s): trap %d with interrupts disabled\n", - (long)curproc->p_pid, curthread->td_name, type); + uprintf("pid %ld (%s): usermode trap %d (%s) with " + "interrupts disabled\n", + (long)curproc->p_pid, curthread->td_name, type, + trap_data[type].msg); /* * Conditionally reenable interrupts. If we hold a spin lock, @@ -691,12 +693,12 @@ ksi.ksi_addr = (void *)addr; ksi.ksi_trapno = type; if (uprintf_signal) { - uprintf("pid %d comm %s: signal %d err %x code %d type %d " - "addr 0x%x ss 0x%04x esp 0x%08x cs 0x%04x eip 0x%08x " + uprintf("pid %d comm %s: signal %d err %#x code %d type %d " + "addr %#x ss %#04x esp %#08x cs %#04x eip %#08x eax %#08x" "<%02x %02x %02x %02x %02x %02x %02x %02x>\n", p->p_pid, p->p_comm, signo, frame->tf_err, ucode, type, addr, frame->tf_ss, frame->tf_esp, frame->tf_cs, - frame->tf_eip, + frame->tf_eip, frame->tf_eax, fubyte((void *)(frame->tf_eip + 0)), fubyte((void *)(frame->tf_eip + 1)), fubyte((void *)(frame->tf_eip + 2)), @@ -988,18 +990,26 @@ void dblfault_handler(void) { + struct i386tss *t; + #ifdef KDTRACE_HOOKS if (dtrace_doubletrap_func != NULL) (*dtrace_doubletrap_func)(); #endif printf("\nFatal double fault:\n"); - printf("eip = 0x%x\n", PCPU_GET(common_tssp)->tss_eip); - printf("esp = 0x%x\n", PCPU_GET(common_tssp)->tss_esp); - printf("ebp = 0x%x\n", PCPU_GET(common_tssp)->tss_ebp); + t = PCPU_GET(common_tssp); + printf( + "eip = %#08x esp = %#08x ebp = %#08x eax = %#08x\n" + "edx = %#08x ecx = %#08x edi = %#08x esi = %#08x\n" + "psl = %#08x cs = %#08x ss = %#08x ds = %#08x\n" + "es = %#08x fs = %#08x gs = %#08x cr3 = %#08x\n", + t->tss_eip, t->tss_esp, t->tss_ebp, t->tss_eax, + t->tss_edx, t->tss_ecx, t->tss_edi, t->tss_esi, + t->tss_eflags, t->tss_cs, t->tss_ss, t->tss_ds, + t->tss_es, t->tss_fs, t->tss_gs, t->tss_cr3); #ifdef SMP - /* two separate prints in case of a trap on an unmapped page */ - printf("cpuid = %d; ", PCPU_GET(cpuid)); - printf("apic id = %02x\n", PCPU_GET(apic_id)); + printf("cpuid = %d; apic id = %02x\n", PCPU_GET(cpuid), + PCPU_GET(apic_id)); #endif panic("double fault"); } diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1080,11 +1080,12 @@ td, td_get_sched(td), p->p_pid, td->td_name); sched_fork_exit(td); + /* - * Processes normally resume in mi_switch() after being - * cpu_switch()'ed to, but when children start up they arrive here - * instead, so we must do much the same things as mi_switch() would. - */ + * Processes normally resume in mi_switch() after being + * cpu_switch()'ed to, but when children start up they arrive here + * instead, so we must do much the same things as mi_switch() would. + */ if ((dtd = PCPU_GET(deadthread))) { PCPU_SET(deadthread, NULL); thread_stash(dtd);