]> Cypherpunks repositories - gostls13.git/commitdiff
runtime/internal/atomic: add early nil check on ARM
authorCherry Zhang <cherryyz@google.com>
Mon, 12 Feb 2018 22:00:01 +0000 (17:00 -0500)
committerCherry Zhang <cherryyz@google.com>
Wed, 14 Feb 2018 17:09:05 +0000 (17:09 +0000)
If nil, fault before taking the lock or calling into the kernel.

Change-Id: I013d78a5f9233c2a9197660025f679940655d384
Reviewed-on: https://go-review.googlesource.com/93636
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
src/runtime/internal/atomic/atomic_arm.go
src/runtime/internal/atomic/sys_linux_arm.s

index 72af5842b98cafa705695b2495d7331eb03187c9..b67a6b6c5a4d4a507db15125142a40eaf4dc81db 100644 (file)
@@ -109,6 +109,7 @@ func Cas64(addr *uint64, old, new uint64) bool {
        if uintptr(unsafe.Pointer(addr))&7 != 0 {
                *(*int)(nil) = 0 // crash on unaligned uint64
        }
+       _ = *addr // if nil, fault before taking the lock
        var ok bool
        addrLock(addr).lock()
        if *addr == old {
@@ -124,6 +125,7 @@ func Xadd64(addr *uint64, delta int64) uint64 {
        if uintptr(unsafe.Pointer(addr))&7 != 0 {
                *(*int)(nil) = 0 // crash on unaligned uint64
        }
+       _ = *addr // if nil, fault before taking the lock
        var r uint64
        addrLock(addr).lock()
        r = *addr + uint64(delta)
@@ -137,6 +139,7 @@ func Xchg64(addr *uint64, v uint64) uint64 {
        if uintptr(unsafe.Pointer(addr))&7 != 0 {
                *(*int)(nil) = 0 // crash on unaligned uint64
        }
+       _ = *addr // if nil, fault before taking the lock
        var r uint64
        addrLock(addr).lock()
        r = *addr
@@ -150,6 +153,7 @@ func Load64(addr *uint64) uint64 {
        if uintptr(unsafe.Pointer(addr))&7 != 0 {
                *(*int)(nil) = 0 // crash on unaligned uint64
        }
+       _ = *addr // if nil, fault before taking the lock
        var r uint64
        addrLock(addr).lock()
        r = *addr
@@ -162,6 +166,7 @@ func Store64(addr *uint64, v uint64) {
        if uintptr(unsafe.Pointer(addr))&7 != 0 {
                *(*int)(nil) = 0 // crash on unaligned uint64
        }
+       _ = *addr // if nil, fault before taking the lock
        addrLock(addr).lock()
        *addr = v
        addrLock(addr).unlock()
index f8de2a2a4162dd334928bb1e4f4389db770e35e3..6151e7c0192e3fb923fc46d7cb9a8f6107aee835 100644 (file)
@@ -11,6 +11,9 @@ TEXT cas<>(SB),NOSPLIT,$0
 
 TEXT runtime∕internal∕atomic·Cas(SB),NOSPLIT,$0
        MOVW    ptr+0(FP), R2
+       // trigger potential paging fault here,
+       // because we don't know how to traceback through __kuser_cmpxchg
+       MOVW    (R2), R0
        MOVW    old+4(FP), R0
 loop:
        MOVW    new+8(FP), R1
@@ -39,4 +42,4 @@ TEXT runtime∕internal∕atomic·Casp1(SB),NOSPLIT,$0
 // a memory barrier, but it requires writing to a coprocessor
 // register. ARMv7 introduced the DMB instruction, but it's expensive
 // even on single-core devices. The kernel helper takes care of all of
-// this for us.
\ No newline at end of file
+// this for us.