svn commit: r366673 - in head/sys/i386: i386 include
John Baldwin
jhb at FreeBSD.org
Tue Oct 13 17:27:38 UTC 2020
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;
More information about the svn-src-all
mailing list