Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 2 Jan 2021 19:53:32 GMT
From:      Michal Meloun <mmel@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: bd03acedb804 - main - arm: Fix atomic_testand{set, clear}_32(). According to atomic (9), the bit position argument should be a modulo operand size. While I'm in, add missing implementation of atomic_testandclear_64(). For more details see https://reviews.freebsd.org/D27886
Message-ID:  <202101021953.102JrWvW061175@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by mmel:

URL: https://cgit.FreeBSD.org/src/commit/?id=bd03acedb804add1e22178d50eb2bfb703974ddf

commit bd03acedb804add1e22178d50eb2bfb703974ddf
Author:     Michal Meloun <mmel@FreeBSD.org>
AuthorDate: 2021-01-02 19:30:00 +0000
Commit:     Michal Meloun <mmel@FreeBSD.org>
CommitDate: 2021-01-02 19:53:11 +0000

    arm: Fix atomic_testand{set,clear}_32(). According to atomic (9), the bit position argument should be a modulo operand size. While I'm in, add missing implementation of atomic_testandclear_64(). For more details see https://reviews.freebsd.org/D27886
    
    Discused with:  rlibby
    MFC after:      3 weeks
---
 sys/arm/include/atomic-v6.h | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/sys/arm/include/atomic-v6.h b/sys/arm/include/atomic-v6.h
index 38072b5b3d77..ede879cb9fa8 100644
--- a/sys/arm/include/atomic-v6.h
+++ b/sys/arm/include/atomic-v6.h
@@ -881,7 +881,7 @@ atomic_testandclear_32(volatile uint32_t *ptr, u_int bit)
 	      [oldv] "=&r"   (oldv),
 	      [newv] "=&r"   (newv)
 	    : [ptr]  "r"     (ptr),
-	             "[bit]" (bit)
+	             "[bit]" (bit & 0x1f)
 	    : "cc", "ip", "memory");
 
 	return (result);
@@ -902,6 +902,23 @@ atomic_testandclear_long(volatile u_long *p, u_int v)
 }
 #define	atomic_testandclear_long	atomic_testandclear_long
 
+
+static __inline int
+atomic_testandclear_64(volatile uint64_t *p, u_int v)
+{
+	volatile uint32_t *p32;
+
+	p32 = (volatile uint32_t *)p;
+	/*
+	 * Assume little-endian,
+	 * atomic_testandclear_32() uses only last 5 bits of v
+	 */
+	if (v >= 32) {
+		p32++;
+	}
+	return (atomic_testandclear_32(p32, v));
+}
+
 static __inline int
 atomic_testandset_32(volatile uint32_t *ptr, u_int bit)
 {
@@ -925,7 +942,7 @@ atomic_testandset_32(volatile uint32_t *ptr, u_int bit)
 	      [oldv] "=&r"   (oldv),
 	      [newv] "=&r"   (newv)
 	    : [ptr]  "r"     (ptr),
-	             "[bit]" (bit)
+	             "[bit]" (bit & 0x1f)
 	    : "cc", "ip", "memory");
 
 	return (result);
@@ -952,9 +969,11 @@ atomic_testandset_64(volatile uint64_t *p, u_int v)
 	volatile uint32_t *p32;
 
 	p32 = (volatile uint32_t *)p;
-	/* Assume little-endian */
+	/*
+	 * Assume little-endian,
+	 * atomic_testandset_32() uses only last 5 bits of v
+	 */
 	if (v >= 32) {
-		v &= 0x1f;
 		p32++;
 	}
 	return (atomic_testandset_32(p32, v));



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202101021953.102JrWvW061175>