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>] [day] [month] [year] [list]
Message-Id: <20180209161833.4605-1-dwmw2@infradead.org>
Date:   Fri,  9 Feb 2018 16:18:33 +0000
From:   David Woodhouse <dwmw2@...radead.org>
To:     x86@...nel.org, linux-kernel@...r.kernel.org,
        llvm-dev@...ts.llvm.org, llvmlinux@...ts.linuxfoundation.org,
        bp@...en8.de
Subject: [RFC HACK] Make clang hate percpu.h less in 32-bit mode

Neither clang nor GCC like this very much with -m32:

	long long ret;
	asm ("movb $5, %0" : "=q" (ret));

However, GCC can tolerate this variant:

	long long ret;
	switch (sizeof(ret)) {
	case 1:
		asm ("movb $5, %0" : "=q" (ret));
	case 8:
		;
	}

Clang, on the other hand, won't accept that because it validates the 
inline asm for the '1' case *before* the optimisation phase where it 
realises that it wouldn't have to emit it anyway.

This patch puts some casts in to make clang less unhappy. I don't like
it very much.

Note that we don't have the same problem for the "=r" case, where a 
64-bit value *also* doesn't fit. This is because even if it *does* have 
to emit it, clang will happily and silently do so even though it's 
clearly bogus:

	long long ret;
	asm ("movl $5, %0" : "=r" (ret));

 $ clang -c -o q.o q.c -m32
 $ gcc -c -o q.o q.c -m32
q.c: In function ‘foo’:
q.c:6:1: warning: unsupported size for integer register


---

 arch/x86/include/asm/percpu.h | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index ba3c523aaf16..3b0e413670e4 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -99,7 +99,7 @@ do {							\
 	case 1:						\
 		asm(op "b %1,"__percpu_arg(0)		\
 		    : "+m" (var)			\
-		    : "qi" ((pto_T__)(val)));		\
+		    : "qi" ((unsigned char)(unsigned long)(val))); \
 		break;					\
 	case 2:						\
 		asm(op "w %1,"__percpu_arg(0)		\
@@ -144,7 +144,7 @@ do {									\
 		else							\
 			asm("addb %1, "__percpu_arg(0)			\
 			    : "+m" (var)				\
-			    : "qi" ((pao_T__)(val)));			\
+			    : "qi" ((unsigned char)(unsigned long)(val))); \
 		break;							\
 	case 2:								\
 		if (pao_ID__ == 1)					\
@@ -182,12 +182,14 @@ do {									\
 
 #define percpu_from_op(op, var)				\
 ({							\
+	unsigned char pfo_u8__;				\
 	typeof(var) pfo_ret__;				\
 	switch (sizeof(var)) {				\
 	case 1:						\
 		asm(op "b "__percpu_arg(1)",%0"		\
-		    : "=q" (pfo_ret__)			\
+		    : "=q" (pfo_u8__)			\
 		    : "m" (var));			\
+		pfo_ret__ = (typeof(var))(unsigned long)pfo_u8__;	\
 		break;					\
 	case 2:						\
 		asm(op "w "__percpu_arg(1)",%0"		\
@@ -211,12 +213,14 @@ do {									\
 
 #define percpu_stable_op(op, var)			\
 ({							\
+	unsigned char pfo_u8__;				\
 	typeof(var) pfo_ret__;				\
 	switch (sizeof(var)) {				\
 	case 1:						\
 		asm(op "b "__percpu_arg(P1)",%0"	\
-		    : "=q" (pfo_ret__)			\
+		    : "=q" (pfo_u8__)			\
 		    : "p" (&(var)));			\
+		pfo_ret__ = (typeof(var))(unsigned long)pfo_u8__;	\
 		break;					\
 	case 2:						\
 		asm(op "w "__percpu_arg(P1)",%0"	\
-- 
2.14.3

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ