Date: Wed, 23 Jun 2010 11:21:19 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r209462 - in head/sys: i386/i386 i386/isa pc98/pc98 Message-ID: <201006231121.o5NBLJ8M049785@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Wed Jun 23 11:21:19 2010 New Revision: 209462 URL: http://svn.freebsd.org/changeset/base/209462 Log: After the FPU use requires #MF working due to INT13 FPU exception handling removal, MFi386 r209198: Use critical sections instead of disabling local interrupts to ensure the consistency between PCPU fpcurthread and the state of FPU. Reviewed by: bde Tested by: pho Modified: head/sys/i386/i386/machdep.c head/sys/i386/i386/vm_machdep.c head/sys/i386/isa/npx.c head/sys/pc98/pc98/machdep.c Modified: head/sys/i386/i386/machdep.c ============================================================================== --- head/sys/i386/i386/machdep.c Wed Jun 23 11:12:58 2010 (r209461) +++ head/sys/i386/i386/machdep.c Wed Jun 23 11:21:19 2010 (r209462) @@ -3391,10 +3391,9 @@ set_fpcontext(struct thread *td, const m static void fpstate_drop(struct thread *td) { - register_t s; KASSERT(PCB_USER_FPU(td->td_pcb), ("fpstate_drop: kernel-owned fpu")); - s = intr_disable(); + critical_enter(); #ifdef DEV_NPX if (PCPU_GET(fpcurthread) == td) npxdrop(); @@ -3411,7 +3410,7 @@ fpstate_drop(struct thread *td) */ curthread->td_pcb->pcb_flags &= ~(PCB_NPXINITDONE | PCB_NPXUSERINITDONE); - intr_restore(s); + critical_exit(); } int Modified: head/sys/i386/i386/vm_machdep.c ============================================================================== --- head/sys/i386/i386/vm_machdep.c Wed Jun 23 11:12:58 2010 (r209461) +++ head/sys/i386/i386/vm_machdep.c Wed Jun 23 11:21:19 2010 (r209462) @@ -150,9 +150,6 @@ cpu_fork(td1, p2, td2, flags) register struct proc *p1; struct pcb *pcb2; struct mdproc *mdp2; -#ifdef DEV_NPX - register_t savecrit; -#endif p1 = td1->td_proc; if ((flags & RFPROC) == 0) { @@ -180,10 +177,10 @@ cpu_fork(td1, p2, td2, flags) if (td1 == curthread) td1->td_pcb->pcb_gs = rgs(); #ifdef DEV_NPX - savecrit = intr_disable(); + critical_enter(); if (PCPU_GET(fpcurthread) == td1) npxsave(td1->td_pcb->pcb_save); - intr_restore(savecrit); + critical_exit(); #endif /* Point the pcb to the top of the stack */ @@ -328,8 +325,10 @@ cpu_thread_exit(struct thread *td) { #ifdef DEV_NPX + critical_enter(); if (td == PCPU_GET(fpcurthread)) npxdrop(); + critical_exit(); #endif /* Disable any hardware breakpoints. */ Modified: head/sys/i386/isa/npx.c ============================================================================== --- head/sys/i386/isa/npx.c Wed Jun 23 11:12:58 2010 (r209461) +++ head/sys/i386/isa/npx.c Wed Jun 23 11:21:19 2010 (r209462) @@ -308,10 +308,9 @@ cleanup: static int npx_attach(device_t dev) { - register_t s; npxinit(); - s = intr_disable(); + critical_enter(); stop_emulating(); fpusave(&npx_initialstate); start_emulating(); @@ -331,7 +330,7 @@ npx_attach(device_t dev) #endif bzero(npx_initialstate.sv_87.sv_ac, sizeof(npx_initialstate.sv_87.sv_ac)); - intr_restore(s); + critical_exit(); return (0); } @@ -352,6 +351,8 @@ npxinit(void) * fninit has the same h/w bugs as fnsave. Use the detoxified * fnsave to throw away any junk in the fpu. npxsave() initializes * the fpu and sets fpcurthread = NULL as important side effects. + * + * It is too early for critical_enter() to work on AP. */ savecrit = intr_disable(); npxsave(&dummy); @@ -374,12 +375,11 @@ void npxexit(td) struct thread *td; { - register_t savecrit; - savecrit = intr_disable(); + critical_enter(); if (curthread == PCPU_GET(fpcurthread)) npxsave(PCPU_GET(curpcb)->pcb_save); - intr_restore(savecrit); + critical_exit(); #ifdef NPX_DEBUG if (hw_float) { u_int masked_exceptions; @@ -602,7 +602,6 @@ static char fpetable[128] = { int npxtrap() { - register_t savecrit; u_short control, status; if (!hw_float) { @@ -610,7 +609,7 @@ npxtrap() PCPU_GET(fpcurthread), curthread, hw_float); panic("npxtrap from nowhere"); } - savecrit = intr_disable(); + critical_enter(); /* * Interrupt handling (for another interrupt) may have pushed the @@ -627,7 +626,7 @@ npxtrap() if (PCPU_GET(fpcurthread) == curthread) fnclex(); - intr_restore(savecrit); + critical_exit(); return (fpetable[status & ((~control & 0x3f) | 0x40)]); } @@ -645,14 +644,15 @@ int npxdna(void) { struct pcb *pcb; - register_t s; if (!hw_float) return (0); + critical_enter(); if (PCPU_GET(fpcurthread) == curthread) { printf("npxdna: fpcurthread == curthread %d times\n", ++err_count); stop_emulating(); + critical_exit(); return (1); } if (PCPU_GET(fpcurthread) != NULL) { @@ -662,7 +662,6 @@ npxdna(void) curthread, curthread->td_proc->p_pid); panic("npxdna"); } - s = intr_disable(); stop_emulating(); /* * Record new context early in case frstor causes an IRQ13. @@ -704,7 +703,7 @@ npxdna(void) */ fpurstor(pcb->pcb_save); } - intr_restore(s); + critical_exit(); return (1); } @@ -744,10 +743,6 @@ npxsave(addr) PCPU_SET(fpcurthread, NULL); } -/* - * This should be called with interrupts disabled and only when the owning - * FPU thread is non-null. - */ void npxdrop() { @@ -763,6 +758,8 @@ npxdrop() fnclex(); td = PCPU_GET(fpcurthread); + KASSERT(td == curthread, ("fpudrop: fpcurthread != curthread")); + CRITICAL_ASSERT(td); PCPU_SET(fpcurthread, NULL); td->td_pcb->pcb_flags &= ~PCB_NPXINITDONE; start_emulating(); @@ -776,7 +773,6 @@ int npxgetregs(struct thread *td, union savefpu *addr) { struct pcb *pcb; - register_t s; if (!hw_float) return (_MC_FPOWNED_NONE); @@ -787,7 +783,7 @@ npxgetregs(struct thread *td, union save SET_FPU_CW(addr, pcb->pcb_initial_npxcw); return (_MC_FPOWNED_NONE); } - s = intr_disable(); + critical_enter(); if (td == PCPU_GET(fpcurthread)) { fpusave(addr); #ifdef CPU_ENABLE_SSE @@ -799,10 +795,10 @@ npxgetregs(struct thread *td, union save * starts with a clean state next time. */ npxdrop(); - intr_restore(s); + critical_exit(); return (_MC_FPOWNED_FPU); } else { - intr_restore(s); + critical_exit(); bcopy(pcb->pcb_save, addr, sizeof(*addr)); return (_MC_FPOWNED_PCB); } @@ -812,7 +808,6 @@ int npxgetuserregs(struct thread *td, union savefpu *addr) { struct pcb *pcb; - register_t s; if (!hw_float) return (_MC_FPOWNED_NONE); @@ -823,7 +818,7 @@ npxgetuserregs(struct thread *td, union SET_FPU_CW(addr, pcb->pcb_initial_npxcw); return (_MC_FPOWNED_NONE); } - s = intr_disable(); + critical_enter(); if (td == PCPU_GET(fpcurthread) && PCB_USER_FPU(pcb)) { fpusave(addr); #ifdef CPU_ENABLE_SSE @@ -835,10 +830,10 @@ npxgetuserregs(struct thread *td, union * starts with a clean state next time. */ npxdrop(); - intr_restore(s); + critical_exit(); return (_MC_FPOWNED_FPU); } else { - intr_restore(s); + critical_exit(); bcopy(&pcb->pcb_user_save, addr, sizeof(*addr)); return (_MC_FPOWNED_PCB); } @@ -851,22 +846,21 @@ void npxsetregs(struct thread *td, union savefpu *addr) { struct pcb *pcb; - register_t s; if (!hw_float) return; pcb = td->td_pcb; - s = intr_disable(); + critical_enter(); if (td == PCPU_GET(fpcurthread)) { #ifdef CPU_ENABLE_SSE if (!cpu_fxsr) #endif fnclex(); /* As in npxdrop(). */ fpurstor(addr); - intr_restore(s); + critical_exit(); } else { - intr_restore(s); + critical_exit(); bcopy(addr, pcb->pcb_save, sizeof(*addr)); } if (PCB_USER_FPU(pcb)) @@ -878,23 +872,22 @@ void npxsetuserregs(struct thread *td, union savefpu *addr) { struct pcb *pcb; - register_t s; if (!hw_float) return; pcb = td->td_pcb; - s = intr_disable(); + critical_enter(); if (td == PCPU_GET(fpcurthread) && PCB_USER_FPU(pcb)) { #ifdef CPU_ENABLE_SSE if (!cpu_fxsr) #endif fnclex(); /* As in npxdrop(). */ fpurstor(addr); - intr_restore(s); + critical_exit(); pcb->pcb_flags |= PCB_NPXUSERINITDONE | PCB_NPXINITDONE; } else { - intr_restore(s); + critical_exit(); bcopy(addr, &pcb->pcb_user_save, sizeof(*addr)); if (PCB_USER_FPU(pcb)) pcb->pcb_flags |= PCB_NPXINITDONE; @@ -1062,13 +1055,12 @@ int fpu_kern_leave(struct thread *td, struct fpu_kern_ctx *ctx) { struct pcb *pcb; - register_t savecrit; pcb = td->td_pcb; - savecrit = intr_disable(); + critical_enter(); if (curthread == PCPU_GET(fpcurthread)) npxdrop(); - intr_restore(savecrit); + critical_exit(); pcb->pcb_save = ctx->prev; if (pcb->pcb_save == &pcb->pcb_user_save) { if ((pcb->pcb_flags & PCB_NPXUSERINITDONE) != 0) Modified: head/sys/pc98/pc98/machdep.c ============================================================================== --- head/sys/pc98/pc98/machdep.c Wed Jun 23 11:12:58 2010 (r209461) +++ head/sys/pc98/pc98/machdep.c Wed Jun 23 11:21:19 2010 (r209462) @@ -2719,9 +2719,8 @@ set_fpcontext(struct thread *td, const m static void fpstate_drop(struct thread *td) { - register_t s; - s = intr_disable(); + critical_enter(); #ifdef DEV_NPX if (PCPU_GET(fpcurthread) == td) npxdrop(); @@ -2737,7 +2736,7 @@ fpstate_drop(struct thread *td) * have too many layers. */ curthread->td_pcb->pcb_flags &= ~PCB_NPXINITDONE; - intr_restore(s); + critical_exit(); } int
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201006231121.o5NBLJ8M049785>