Module Name: src Committed By: maxv Date: Sun Oct 15 12:49:53 UTC 2017
Modified Files: src/sys/arch/amd64/amd64: machdep.c netbsd32_machdep.c src/sys/arch/amd64/include: segments.h src/sys/compat/linux/arch/amd64: linux_machdep.c src/sys/compat/linux32/arch/amd64: linux32_machdep.c Log Message: Use two separate functions: cpu_segregs32_zero and cpu_segregs64_zero. The way segment registers work on amd64 will diverge between 32bit and 64bit LWPs. To generate a diff of this commit: cvs rdiff -u -r1.265 -r1.266 src/sys/arch/amd64/amd64/machdep.c cvs rdiff -u -r1.110 -r1.111 src/sys/arch/amd64/amd64/netbsd32_machdep.c cvs rdiff -u -r1.30 -r1.31 src/sys/arch/amd64/include/segments.h cvs rdiff -u -r1.52 -r1.53 src/sys/compat/linux/arch/amd64/linux_machdep.c cvs rdiff -u -r1.40 -r1.41 \ src/sys/compat/linux32/arch/amd64/linux32_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/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.265 src/sys/arch/amd64/amd64/machdep.c:1.266 --- src/sys/arch/amd64/amd64/machdep.c:1.265 Sun Oct 15 10:58:32 2017 +++ src/sys/arch/amd64/amd64/machdep.c Sun Oct 15 12:49:53 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.265 2017/10/15 10:58:32 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.266 2017/10/15 12:49: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.265 2017/10/15 10:58:32 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.266 2017/10/15 12:49:53 maxv Exp $"); /* #define XENDEBUG_LOW */ @@ -1330,7 +1330,7 @@ setregs(struct lwp *l, struct exec_packa tf = l->l_md.md_regs; tf->tf_ds = LSEL(LUDATA_SEL, SEL_UPL); tf->tf_es = LSEL(LUDATA_SEL, SEL_UPL); - cpu_fsgs_zero(l); + cpu_segregs64_zero(l); tf->tf_rdi = 0; tf->tf_rsi = 0; tf->tf_rbp = 0; @@ -2042,17 +2042,17 @@ mm_md_kernacc(void *ptr, vm_prot_t prot, } /* - * Zero out an LWP's TLS context (%fs and %gs and associated stuff). - * Used when exec'ing a new program. + * Zero out a 64bit LWP's segments registers. Used when exec'ing a new + * 64bit program. */ - void -cpu_fsgs_zero(struct lwp *l) +cpu_segregs64_zero(struct lwp *l) { struct trapframe * const tf = l->l_md.md_regs; struct pcb *pcb; uint64_t zero = 0; + KASSERT((l->l_proc->p_flag & PK_32) == 0); KASSERT(l == curlwp); pcb = lwp_getpcb(l); @@ -2062,15 +2062,43 @@ cpu_fsgs_zero(struct lwp *l) tf->tf_gs = 0; setfs(0); setusergs(0); - if ((l->l_proc->p_flag & PK_32) == 0) { + #ifndef XEN - wrmsr(MSR_FSBASE, 0); - wrmsr(MSR_KERNELGSBASE, 0); + wrmsr(MSR_FSBASE, 0); + wrmsr(MSR_KERNELGSBASE, 0); #else - HYPERVISOR_set_segment_base(SEGBASE_FS, 0); - HYPERVISOR_set_segment_base(SEGBASE_GS_USER, 0); + HYPERVISOR_set_segment_base(SEGBASE_FS, 0); + HYPERVISOR_set_segment_base(SEGBASE_GS_USER, 0); #endif - } + + pcb->pcb_fs = 0; + pcb->pcb_gs = 0; + update_descriptor(&curcpu()->ci_gdt[GUFS_SEL], &zero); + update_descriptor(&curcpu()->ci_gdt[GUGS_SEL], &zero); + kpreempt_enable(); +} + +/* + * Zero out a 32bit LWP's segments registers. Used when exec'ing a new + * 32bit program. + */ +void +cpu_segregs32_zero(struct lwp *l) +{ + struct trapframe * const tf = l->l_md.md_regs; + struct pcb *pcb; + uint64_t zero = 0; + + KASSERT(l->l_proc->p_flag & PK_32); + KASSERT(l == curlwp); + + pcb = lwp_getpcb(l); + + kpreempt_disable(); + tf->tf_fs = 0; + tf->tf_gs = 0; + setfs(0); + setusergs(0); pcb->pcb_fs = 0; pcb->pcb_gs = 0; update_descriptor(&curcpu()->ci_gdt[GUFS_SEL], &zero); @@ -2082,7 +2110,6 @@ cpu_fsgs_zero(struct lwp *l) * Load an LWP's TLS context, possibly changing the %fs and %gs selectors. * Used only for 32-bit processes. */ - void cpu_fsgs_reload(struct lwp *l, int fssel, int gssel) { Index: src/sys/arch/amd64/amd64/netbsd32_machdep.c diff -u src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.110 src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.111 --- src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.110 Sun Oct 15 11:36:15 2017 +++ src/sys/arch/amd64/amd64/netbsd32_machdep.c Sun Oct 15 12:49:53 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_machdep.c,v 1.110 2017/10/15 11:36:15 maxv Exp $ */ +/* $NetBSD: netbsd32_machdep.c,v 1.111 2017/10/15 12:49:53 maxv Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -36,7 +36,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.110 2017/10/15 11:36:15 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.111 2017/10/15 12:49:53 maxv Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -148,7 +148,7 @@ netbsd32_setregs(struct lwp *l, struct e tf = l->l_md.md_regs; tf->tf_ds = LSEL(LUDATA32_SEL, SEL_UPL); tf->tf_es = LSEL(LUDATA32_SEL, SEL_UPL); - cpu_fsgs_zero(l); + cpu_segregs32_zero(l); cpu_fsgs_reload(l, tf->tf_ds, tf->tf_es); tf->tf_rdi = 0; tf->tf_rsi = 0; Index: src/sys/arch/amd64/include/segments.h diff -u src/sys/arch/amd64/include/segments.h:1.30 src/sys/arch/amd64/include/segments.h:1.31 --- src/sys/arch/amd64/include/segments.h:1.30 Sun Sep 17 09:41:35 2017 +++ src/sys/arch/amd64/include/segments.h Sun Oct 15 12:49:53 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: segments.h,v 1.30 2017/09/17 09:41:35 maxv Exp $ */ +/* $NetBSD: segments.h,v 1.31 2017/10/15 12:49:53 maxv Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -253,7 +253,8 @@ void idt_vec_free(int); #endif struct lwp; -void cpu_fsgs_zero(struct lwp *); +void cpu_segregs64_zero(struct lwp *); +void cpu_segregs32_zero(struct lwp *); void cpu_fsgs_reload(struct lwp *, int, int); #endif /* _KERNEL */ Index: src/sys/compat/linux/arch/amd64/linux_machdep.c diff -u src/sys/compat/linux/arch/amd64/linux_machdep.c:1.52 src/sys/compat/linux/arch/amd64/linux_machdep.c:1.53 --- src/sys/compat/linux/arch/amd64/linux_machdep.c:1.52 Fri Jul 14 13:21:29 2017 +++ src/sys/compat/linux/arch/amd64/linux_machdep.c Sun Oct 15 12:49:53 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: linux_machdep.c,v 1.52 2017/07/14 13:21:29 maxv Exp $ */ +/* $NetBSD: linux_machdep.c,v 1.53 2017/10/15 12:49:53 maxv Exp $ */ /*- * Copyright (c) 2005 Emmanuel Dreyfus, all rights reserved. @@ -33,7 +33,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.52 2017/07/14 13:21:29 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.53 2017/10/15 12:49:53 maxv Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -118,7 +118,7 @@ linux_setregs(struct lwp *l, struct exec tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL); tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL); tf->tf_es = 0; - cpu_fsgs_zero(l); + cpu_segregs64_zero(l); return; } Index: src/sys/compat/linux32/arch/amd64/linux32_machdep.c diff -u src/sys/compat/linux32/arch/amd64/linux32_machdep.c:1.40 src/sys/compat/linux32/arch/amd64/linux32_machdep.c:1.41 --- src/sys/compat/linux32/arch/amd64/linux32_machdep.c:1.40 Sun Oct 15 11:36:15 2017 +++ src/sys/compat/linux32/arch/amd64/linux32_machdep.c Sun Oct 15 12:49:53 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: linux32_machdep.c,v 1.40 2017/10/15 11:36:15 maxv Exp $ */ +/* $NetBSD: linux32_machdep.c,v 1.41 2017/10/15 12:49:53 maxv Exp $ */ /*- * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. @@ -31,7 +31,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: linux32_machdep.c,v 1.40 2017/10/15 11:36:15 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux32_machdep.c,v 1.41 2017/10/15 12:49:53 maxv Exp $"); #include <sys/param.h> #include <sys/proc.h> @@ -311,7 +311,7 @@ linux32_setregs(struct lwp *l, struct ex tf->tf_ss = GSEL(GUDATA32_SEL, SEL_UPL); tf->tf_ds = GSEL(GUDATA32_SEL, SEL_UPL); tf->tf_es = GSEL(GUDATA32_SEL, SEL_UPL); - cpu_fsgs_zero(l); + cpu_segregs32_zero(l); cpu_fsgs_reload(l, GSEL(GUDATA32_SEL, SEL_UPL), GSEL(GUDATA32_SEL, SEL_UPL)); }