]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix fault during arm software floating point
authorRuss Cox <rsc@golang.org>
Thu, 3 Apr 2014 19:39:48 +0000 (15:39 -0400)
committerRuss Cox <rsc@golang.org>
Thu, 3 Apr 2014 19:39:48 +0000 (15:39 -0400)
The software floating point runs with m->locks++
to avoid being preempted; recognize this case in panic
and undo it so that m->locks is maintained correctly
when panicking.

Fixes #7553.

LGTM=dvyukov
R=golang-codereviews, dvyukov
CC=golang-codereviews
https://golang.org/cl/84030043

src/pkg/runtime/panic.c
src/pkg/runtime/runtime.h
src/pkg/runtime/vlop_arm.s

index 0bf3b6a1404ade426007cbd3443bd31ee08c930c..3af8cb67aa3bf1c935133cf49ad364c3819f31f1 100644 (file)
@@ -498,7 +498,7 @@ runtime·canpanic(G *gp)
        // and not stuck in a system call.
        if(gp == nil || gp != m->curg)
                return false;
-       if(m->locks != 0 || m->mallocing != 0 || m->throwing != 0 || m->gcing != 0 || m->dying != 0)
+       if(m->locks-m->softfloat != 0 || m->mallocing != 0 || m->throwing != 0 || m->gcing != 0 || m->dying != 0)
                return false;
        if(gp->status != Grunning || gp->syscallsp != 0)
                return false;
@@ -526,6 +526,16 @@ runtime·panicstring(int8 *s)
 {
        Eface err;
 
+       // m->softfloat is set during software floating point,
+       // which might cause a fault during a memory load.
+       // It increments m->locks to avoid preemption.
+       // If we're panicking, the software floating point frames
+       // will be unwound, so decrement m->locks as they would.
+       if(m->softfloat) {
+               m->locks--;
+               m->softfloat = 0;
+       }
+
        if(m->mallocing) {
                runtime·printf("panic: %s\n", s);
                runtime·throw("panic during malloc");
@@ -534,6 +544,10 @@ runtime·panicstring(int8 *s)
                runtime·printf("panic: %s\n", s);
                runtime·throw("panic during gc");
        }
+       if(m->locks) {
+               runtime·printf("panic: %s\n", s);
+               runtime·throw("panic holding locks");
+       }
        runtime·newErrorCString(s, &err);
        runtime·panic(err);
 }
index 28c831a0684cf3b338e19a07f9a5954af187c6d9..0ba1238734f2c06c9e88916cca92d996d1dbb9a0 100644 (file)
@@ -312,6 +312,7 @@ struct      M
        int32   throwing;
        int32   gcing;
        int32   locks;
+       int32   softfloat;
        int32   dying;
        int32   profilehz;
        int32   helpgc;
index 941de3e8dbc75d3a81b1569560e8adcbdad3dbec..80f516ec4f6838da411176720f44c810dc7d6c1d 100644 (file)
@@ -75,10 +75,14 @@ TEXT _sfloat(SB), NOSPLIT, $64-0 // 4 arg + 14*4 saved regs + cpsr
        MOVW    m_locks(m), R1
        ADD     $1, R1
        MOVW    R1, m_locks(m)
+       MOVW    $1, R1
+       MOVW    R1, m_softfloat(m)
        BL      runtime·_sfloat2(SB)
        MOVW    m_locks(m), R1
        SUB     $1, R1
        MOVW    R1, m_locks(m)
+       MOVW    $0, R1
+       MOVW    R1, m_softfloat(m)
        MOVW    R0, 0(R13)
        MOVW    64(R13), R1
        WORD    $0xe128f001     // msr cpsr_f, r1