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.