From owner-svn-src-head@freebsd.org Tue Oct 13 17:27:38 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 9717D4468E7; Tue, 13 Oct 2020 17:27:38 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4C9jDB3WbSz3yT0; Tue, 13 Oct 2020 17:27:38 +0000 (UTC) (envelope-from jhb@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 4280120E29; Tue, 13 Oct 2020 17:27:38 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 09DHRc33015651; Tue, 13 Oct 2020 17:27:38 GMT (envelope-from jhb@FreeBSD.org) Received: (from jhb@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 09DHRbdu015648; Tue, 13 Oct 2020 17:27:37 GMT (envelope-from jhb@FreeBSD.org) Message-Id: <202010131727.09DHRbdu015648@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhb set sender to jhb@FreeBSD.org using -f From: John Baldwin Date: Tue, 13 Oct 2020 17:27:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r366673 - in head/sys/i386: i386 include X-SVN-Group: head X-SVN-Commit-Author: jhb X-SVN-Commit-Paths: in head/sys/i386: i386 include X-SVN-Commit-Revision: 366673 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Oct 2020 17:27:38 -0000 Author: jhb Date: Tue Oct 13 17:27:37 2020 New Revision: 366673 URL: https://svnweb.freebsd.org/changeset/base/366673 Log: Add support for FPU_KERN_NOCTX. This mirrors the implementation on amd64. Reviewed by: kib Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D26754 Modified: head/sys/i386/i386/npx.c head/sys/i386/include/npx.h head/sys/i386/include/pcb.h Modified: head/sys/i386/i386/npx.c ============================================================================== --- head/sys/i386/i386/npx.c Tue Oct 13 17:26:12 2020 (r366672) +++ head/sys/i386/i386/npx.c Tue Oct 13 17:27:37 2020 (r366673) @@ -886,6 +886,9 @@ npxdna(void) return (0); td = curthread; critical_enter(); + + KASSERT((curpcb->pcb_flags & PCB_NPXNOSAVE) == 0, + ("npxdna while in fpu_kern_enter(FPU_KERN_NOCTX)")); if (__predict_false(PCPU_GET(fpcurthread) == td)) { /* * Some virtual machines seems to set %cr0.TS at @@ -1390,8 +1393,34 @@ fpu_kern_enter(struct thread *td, struct fpu_kern_ctx { struct pcb *pcb; - KASSERT((ctx->flags & FPU_KERN_CTX_INUSE) == 0, ("using inuse ctx")); + pcb = td->td_pcb; + KASSERT((flags & FPU_KERN_NOCTX) != 0 || ctx != NULL, + ("ctx is required when !FPU_KERN_NOCTX")); + KASSERT(ctx == NULL || (ctx->flags & FPU_KERN_CTX_INUSE) == 0, + ("using inuse ctx")); + KASSERT((pcb->pcb_flags & PCB_NPXNOSAVE) == 0, + ("recursive fpu_kern_enter while in PCB_NPXNOSAVE state")); + if ((flags & FPU_KERN_NOCTX) != 0) { + critical_enter(); + stop_emulating(); + if (curthread == PCPU_GET(fpcurthread)) { + fpusave(curpcb->pcb_save); + PCPU_SET(fpcurthread, NULL); + } else { + KASSERT(PCPU_GET(fpcurthread) == NULL, + ("invalid fpcurthread")); + } + + /* + * This breaks XSAVEOPT tracker, but + * PCB_NPXNOSAVE state is supposed to never need to + * save FPU context at all. + */ + fpurstor(npx_initialstate); + pcb->pcb_flags |= PCB_KERNNPX | PCB_NPXNOSAVE | PCB_NPXINITDONE; + return; + } if ((flags & FPU_KERN_KTHR) != 0 && is_fpu_kern_thread(0)) { ctx->flags = FPU_KERN_CTX_DUMMY | FPU_KERN_CTX_INUSE; return; @@ -1416,17 +1445,32 @@ fpu_kern_leave(struct thread *td, struct fpu_kern_ctx { struct pcb *pcb; - KASSERT((ctx->flags & FPU_KERN_CTX_INUSE) != 0, - ("leaving not inuse ctx")); - ctx->flags &= ~FPU_KERN_CTX_INUSE; - - if (is_fpu_kern_thread(0) && (ctx->flags & FPU_KERN_CTX_DUMMY) != 0) - return (0); pcb = td->td_pcb; - critical_enter(); - if (curthread == PCPU_GET(fpcurthread)) - npxdrop(); - pcb->pcb_save = ctx->prev; + + if ((pcb->pcb_flags & PCB_NPXNOSAVE) != 0) { + KASSERT(ctx == NULL, ("non-null ctx after FPU_KERN_NOCTX")); + KASSERT(PCPU_GET(fpcurthread) == NULL, + ("non-NULL fpcurthread for PCB_NPXNOSAVE")); + CRITICAL_ASSERT(td); + + pcb->pcb_flags &= ~(PCB_NPXNOSAVE | PCB_NPXINITDONE); + start_emulating(); + } else { + KASSERT((ctx->flags & FPU_KERN_CTX_INUSE) != 0, + ("leaving not inuse ctx")); + ctx->flags &= ~FPU_KERN_CTX_INUSE; + + if (is_fpu_kern_thread(0) && + (ctx->flags & FPU_KERN_CTX_DUMMY) != 0) + return (0); + KASSERT((ctx->flags & FPU_KERN_CTX_DUMMY) == 0, + ("dummy ctx")); + critical_enter(); + if (curthread == PCPU_GET(fpcurthread)) + npxdrop(); + pcb->pcb_save = ctx->prev; + } + if (pcb->pcb_save == get_pcb_user_save_pcb(pcb)) { if ((pcb->pcb_flags & PCB_NPXUSERINITDONE) != 0) pcb->pcb_flags |= PCB_NPXINITDONE; Modified: head/sys/i386/include/npx.h ============================================================================== --- head/sys/i386/include/npx.h Tue Oct 13 17:26:12 2020 (r366672) +++ head/sys/i386/include/npx.h Tue Oct 13 17:27:37 2020 (r366673) @@ -92,6 +92,7 @@ void fpu_save_area_reset(union savefpu *fsa); #define FPU_KERN_NORMAL 0x0000 #define FPU_KERN_NOWAIT 0x0001 #define FPU_KERN_KTHR 0x0002 +#define FPU_KERN_NOCTX 0x0004 #endif Modified: head/sys/i386/include/pcb.h ============================================================================== --- head/sys/i386/include/pcb.h Tue Oct 13 17:26:12 2020 (r366672) +++ head/sys/i386/include/pcb.h Tue Oct 13 17:27:37 2020 (r366673) @@ -86,6 +86,7 @@ struct pcb { #define PCB_VM86CALL 0x10 /* in vm86 call */ #define PCB_NPXUSERINITDONE 0x20 /* user fpu state is initialized */ #define PCB_KERNNPX 0x40 /* kernel uses npx */ +#define PCB_NPXNOSAVE 0x80 /* no save area for current FPU ctx */ uint16_t pcb_initial_npxcw;