lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Sun, 01 Apr 2018 21:41:15 +0100
From:   David Howells <dhowells@...hat.com>
To:     linux-kernel@...r.kernel.org
Subject: [PATCH 10/45] C++: x86: Turn xchg(),
 xadd() & co. into inline template functions

Turn xchg(), xadd() and similar functions into inline C++ template
functions.  This produces more robust source as the all the casting the C
macros require is then unnecessary.

Signed-off-by: David Howells <dhowells@...hat.com>
---

 arch/x86/include/asm/cmpxchg.h |  109 ++++++++++++++++++++++++----------------
 1 file changed, 65 insertions(+), 44 deletions(-)

diff --git a/arch/x86/include/asm/cmpxchg.h b/arch/x86/include/asm/cmpxchg.h
index 56bd436ed01b..5e896c17476d 100644
--- a/arch/x86/include/asm/cmpxchg.h
+++ b/arch/x86/include/asm/cmpxchg.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+/* SPDX-License-Identifier: GPL-2.0 -*- c++ -*- */
 #ifndef ASM_X86_CMPXCHG_H
 #define ASM_X86_CMPXCHG_H
 
@@ -39,43 +39,73 @@ extern void __add_wrong_size(void)
  * An exchange-type operation, which takes a value and a pointer, and
  * returns the old value.
  */
-#define __xchg_op(ptr, arg, op, lock)					\
-	({								\
-	        __typeof__ (*(ptr)) __ret = (arg);			\
-		switch (sizeof(*(ptr))) {				\
-		case __X86_CASE_B:					\
-			asm volatile (lock #op "b %b0, %1\n"		\
-				      : "+q" (__ret), "+m" (*(ptr))	\
-				      : : "memory", "cc");		\
-			break;						\
-		case __X86_CASE_W:					\
-			asm volatile (lock #op "w %w0, %1\n"		\
-				      : "+r" (__ret), "+m" (*(ptr))	\
-				      : : "memory", "cc");		\
-			break;						\
-		case __X86_CASE_L:					\
-			asm volatile (lock #op "l %0, %1\n"		\
-				      : "+r" (__ret), "+m" (*(ptr))	\
-				      : : "memory", "cc");		\
-			break;						\
-		case __X86_CASE_Q:					\
-			asm volatile (lock #op "q %q0, %1\n"		\
-				      : "+r" (__ret), "+m" (*(ptr))	\
-				      : : "memory", "cc");		\
-			break;						\
-		default:						\
-			__ ## op ## _wrong_size();			\
-		}							\
-		__ret;							\
-	})
+template <typename P, typename N>
+static inline P xchg(P *ptr, N rep)
+{
+	P v = rep;
+
+	if (sizeof(P) > sizeof(unsigned long))
+		__xchg_wrong_size();
+
+	/* Note: no "lock" prefix even on SMP: xchg always implies lock anyway.
+	 * Since this is generally used to protect other memory information, we
+	 * use "asm volatile" and "memory" clobbers to prevent gcc from moving
+	 * information around.
+	 */
+	asm volatile("xchg %[v], %[ptr]"
+		     : [ptr] "+m" (*ptr),
+		       [v]   "+a" (v)
+		     :
+		     : "memory");
+
+	return v;
+}
 
 /*
- * Note: no "lock" prefix even on SMP: xchg always implies lock anyway.
- * Since this is generally used to protect other memory information, we
- * use "asm volatile" and "memory" clobbers to prevent gcc from moving
- * information around.
+ * __xadd() adds "inc" to "*ptr" and atomically returns the previous
+ * value of "*ptr".
+ *
+ * __xadd() is always locked.
  */
-#define xchg(ptr, v)	__xchg_op((ptr), (v), xchg, "")
+template <typename P, typename N>
+static inline P __xadd(P *ptr, N inc)
+{
+	P v = inc;
+
+	if (sizeof(P) > sizeof(unsigned long))
+		__xadd_wrong_size();
+
+	asm volatile("lock; xadd %[v], %[ptr]"
+		     : [ptr] "+m" (*ptr),
+		       [v]   "+a" (v)
+		     :
+		     : "memory");
+
+	return v;
+}
+
+/*
+ * xadd() adds "inc" to "*ptr" and atomically returns the previous
+ * value of "*ptr".
+ *
+ * xadd() is locked when multiple CPUs are online
+ */
+template <typename P, typename N>
+static inline P xadd(P *ptr, N inc)
+{
+	P v = inc;
+
+	if (sizeof(P) > sizeof(unsigned long))
+		__xadd_wrong_size();
+
+	asm volatile(LOCK_PREFIX "xadd %[v], %[ptr]"
+		     : [ptr] "+m" (*ptr),
+		       [v]   "+a" (v)
+		     :
+		     : "memory");
+
+	return v;
+}
 
 /*
  * Atomic compare and exchange.  Compare OLD with MEM, if identical,
@@ -224,15 +254,6 @@ extern void __add_wrong_size(void)
 #define try_cmpxchg(ptr, pold, new)					\
 	__try_cmpxchg((ptr), (pold), (new), sizeof(*(ptr)))
 
-/*
- * xadd() adds "inc" to "*ptr" and atomically returns the previous
- * value of "*ptr".
- *
- * xadd() is locked when multiple CPUs are online
- */
-#define __xadd(ptr, inc, lock)	__xchg_op((ptr), (inc), xadd, lock)
-#define xadd(ptr, inc)		__xadd((ptr), (inc), LOCK_PREFIX)
-
 #define __cmpxchg_double(pfx, p1, p2, o1, o2, n1, n2)			\
 ({									\
 	bool __ret;							\

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ