Source-Changes-HG archive

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

[src/trunk]: src/sys/arch Improve our segregs model. Pass 2/3.



details:   https://anonhg.NetBSD.org/src/rev/5af8ea9178da
branches:  trunk
changeset: 827194:5af8ea9178da
user:      maxv <maxv%NetBSD.org@localhost>
date:      Thu Oct 19 19:05:53 2017 +0000

description:
Improve our segregs model. Pass 2/3.

Treat %fs the same way we treat %ds and %es. For a new 32bit LWP %fs is
set to GUDATA32_SEL, and always updated in INTRFASTEXIT.

This solves an important issue we had until now: we couldn't handle the
faults generated by the "movw $val,%fs" instructions, because they were
deep into the kernel context. Now %fs can fault only in INTRFASTEXIT,
which is safe.

Note that it also fixes a bug I believe affected the kernel: on AMD CPUs,
setting %fs to zero does not flush the internal register state, and
therefore we could leak the %fs base address when context-switching. This
being said, I couldn't trigger the issue on the AMD cpu I have. Whatever,
it's fixed now, since we first set %fs to GUDATA32 - which does flush the
register state.

diffstat:

 sys/arch/amd64/amd64/locore.S  |  7 ++++---
 sys/arch/amd64/amd64/machdep.c |  7 +++----
 sys/arch/x86/x86/sys_machdep.c |  7 ++-----
 3 files changed, 9 insertions(+), 12 deletions(-)

diffs (95 lines):

diff -r af3a971b062e -r 5af8ea9178da sys/arch/amd64/amd64/locore.S
--- a/sys/arch/amd64/amd64/locore.S     Thu Oct 19 18:36:31 2017 +0000
+++ b/sys/arch/amd64/amd64/locore.S     Thu Oct 19 19:05:53 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: locore.S,v 1.134 2017/10/19 18:36:31 maxv Exp $        */
+/*     $NetBSD: locore.S,v 1.135 2017/10/19 19:05:53 maxv Exp $        */
 
 /*
  * Copyright-o-rama!
@@ -1196,12 +1196,12 @@
        movq    PCB_GS(%r14),%rax
        movq    %rax,(GUGS_SEL*8)(%rcx)
 
-       /* Set default 32bit values in %ds, %es. %fs and %gs are special. */
+       /* Set default 32bit values in %ds, %es and %fs. %gs is special. */
        movq    L_MD_REGS(%r12),%rbx
        movq    $GSEL(GUDATA32_SEL, SEL_UPL),%rax
        movw    %ax,%ds
        movw    %ax,%es
-       movw    TF_FS(%rbx),%fs
+       movw    %ax,%fs
        CLI(ax)
        SWAPGS
        movw    TF_GS(%rbx),%gs
@@ -1484,6 +1484,7 @@
        NOT_XEN(cli;)
        movw    TF_ES(%rsp),%es
        movw    TF_DS(%rsp),%ds
+       movw    TF_FS(%rsp),%fs
        SWAPGS
        jmp     .Lkexit
 
diff -r af3a971b062e -r 5af8ea9178da sys/arch/amd64/amd64/machdep.c
--- a/sys/arch/amd64/amd64/machdep.c    Thu Oct 19 18:36:31 2017 +0000
+++ b/sys/arch/amd64/amd64/machdep.c    Thu Oct 19 19:05:53 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.270 2017/10/19 18:36:31 maxv Exp $       */
+/*     $NetBSD: machdep.c,v 1.271 2017/10/19 19:05:53 maxv Exp $       */
 
 /*
  * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011
@@ -110,7 +110,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.270 2017/10/19 18:36:31 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.271 2017/10/19 19:05:53 maxv Exp $");
 
 /* #define XENDEBUG_LOW  */
 
@@ -453,7 +453,7 @@
                update_descriptor(&curcpu()->ci_gdt[GUGS_SEL], &pcb->pcb_gs);
                setds(GSEL(GUDATA32_SEL, SEL_UPL));
                setes(GSEL(GUDATA32_SEL, SEL_UPL));
-               setfs(tf->tf_fs);
+               setfs(GSEL(GUDATA32_SEL, SEL_UPL));
                HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, tf->tf_gs);
        } else {
                update_descriptor(&curcpu()->ci_gdt[GUFS_SEL], &zero);
@@ -2138,7 +2138,6 @@
        kpreempt_disable();
        update_descriptor(&curcpu()->ci_gdt[GUFS_SEL], &pcb->pcb_fs);
        update_descriptor(&curcpu()->ci_gdt[GUGS_SEL], &pcb->pcb_gs);
-       setfs(fssel);
        setusergs(gssel);
        tf->tf_fs = fssel;
        tf->tf_gs = gssel;
diff -r af3a971b062e -r 5af8ea9178da sys/arch/x86/x86/sys_machdep.c
--- a/sys/arch/x86/x86/sys_machdep.c    Thu Oct 19 18:36:31 2017 +0000
+++ b/sys/arch/x86/x86/sys_machdep.c    Thu Oct 19 19:05:53 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sys_machdep.c,v 1.40 2017/10/15 11:39:42 maxv Exp $    */
+/*     $NetBSD: sys_machdep.c,v 1.41 2017/10/19 19:05:53 maxv Exp $    */
 
 /*
  * Copyright (c) 1998, 2007, 2009, 2017 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.40 2017/10/15 11:39:42 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.41 2017/10/19 19:05:53 maxv Exp $");
 
 #include "opt_mtrr.h"
 #include "opt_pmc.h"
@@ -601,9 +601,6 @@
                    sizeof(struct segment_descriptor));
                if (l == curlwp) {
                        update_descriptor(&curcpu()->ci_gdt[GUFS_SEL], &usd);
-#ifdef __x86_64__
-                       setfs(GSEL(GUFS_SEL, SEL_UPL));
-#endif
                }
                tf->tf_fs = GSEL(GUFS_SEL, SEL_UPL);
        } else /* which == 'g' */ {



Home | Main Index | Thread Index | Old Index