Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/amd64/amd64 Fix the double-fault handler. We're exe...



details:   https://anonhg.NetBSD.org/src/rev/152d8b701e52
branches:  trunk
changeset: 358858:152d8b701e52
user:      maxv <maxv%NetBSD.org@localhost>
date:      Sat Jan 20 08:30:53 2018 +0000

description:
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.

diffstat:

 sys/arch/amd64/amd64/amd64_trap.S |  41 ++++++++++++++++++++++++++++++++++++--
 sys/arch/amd64/amd64/trap.c       |  21 ++++++++++++++++++-
 2 files changed, 57 insertions(+), 5 deletions(-)

diffs (120 lines):

diff -r 3b565d4ce98c -r 152d8b701e52 sys/arch/amd64/amd64/amd64_trap.S
--- a/sys/arch/amd64/amd64/amd64_trap.S Sat Jan 20 07:43:28 2018 +0000
+++ b/sys/arch/amd64/amd64/amd64_trap.S Sat Jan 20 08:30:53 2018 +0000
@@ -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 @@
        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 @@
        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)
diff -r 3b565d4ce98c -r 152d8b701e52 sys/arch/amd64/amd64/trap.c
--- a/sys/arch/amd64/amd64/trap.c       Sat Jan 20 07:43:28 2018 +0000
+++ b/sys/arch/amd64/amd64/trap.c       Sat Jan 20 08:30:53 2018 +0000
@@ -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 @@
 #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 @@
        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.



Home | Main Index | Thread Index | Old Index