From owner-svn-src-all@freebsd.org Fri Aug 3 14:12:39 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 43A1A106AF70; Fri, 3 Aug 2018 14:12:39 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id EB76C83368; Fri, 3 Aug 2018 14:12:38 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id CC6C12179B; Fri, 3 Aug 2018 14:12:38 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w73ECc6O069911; Fri, 3 Aug 2018 14:12:38 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w73ECcst069907; Fri, 3 Aug 2018 14:12:38 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201808031412.w73ECcst069907@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Fri, 3 Aug 2018 14:12:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r337245 - in stable/10/sys: amd64/amd64 i386/i386 i386/isa X-SVN-Group: stable-10 X-SVN-Commit-Author: kib X-SVN-Commit-Paths: in stable/10/sys: amd64/amd64 i386/i386 i386/isa X-SVN-Commit-Revision: 337245 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 03 Aug 2018 14:12:39 -0000 Author: kib Date: Fri Aug 3 14:12:37 2018 New Revision: 337245 URL: https://svnweb.freebsd.org/changeset/base/337245 Log: MFC r336683: Extend ranges of the critical sections to ensure that context switch code never sees FPU pcb flags not consistent with the hardware state. Modified: stable/10/sys/amd64/amd64/fpu.c stable/10/sys/amd64/amd64/machdep.c stable/10/sys/i386/i386/machdep.c stable/10/sys/i386/isa/npx.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/amd64/amd64/fpu.c ============================================================================== --- stable/10/sys/amd64/amd64/fpu.c Fri Aug 3 14:08:39 2018 (r337244) +++ stable/10/sys/amd64/amd64/fpu.c Fri Aug 3 14:12:37 2018 (r337245) @@ -741,22 +741,22 @@ fpugetregs(struct thread *td) int max_ext_n, i, owned; pcb = td->td_pcb; + critical_enter(); if ((pcb->pcb_flags & PCB_USERFPUINITDONE) == 0) { bcopy(fpu_initialstate, get_pcb_user_save_pcb(pcb), cpu_max_ext_state_size); get_pcb_user_save_pcb(pcb)->sv_env.en_cw = pcb->pcb_initial_fpucw; fpuuserinited(td); + critical_exit(); return (_MC_FPOWNED_PCB); } - critical_enter(); if (td == PCPU_GET(fpcurthread) && PCB_USER_FPU(pcb)) { fpusave(get_pcb_user_save_pcb(pcb)); owned = _MC_FPOWNED_FPU; } else { owned = _MC_FPOWNED_PCB; } - critical_exit(); if (use_xsave) { /* * Handle partially saved state. @@ -776,6 +776,7 @@ fpugetregs(struct thread *td) *xstate_bv |= bit; } } + critical_exit(); return (owned); } @@ -784,6 +785,7 @@ fpuuserinited(struct thread *td) { struct pcb *pcb; + CRITICAL_ASSERT(td); pcb = td->td_pcb; if (PCB_USER_FPU(pcb)) set_pcb_flags(pcb, @@ -842,26 +844,25 @@ fpusetregs(struct thread *td, struct savefpu *addr, ch addr->sv_env.en_mxcsr &= cpu_mxcsr_mask; pcb = td->td_pcb; + error = 0; critical_enter(); if (td == PCPU_GET(fpcurthread) && PCB_USER_FPU(pcb)) { error = fpusetxstate(td, xfpustate, xfpustate_size); - if (error != 0) { - critical_exit(); - return (error); + if (error == 0) { + bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr)); + fpurestore(get_pcb_user_save_td(td)); + set_pcb_flags(pcb, PCB_FPUINITDONE | + PCB_USERFPUINITDONE); } - bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr)); - fpurestore(get_pcb_user_save_td(td)); - critical_exit(); - set_pcb_flags(pcb, PCB_FPUINITDONE | PCB_USERFPUINITDONE); } else { - critical_exit(); error = fpusetxstate(td, xfpustate, xfpustate_size); - if (error != 0) - return (error); - bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr)); - fpuuserinited(td); + if (error == 0) { + bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr)); + fpuuserinited(td); + } } - return (0); + critical_exit(); + return (error); } /* @@ -1004,6 +1005,7 @@ fpu_kern_enter(struct thread *td, struct fpu_kern_ctx return (0); } pcb = td->td_pcb; + critical_enter(); KASSERT(!PCB_USER_FPU(pcb) || pcb->pcb_save == get_pcb_user_save_pcb(pcb), ("mangled pcb_save")); ctx->flags = 0; @@ -1014,6 +1016,7 @@ fpu_kern_enter(struct thread *td, struct fpu_kern_ctx pcb->pcb_save = fpu_kern_ctx_savefpu(ctx); set_pcb_flags(pcb, PCB_KERNFPU); clear_pcb_flags(pcb, PCB_FPUINITDONE); + critical_exit(); return (0); } @@ -1029,7 +1032,6 @@ fpu_kern_leave(struct thread *td, struct fpu_kern_ctx critical_enter(); if (curthread == PCPU_GET(fpcurthread)) fpudrop(); - critical_exit(); pcb->pcb_save = ctx->prev; if (pcb->pcb_save == get_pcb_user_save_pcb(pcb)) { if ((pcb->pcb_flags & PCB_USERFPUINITDONE) != 0) { @@ -1044,6 +1046,7 @@ fpu_kern_leave(struct thread *td, struct fpu_kern_ctx clear_pcb_flags(pcb, PCB_FPUINITDONE); KASSERT(!PCB_USER_FPU(pcb), ("unpaired fpu_kern_leave")); } + critical_exit(); return (0); } Modified: stable/10/sys/amd64/amd64/machdep.c ============================================================================== --- stable/10/sys/amd64/amd64/machdep.c Fri Aug 3 14:08:39 2018 (r337244) +++ stable/10/sys/amd64/amd64/machdep.c Fri Aug 3 14:12:37 2018 (r337245) @@ -2380,8 +2380,10 @@ int set_fpregs(struct thread *td, struct fpreg *fpregs) { + critical_enter(); set_fpregs_xmm(fpregs, get_pcb_user_save_td(td)); fpuuserinited(td); + critical_exit(); return (0); } Modified: stable/10/sys/i386/i386/machdep.c ============================================================================== --- stable/10/sys/i386/i386/machdep.c Fri Aug 3 14:08:39 2018 (r337244) +++ stable/10/sys/i386/i386/machdep.c Fri Aug 3 14:12:37 2018 (r337245) @@ -3780,6 +3780,7 @@ int set_fpregs(struct thread *td, struct fpreg *fpregs) { + critical_enter(); #ifdef CPU_ENABLE_SSE if (cpu_fxsr) set_fpregs_xmm((struct save87 *)fpregs, @@ -3791,6 +3792,7 @@ set_fpregs(struct thread *td, struct fpreg *fpregs) #ifdef DEV_NPX npxuserinited(td); #endif + critical_exit(); return (0); } Modified: stable/10/sys/i386/isa/npx.c ============================================================================== --- stable/10/sys/i386/isa/npx.c Fri Aug 3 14:08:39 2018 (r337244) +++ stable/10/sys/i386/isa/npx.c Fri Aug 3 14:12:37 2018 (r337245) @@ -1037,14 +1037,15 @@ npxgetregs(struct thread *td) return (_MC_FPOWNED_NONE); pcb = td->td_pcb; + critical_enter(); if ((pcb->pcb_flags & PCB_NPXINITDONE) == 0) { bcopy(npx_initialstate, get_pcb_user_save_pcb(pcb), cpu_max_ext_state_size); SET_FPU_CW(get_pcb_user_save_pcb(pcb), pcb->pcb_initial_npxcw); npxuserinited(td); + critical_exit(); return (_MC_FPOWNED_PCB); } - critical_enter(); if (td == PCPU_GET(fpcurthread)) { fpusave(get_pcb_user_save_pcb(pcb)); #ifdef CPU_ENABLE_SSE @@ -1060,7 +1061,6 @@ npxgetregs(struct thread *td) } else { owned = _MC_FPOWNED_PCB; } - critical_exit(); #ifdef CPU_ENABLE_SSE if (use_xsave) { /* @@ -1085,6 +1085,7 @@ npxgetregs(struct thread *td) } } #endif + critical_exit(); return (owned); } @@ -1093,6 +1094,7 @@ npxuserinited(struct thread *td) { struct pcb *pcb; + CRITICAL_ASSERT(td); pcb = td->td_pcb; if (PCB_USER_FPU(pcb)) pcb->pcb_flags |= PCB_NPXINITDONE; @@ -1156,32 +1158,32 @@ npxsetregs(struct thread *td, union savefpu *addr, cha addr->sv_xmm.sv_env.en_mxcsr &= cpu_mxcsr_mask; #endif pcb = td->td_pcb; + error = 0; critical_enter(); if (td == PCPU_GET(fpcurthread) && PCB_USER_FPU(pcb)) { #ifdef CPU_ENABLE_SSE error = npxsetxstate(td, xfpustate, xfpustate_size); - if (error != 0) { - critical_exit(); - return (error); - } - if (!cpu_fxsr) #endif - fnclex(); /* As in npxdrop(). */ - bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr)); - fpurstor(get_pcb_user_save_td(td)); - critical_exit(); - pcb->pcb_flags |= PCB_NPXUSERINITDONE | PCB_NPXINITDONE; + if (error == 0) { +#ifdef CPU_ENABLE_SSE + if (!cpu_fxsr) +#endif + fnclex(); /* As in npxdrop(). */ + bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr)); + fpurstor(get_pcb_user_save_td(td)); + pcb->pcb_flags |= PCB_NPXUSERINITDONE | PCB_NPXINITDONE; + } } else { - critical_exit(); #ifdef CPU_ENABLE_SSE error = npxsetxstate(td, xfpustate, xfpustate_size); - if (error != 0) - return (error); #endif - bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr)); - npxuserinited(td); + if (error == 0) { + bcopy(addr, get_pcb_user_save_td(td), sizeof(*addr)); + npxuserinited(td); + } } - return (0); + critical_exit(); + return (error); } static void @@ -1350,6 +1352,7 @@ fpu_kern_enter(struct thread *td, struct fpu_kern_ctx return (0); } pcb = td->td_pcb; + critical_enter(); KASSERT(!PCB_USER_FPU(pcb) || pcb->pcb_save == get_pcb_user_save_pcb(pcb), ("mangled pcb_save")); ctx->flags = 0; @@ -1360,6 +1363,7 @@ fpu_kern_enter(struct thread *td, struct fpu_kern_ctx pcb->pcb_save = fpu_kern_ctx_savefpu(ctx); pcb->pcb_flags |= PCB_KERNNPX; pcb->pcb_flags &= ~PCB_NPXINITDONE; + critical_exit(); return (0); } @@ -1374,7 +1378,6 @@ fpu_kern_leave(struct thread *td, struct fpu_kern_ctx critical_enter(); if (curthread == PCPU_GET(fpcurthread)) npxdrop(); - critical_exit(); pcb->pcb_save = ctx->prev; if (pcb->pcb_save == get_pcb_user_save_pcb(pcb)) { if ((pcb->pcb_flags & PCB_NPXUSERINITDONE) != 0) @@ -1389,6 +1392,7 @@ fpu_kern_leave(struct thread *td, struct fpu_kern_ctx pcb->pcb_flags &= ~PCB_NPXINITDONE; KASSERT(!PCB_USER_FPU(pcb), ("unpaired fpu_kern_leave")); } + critical_exit(); return (0); }