svn commit: r366713 - in head/sys: amd64/amd64 amd64/include i386/i386 i386/include
Konstantin Belousov
kib at FreeBSD.org
Wed Oct 14 23:01:43 UTC 2020
Author: kib
Date: Wed Oct 14 23:01:41 2020
New Revision: 366713
URL: https://svnweb.freebsd.org/changeset/base/366713
Log:
Fix for mis-interpretation of PCB_KERNFPU.
RIght now PCB_KERNFPU is used both as indication that kernel prepared
hardware FPU context to use and that the thread is fpu-kern
thread. This also breaks fpu_kern_enter(FPU_KERN_NOCTX), since
fpu_kern_leave() then clears PCB_KERNFPU.
Introduce new flag PCB_KERNFPU_THR which indicates that the thread is
fpu-kern. Do not clear PCB_KERNFPU if fpu-kern thread leaves noctx
fpu region.
Reported and tested by: jhb (amd64)
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D25511
Modified:
head/sys/amd64/amd64/fpu.c
head/sys/amd64/include/pcb.h
head/sys/i386/i386/npx.c
head/sys/i386/include/pcb.h
Modified: head/sys/amd64/amd64/fpu.c
==============================================================================
--- head/sys/amd64/amd64/fpu.c Wed Oct 14 22:57:50 2020 (r366712)
+++ head/sys/amd64/amd64/fpu.c Wed Oct 14 23:01:41 2020 (r366713)
@@ -1230,8 +1230,9 @@ fpu_kern_leave(struct thread *td, struct fpu_kern_ctx
if (pcb->pcb_save == get_pcb_user_save_pcb(pcb)) {
if ((pcb->pcb_flags & PCB_USERFPUINITDONE) != 0) {
set_pcb_flags(pcb, PCB_FPUINITDONE);
- clear_pcb_flags(pcb, PCB_KERNFPU);
- } else
+ if ((pcb->pcb_flags & PCB_KERNFPU_THR) == 0)
+ clear_pcb_flags(pcb, PCB_KERNFPU);
+ } else if ((pcb->pcb_flags & PCB_KERNFPU_THR) == 0)
clear_pcb_flags(pcb, PCB_FPUINITDONE | PCB_KERNFPU);
} else {
if ((ctx->flags & FPU_KERN_CTX_FPUINITDONE) != 0)
@@ -1254,7 +1255,7 @@ fpu_kern_thread(u_int flags)
("mangled pcb_save"));
KASSERT(PCB_USER_FPU(curpcb), ("recursive call"));
- set_pcb_flags(curpcb, PCB_KERNFPU);
+ set_pcb_flags(curpcb, PCB_KERNFPU | PCB_KERNFPU_THR);
return (0);
}
@@ -1264,7 +1265,7 @@ is_fpu_kern_thread(u_int flags)
if ((curthread->td_pflags & TDP_KTHREAD) == 0)
return (0);
- return ((curpcb->pcb_flags & PCB_KERNFPU) != 0);
+ return ((curpcb->pcb_flags & PCB_KERNFPU_THR) != 0);
}
/*
Modified: head/sys/amd64/include/pcb.h
==============================================================================
--- head/sys/amd64/include/pcb.h Wed Oct 14 22:57:50 2020 (r366712)
+++ head/sys/amd64/include/pcb.h Wed Oct 14 23:01:41 2020 (r366713)
@@ -84,6 +84,7 @@ struct pcb {
#define PCB_KERNFPU 0x04 /* kernel uses fpu */
#define PCB_FPUINITDONE 0x08 /* fpu state is initialized */
#define PCB_USERFPUINITDONE 0x10 /* fpu user state is initialized */
+#define PCB_KERNFPU_THR 0x20 /* fpu_kern_thread() */
#define PCB_32BIT 0x40 /* process has 32 bit context (segs etc) */
#define PCB_FPUNOSAVE 0x80 /* no save area for current FPU ctx */
Modified: head/sys/i386/i386/npx.c
==============================================================================
--- head/sys/i386/i386/npx.c Wed Oct 14 22:57:50 2020 (r366712)
+++ head/sys/i386/i386/npx.c Wed Oct 14 23:01:41 2020 (r366713)
@@ -1472,11 +1472,12 @@ fpu_kern_leave(struct thread *td, struct fpu_kern_ctx
}
if (pcb->pcb_save == get_pcb_user_save_pcb(pcb)) {
- if ((pcb->pcb_flags & PCB_NPXUSERINITDONE) != 0)
+ if ((pcb->pcb_flags & PCB_NPXUSERINITDONE) != 0) {
pcb->pcb_flags |= PCB_NPXINITDONE;
- else
- pcb->pcb_flags &= ~PCB_NPXINITDONE;
- pcb->pcb_flags &= ~PCB_KERNNPX;
+ if ((pcb->pcb_flags & PCB_KERNNPX_THR) == 0)
+ pcb->pcb_flags |= ~PCB_KERNNPX;
+ } else if ((pcb->pcb_flags & PCB_KERNNPX_THR) == 0)
+ pcb->pcb_flags &= ~(PCB_NPXINITDONE | PCB_KERNNPX);
} else {
if ((ctx->flags & FPU_KERN_CTX_NPXINITDONE) != 0)
pcb->pcb_flags |= PCB_NPXINITDONE;
@@ -1498,7 +1499,7 @@ fpu_kern_thread(u_int flags)
("mangled pcb_save"));
KASSERT(PCB_USER_FPU(curpcb), ("recursive call"));
- curpcb->pcb_flags |= PCB_KERNNPX;
+ curpcb->pcb_flags |= PCB_KERNNPX | PCB_KERNNPX_THR;
return (0);
}
@@ -1508,7 +1509,7 @@ is_fpu_kern_thread(u_int flags)
if ((curthread->td_pflags & TDP_KTHREAD) == 0)
return (0);
- return ((curpcb->pcb_flags & PCB_KERNNPX) != 0);
+ return ((curpcb->pcb_flags & PCB_KERNNPX_THR) != 0);
}
/*
Modified: head/sys/i386/include/pcb.h
==============================================================================
--- head/sys/i386/include/pcb.h Wed Oct 14 22:57:50 2020 (r366712)
+++ head/sys/i386/include/pcb.h Wed Oct 14 23:01:41 2020 (r366713)
@@ -82,6 +82,7 @@ struct pcb {
u_int pcb_flags;
#define PCB_DBREGS 0x02 /* process using debug registers */
+#define PCB_KERNNPX_THR 0x04 /* fpu_kern_thread() */
#define PCB_NPXINITDONE 0x08 /* fpu state is initialized */
#define PCB_VM86CALL 0x10 /* in vm86 call */
#define PCB_NPXUSERINITDONE 0x20 /* user fpu state is initialized */
More information about the svn-src-all
mailing list