Module Name: src Committed By: riastradh Date: Mon Jul 20 16:41:18 UTC 2020
Modified Files: src/sys/arch/x86/x86: fpu.c Log Message: Save fpu state at IPL_VM to exclude fpu_kern_enter/leave. This way fpu_kern_enter/leave cannot interrupt the transition, so the transition from state-on-CPU to state-in-memory (with TS set) is atomic whether in an interrupt or not. (I am not 100% convinced that this is necessary, but it makes reasoning about the transition simpler.) To generate a diff of this commit: cvs rdiff -u -r1.70 -r1.71 src/sys/arch/x86/x86/fpu.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/x86/x86/fpu.c diff -u src/sys/arch/x86/x86/fpu.c:1.70 src/sys/arch/x86/x86/fpu.c:1.71 --- src/sys/arch/x86/x86/fpu.c:1.70 Mon Jul 20 16:38:47 2020 +++ src/sys/arch/x86/x86/fpu.c Mon Jul 20 16:41:18 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: fpu.c,v 1.70 2020/07/20 16:38:47 riastradh Exp $ */ +/* $NetBSD: fpu.c,v 1.71 2020/07/20 16:41:18 riastradh Exp $ */ /* * Copyright (c) 2008, 2019 The NetBSD Foundation, Inc. All @@ -96,7 +96,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.70 2020/07/20 16:38:47 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.71 2020/07/20 16:41:18 riastradh Exp $"); #include "opt_multiprocessor.h" @@ -151,14 +151,15 @@ fpu_save_lwp(struct lwp *l) { struct pcb *pcb = lwp_getpcb(l); union savefpu *area = &pcb->pcb_savefpu; + int s; - kpreempt_disable(); + s = splvm(); if (l->l_md.md_flags & MDL_FPU_IN_CPU) { KASSERT((l->l_flag & LW_SYSTEM) == 0); fpu_area_save(area, x86_xsave_features); l->l_md.md_flags &= ~MDL_FPU_IN_CPU; } - kpreempt_enable(); + splx(s); } /* @@ -299,8 +300,12 @@ fpu_handle_deferred(void) void fpu_switch(struct lwp *oldlwp, struct lwp *newlwp) { + struct cpu_info *ci __diagused = curcpu(); struct pcb *pcb; + KASSERTMSG(ci->ci_ilevel >= IPL_SCHED, "cpu%d ilevel=%d", + cpu_index(ci), ci->ci_ilevel); + if (oldlwp->l_md.md_flags & MDL_FPU_IN_CPU) { KASSERT(!(oldlwp->l_flag & LW_SYSTEM)); pcb = lwp_getpcb(oldlwp); @@ -334,11 +339,13 @@ fpu_lwp_fork(struct lwp *l1, struct lwp void fpu_lwp_abandon(struct lwp *l) { + int s; + KASSERT(l == curlwp); - kpreempt_disable(); + s = splvm(); l->l_md.md_flags &= ~MDL_FPU_IN_CPU; stts(); - kpreempt_enable(); + splx(s); } /* -------------------------------------------------------------------------- */