Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F169493115
D26754.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D26754.id.diff
View Options
Index: head/sys/i386/i386/npx.c
===================================================================
--- head/sys/i386/i386/npx.c
+++ head/sys/i386/i386/npx.c
@@ -886,6 +886,9 @@
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 @@
{
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 @@
{
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;
Index: head/sys/i386/include/npx.h
===================================================================
--- head/sys/i386/include/npx.h
+++ head/sys/i386/include/npx.h
@@ -92,6 +92,7 @@
#define FPU_KERN_NORMAL 0x0000
#define FPU_KERN_NOWAIT 0x0001
#define FPU_KERN_KTHR 0x0002
+#define FPU_KERN_NOCTX 0x0004
#endif
Index: head/sys/i386/include/pcb.h
===================================================================
--- head/sys/i386/include/pcb.h
+++ head/sys/i386/include/pcb.h
@@ -86,6 +86,7 @@
#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;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Sep 2, 5:05 PM (7 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37981214
Default Alt Text
D26754.id.diff (3 KB)
Attached To
Mode
D26754: Add support for FPU_KERN_NOCTX.
Attached
Detach File
Event Timeline
Log In to Comment