diff options
author | ian <ian@FreeBSD.org> | 2014-03-09 14:24:05 +0000 |
---|---|---|
committer | ian <ian@FreeBSD.org> | 2014-03-09 14:24:05 +0000 |
commit | 5b807dd0fd3fad9945eb48c0f326fba5f4d32dc6 (patch) | |
tree | a4bfe346436c1c9dd53e41dc88498129102fcfac /sys/arm | |
parent | c594471e9600f3c3730f90170396dd770d6120f3 (diff) | |
download | FreeBSD-src-5b807dd0fd3fad9945eb48c0f326fba5f4d32dc6.zip FreeBSD-src-5b807dd0fd3fad9945eb48c0f326fba5f4d32dc6.tar.gz |
Always call vfp_discard() on thread death, not just when the VFP is
enabled. In vfp_discard(), if the state in the VFP hardware belongs to
the thread which is dying, NULL out pcpu fpcurthread to indicate the
state currently in the hardware belongs to nobody.
Submitted by: Juergen Weiss
Pointy hat to: me
Diffstat (limited to 'sys/arm')
-rw-r--r-- | sys/arm/arm/swtch.S | 9 | ||||
-rw-r--r-- | sys/arm/arm/vfp.c | 18 | ||||
-rw-r--r-- | sys/arm/include/vfp.h | 2 |
3 files changed, 14 insertions, 15 deletions
diff --git a/sys/arm/arm/swtch.S b/sys/arm/arm/swtch.S index 2703b03..d704823 100644 --- a/sys/arm/arm/swtch.S +++ b/sys/arm/arm/swtch.S @@ -124,14 +124,11 @@ ENTRY(cpu_throw) * r5 = newtd */ - GET_PCPU(r7, r9) - -#ifdef VFP - fmrx r0, fpexc /* This thread is dying, if the VFP */ - tst r0, #(VFPEXC_EN) /* is enabled, go shut it down */ - blne _C_LABEL(vfp_discard) /* without preserving its state. */ +#ifdef VFP /* This thread is dying, disable */ + bl _C_LABEL(vfp_discard) /* VFP without preserving state. */ #endif + GET_PCPU(r7, r9) ldr r7, [r5, #(TD_PCB)] /* r7 = new thread's PCB */ /* Switch to lwp0 context */ diff --git a/sys/arm/arm/vfp.c b/sys/arm/arm/vfp.c index d370da4..240ede3 100644 --- a/sys/arm/arm/vfp.c +++ b/sys/arm/arm/vfp.c @@ -229,21 +229,23 @@ vfp_store(struct vfp_state *vfpsave, boolean_t disable_vfp) } /* - * If the VFP hardware is on, the current thread was using it but now that - * thread is dying. Turn off the VFP and set pcpu fpcurthread to 0, to indicate - * that the VFP hardware state does not belong to any thread. Called only from - * cpu_throw(), so we don't have to worry about a context switch here. + * The current thread is dying. If the state currently in the hardware belongs + * to the current thread, set fpcurthread to NULL to indicate that the VFP + * hardware state does not belong to any thread. If the VFP is on, turn it off. + * Called only from cpu_throw(), so we don't have to worry about a context + * switch here. */ void -vfp_discard() +vfp_discard(struct thread *td) { u_int tmp; + if (PCPU_GET(fpcurthread) == td) + PCPU_SET(fpcurthread, NULL); + tmp = fmrx(VFPEXC); - if (tmp & VFPEXC_EN) { + if (tmp & VFPEXC_EN) fmxr(VFPEXC, tmp & ~VFPEXC_EN); - PCPU_SET(fpcurthread, 0); - } } #endif diff --git a/sys/arm/include/vfp.h b/sys/arm/include/vfp.h index 9023821..befba18 100644 --- a/sys/arm/include/vfp.h +++ b/sys/arm/include/vfp.h @@ -129,7 +129,7 @@ #ifndef LOCORE void vfp_init(void); void vfp_store(struct vfp_state *, boolean_t); -void vfp_discard(void); +void vfp_discard(struct thread *); #endif #endif |