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' */ {