Module Name:    src
Committed By:   maxv
Date:           Thu Oct 19 19:05:53 UTC 2017

Modified Files:
        src/sys/arch/amd64/amd64: locore.S machdep.c
        src/sys/arch/x86/x86: sys_machdep.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.134 -r1.135 src/sys/arch/amd64/amd64/locore.S
cvs rdiff -u -r1.270 -r1.271 src/sys/arch/amd64/amd64/machdep.c
cvs rdiff -u -r1.40 -r1.41 src/sys/arch/x86/x86/sys_machdep.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/locore.S
diff -u src/sys/arch/amd64/amd64/locore.S:1.134 src/sys/arch/amd64/amd64/locore.S:1.135
--- src/sys/arch/amd64/amd64/locore.S:1.134	Thu Oct 19 18:36:31 2017
+++ src/sys/arch/amd64/amd64/locore.S	Thu Oct 19 19:05:53 2017
@@ -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 @@ lwp_32bit:
 	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 @@ ENTRY(intrfastexit)
 	NOT_XEN(cli;)
 	movw	TF_ES(%rsp),%es
 	movw	TF_DS(%rsp),%ds
+	movw	TF_FS(%rsp),%fs
 	SWAPGS
 	jmp	.Lkexit
 

Index: src/sys/arch/amd64/amd64/machdep.c
diff -u src/sys/arch/amd64/amd64/machdep.c:1.270 src/sys/arch/amd64/amd64/machdep.c:1.271
--- src/sys/arch/amd64/amd64/machdep.c:1.270	Thu Oct 19 18:36:31 2017
+++ src/sys/arch/amd64/amd64/machdep.c	Thu Oct 19 19:05:53 2017
@@ -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 @@ x86_64_tls_switch(struct lwp *l)
 		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 @@ cpu_fsgs_reload(struct lwp *l, int fssel
 	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;

Index: src/sys/arch/x86/x86/sys_machdep.c
diff -u src/sys/arch/x86/x86/sys_machdep.c:1.40 src/sys/arch/x86/x86/sys_machdep.c:1.41
--- src/sys/arch/x86/x86/sys_machdep.c:1.40	Sun Oct 15 11:39:42 2017
+++ src/sys/arch/x86/x86/sys_machdep.c	Thu Oct 19 19:05:53 2017
@@ -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 @@ x86_set_sdbase32(void *arg, char which, 
 		    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' */ {

Reply via email to