Module Name: src Committed By: maxv Date: Sat Jan 20 08:30:53 UTC 2018
Modified Files: src/sys/arch/amd64/amd64: amd64_trap.S trap.c Log Message: Fix the double-fault handler. We're executing on ist1 and must not jump out of it, so don't enable interrupts. And use the SVS_*_ALTSTACK macros. While here, fix the NMI handler too: it should use SVS_LEAVE_ALTSTACK. To generate a diff of this commit: cvs rdiff -u -r1.18 -r1.19 src/sys/arch/amd64/amd64/amd64_trap.S cvs rdiff -u -r1.110 -r1.111 src/sys/arch/amd64/amd64/trap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/amd64/amd64/amd64_trap.S diff -u src/sys/arch/amd64/amd64/amd64_trap.S:1.18 src/sys/arch/amd64/amd64/amd64_trap.S:1.19 --- src/sys/arch/amd64/amd64/amd64_trap.S:1.18 Thu Jan 18 07:25:34 2018 +++ src/sys/arch/amd64/amd64/amd64_trap.S Sat Jan 20 08:30:53 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: amd64_trap.S,v 1.18 2018/01/18 07:25:34 maxv Exp $ */ +/* $NetBSD: amd64_trap.S,v 1.19 2018/01/20 08:30:53 maxv Exp $ */ /* * Copyright (c) 1998, 2007, 2008, 2017 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ #if 0 #include <machine/asm.h> -__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.18 2018/01/18 07:25:34 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.19 2018/01/20 08:30:53 maxv Exp $"); #endif /* @@ -146,7 +146,7 @@ IDTVEC(trap02) movq %rsp,%rdi incq CPUVAR(NTRAP) call _C_LABEL(nmitrap) - SVS_LEAVE + SVS_LEAVE_ALTSTACK .Lnmileave: movw TF_ES(%rsp),%es @@ -224,8 +224,43 @@ IDTVEC(trap07) jmp .Lalltraps_checkusr IDTVEC_END(trap07) +/* + * Double faults execute on a particular stack, and we must not jump out + * of it. So don't enable interrupts. + */ IDTVEC(trap08) +#if defined(XEN) TRAP(T_DOUBLEFLT) +#else + TRAP_NJ(T_DOUBLEFLT) + subq $TF_REGSIZE,%rsp + INTR_SAVE_GPRS + SVS_ENTER_ALTSTACK + testb $SEL_UPL,TF_CS(%rsp) + jz 1f + swapgs +1: + cld + SMAP_ENABLE + movw %gs,TF_GS(%rsp) + movw %fs,TF_FS(%rsp) + movw %es,TF_ES(%rsp) + movw %ds,TF_DS(%rsp) + + movq %rsp,%rdi + incq CPUVAR(NTRAP) + call _C_LABEL(doubletrap) + + SVS_LEAVE_ALTSTACK + INTR_RESTORE_GPRS + + testb $SEL_UPL,TF_CS(%rsp) + jz 1f + swapgs +1: + addq $TF_REGSIZE+16,%rsp + iretq +#endif IDTVEC_END(trap08) IDTVEC(trap09) Index: src/sys/arch/amd64/amd64/trap.c diff -u src/sys/arch/amd64/amd64/trap.c:1.110 src/sys/arch/amd64/amd64/trap.c:1.111 --- src/sys/arch/amd64/amd64/trap.c:1.110 Wed Jan 10 20:51:11 2018 +++ src/sys/arch/amd64/amd64/trap.c Sat Jan 20 08:30:53 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.110 2018/01/10 20:51:11 maxv Exp $ */ +/* $NetBSD: trap.c,v 1.111 2018/01/20 08:30:53 maxv Exp $ */ /* * Copyright (c) 1998, 2000, 2017 The NetBSD Foundation, Inc. @@ -64,7 +64,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.110 2018/01/10 20:51:11 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.111 2018/01/20 08:30:53 maxv Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -121,6 +121,7 @@ dtrace_doubletrap_func_t dtrace_doubletr #endif void nmitrap(struct trapframe *); +void doubletrap(struct trapframe *); void trap(struct trapframe *); void trap_return_fault_return(struct trapframe *) __dead; @@ -228,6 +229,22 @@ nmitrap(struct trapframe *frame) x86_nmi(); } +void +doubletrap(struct trapframe *frame) +{ + const int type = T_DOUBLEFLT; + struct lwp *l = curlwp; + + trap_print(frame, l); + + if (kdb_trap(type, 0, frame)) + return; + if (kgdb_trap(type, frame)) + return; + + panic("double fault"); +} + /* * Did we receive in kernel mode a trap that ought to be considered as a user * trap? If this function returns, the answer is no.