Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/amd64 Declare INTRFASTEXIT as a function, so that t...



details:   https://anonhg.NetBSD.org/src/rev/c0bf10510237
branches:  trunk
changeset: 826592:c0bf10510237
user:      maxv <maxv%NetBSD.org@localhost>
date:      Fri Sep 15 17:32:12 2017 +0000

description:
Declare INTRFASTEXIT as a function, so that there is only one iretq in the
kernel. Then, check %rip against the address of this iretq instead of
disassembling (%rip) - which could fault again, or point at some random
address which happens to contain the iretq opcode. The same is true for gs
below, but I'll fix that in another commit.

diffstat:

 sys/arch/amd64/amd64/amd64_trap.S |  11 +++++----
 sys/arch/amd64/amd64/locore.S     |  41 ++++++++++++++++++++++++++------------
 sys/arch/amd64/include/frameasm.h |  13 +----------
 3 files changed, 36 insertions(+), 29 deletions(-)

diffs (151 lines):

diff -r 7e558aedc700 -r c0bf10510237 sys/arch/amd64/amd64/amd64_trap.S
--- a/sys/arch/amd64/amd64/amd64_trap.S Fri Sep 15 17:22:09 2017 +0000
+++ b/sys/arch/amd64/amd64/amd64_trap.S Fri Sep 15 17:32:12 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: amd64_trap.S,v 1.10 2017/09/03 08:52:18 maxv Exp $     */
+/*     $NetBSD: amd64_trap.S,v 1.11 2017/09/15 17:32:12 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.10 2017/09/03 08:52:18 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.11 2017/09/15 17:32:12 maxv Exp $");
 #endif
 
 /*
@@ -385,9 +385,9 @@
        je      1b
 
        /* Case 2: fault on iretq? */
-       movq    TF_RIP(%rsp),%rax
-       cmpw    $0xcf48,(%rax)          /* Faulting instruction is iretq ? */
-       jne     5f                      /* Jump if not */
+       leaq    do_iret(%rip),%rdi
+       cmpq    %rdi,TF_RIP(%rsp)
+       jne     5f
        movq    TF_RSP(%rsp),%rax       /* Must read %rsp, may be a pad word */
        testb   $SEL_UPL,8(%rax)        /* Check %cs of outer iret frame */
        je      2b                      /* jump if iret was to kernel  */
@@ -395,6 +395,7 @@
 5:
 
        /* Case 3: move to %gs? */
+       movq    TF_RIP(%rsp),%rax
        movw    (%rax),%ax
        andb    $070,%ah                /* mask mod/rm from mod/reg/rm */
        cmpw    $0x8e+050*256,%ax       /* Any move to %gs (reg 5) */
diff -r 7e558aedc700 -r c0bf10510237 sys/arch/amd64/amd64/locore.S
--- a/sys/arch/amd64/amd64/locore.S     Fri Sep 15 17:22:09 2017 +0000
+++ b/sys/arch/amd64/amd64/locore.S     Fri Sep 15 17:32:12 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: locore.S,v 1.128 2017/08/31 10:30:58 maxv Exp $        */
+/*     $NetBSD: locore.S,v 1.129 2017/09/15 17:32:12 maxv Exp $        */
 
 /*
  * Copyright-o-rama!
@@ -329,6 +329,7 @@
        .globl  _C_LABEL(biosbasemem)
        .globl  _C_LABEL(biosextmem)
        .globl  do_sysret
+       .globl  do_iret
 
        .type   _C_LABEL(tablesize), @object
 _C_LABEL(tablesize):   .long   TABLESIZE
@@ -1304,12 +1305,19 @@
        jne     spl_error
 #endif
 
+       /*
+        * If the syscall might have modified some registers, or we are a 32bit
+        * process we must return to user with an 'iret' instruction.
+        * If the iret faults in kernel (assumed due to illegal register values)
+        * then a SIGSEGV will be signalled.
+        */
        testl   $(MDL_IRET|MDL_COMPAT32),L_MD_FLAGS(%r14)
        INTR_RESTORE_GPRS
        movw    TF_ES(%rsp),%es
        movw    TF_DS(%rsp),%ds
        SWAPGS
-       jnz     2f
+       jnz     .Lkexit
+
 #ifndef XEN
        movq    TF_RIP(%rsp),%rcx       /* %rip for sysret */
        movq    TF_RFLAGS(%rsp),%r11    /* %flags for sysret */
@@ -1322,16 +1330,6 @@
        jmp     HYPERVISOR_iret
 #endif
 
-/*
- * If the syscall might have modified some registers, or we are a 32bit
- * process we must return to user with an 'iret' instruction.
- * If the iret faults in kernel (assumed due to illegal register values)
- * then a SIGSEGV will be signalled.
- */
-2:
-       addq    $TF_RIP,%rsp
-       iretq
-
 #ifdef DIAGNOSTIC
        /* Report SPL error */
 spl_error:
@@ -1441,7 +1439,6 @@
  *
  * Zero a page without polluting the cache.
  */
-
 ENTRY(pagezero)
        movq    $-PAGE_SIZE,%rdx
        subq    %rdx,%rdi
@@ -1460,3 +1457,21 @@
        sfence
        ret
 END(pagezero)
+
+ENTRY(intrfastexit)
+       INTR_RESTORE_GPRS
+       testq   $SEL_UPL,TF_CS(%rsp)    /* interrupted %cs */
+       jz      .Lkexit
+
+       /* Disable interrupts until the 'iret', user registers loaded. */
+       NOT_XEN(cli;)
+       movw    TF_ES(%rsp),%es
+       movw    TF_DS(%rsp),%ds
+       SWAPGS
+
+.Lkexit:
+       addq    $TF_REGSIZE+16,%rsp     /* + T_xxx and error code */
+do_iret:
+       iretq
+END(intrfastexit)
+
diff -r 7e558aedc700 -r c0bf10510237 sys/arch/amd64/include/frameasm.h
--- a/sys/arch/amd64/include/frameasm.h Fri Sep 15 17:22:09 2017 +0000
+++ b/sys/arch/amd64/include/frameasm.h Fri Sep 15 17:32:12 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: frameasm.h,v 1.20 2012/07/15 15:17:56 dsl Exp $        */
+/*     $NetBSD: frameasm.h,v 1.21 2017/09/15 17:32:12 maxv Exp $       */
 
 #ifndef _AMD64_MACHINE_FRAMEASM_H
 #define _AMD64_MACHINE_FRAMEASM_H
@@ -92,16 +92,7 @@
 98:
 
 #define INTRFASTEXIT \
-       INTR_RESTORE_GPRS               ; \
-       testq   $SEL_UPL,TF_CS(%rsp)    /* Interrupted %cs */ ; \
-       je      99f                     ; \
-/* Disable interrupts until the 'iret', user registers loaded. */ \
-       NOT_XEN(cli;)                     \
-       movw    TF_ES(%rsp),%es         ; \
-       movw    TF_DS(%rsp),%ds         ; \
-       SWAPGS                          ; \
-99:    addq    $TF_REGSIZE+16,%rsp     /* + T_xxx and error code */ ; \
-       iretq
+       jmp     intrfastexit
 
 #define INTR_RECURSE_HWFRAME \
        movq    %rsp,%r10               ; \



Home | Main Index | Thread Index | Old Index