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
This commit is contained in:
parent
d3ba71b2b1
commit
e406235000
@ -1230,8 +1230,9 @@ fpu_kern_leave(struct thread *td, struct fpu_kern_ctx *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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -1472,11 +1472,12 @@ fpu_kern_leave(struct thread *td, struct fpu_kern_ctx *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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user