Skip to contentSkip to conversation

arm64: Work around broken GCC 4.9 handling of "S" constraint

PATCH Applied Marc Zyngier 3 participants 3 messages Dec 17, 2020

Subsystems (2)
lore
Share & tools
lore

Marc Zyngier

author maintainer
#0 lore raw

PATCH 1/1 arm64: Work around broken GCC 4.9 handling of "S" constraint

GCC 4.9 seems to have a problem with the "S" asm constraint when the symbol lives in the same compilation unit, and pretends the constraint is impossible:

$ cat x.c
void *foo(void)
{
	static int x;
	int *addr;
	asm("adrp %0, %1" : "=r" (addr) : "S" (&x));
	return addr;
}
$ ~/Work/gcc-linaro-aarch64-linux-gnu-4.9-2014.09_linux/bin/aarch64-linux-gnu-gcc -S -x c -O2 x.c
x.c: In function ‘foo’:
x.c:5:2: error: impossible constraint in ‘asm’
  asm("adrp %0, %1" : "=r" (addr) : "S" (&x));
  ^

Boo. Following revisions of the compiler work just fine, though.

We can fallback to the "i" constraint for GCC version prior to 5.0, which *seems* to do the right thing. Hopefully we will be able to remove this at some point, but in the meantime this gets us going.

---
* From v1: Dropped the detection hack and rely on GCC_VERSION

 arch/arm64/include/asm/kvm_asm.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
arch/arm64/include/asm/kvm_asm.h +7 -1
index 7ccf770c53d9..8a33d83ea843 100644
@@ -199,6 +199,12 @@ extern void __vgic_v3_init_lrs(void);
 
 extern u32 __kvm_get_mdcr_el2(void);
 
+#if defined(GCC_VERSION) && GCC_VERSION < 50000
+#define SYM_CONSTRAINT	"i"
+#else
+#define SYM_CONSTRAINT	"S"
+#endif
+
 /*
  * Obtain the PC-relative address of a kernel symbol
  * s: symbol
@@ -215,7 +221,7 @@ extern u32 __kvm_get_mdcr_el2(void);
 		typeof(s) *addr;					\
 		asm("adrp	%0, %1\n"				\
 		    "add	%0, %0, :lo12:%1\n"			\
-		    : "=r" (addr) : "S" (&s));				\
+		    : "=r" (addr) : SYM_CONSTRAINT (&s));		\
 		addr;							\
 	})
 
Signature · 6 lines
2.29.2

_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Acked-by on v1 1/1
#1 lore raw
Quoted 20 lines · Marc Zyngier

GCC 4.9 seems to have a problem with the "S" asm constraint when the symbol lives in the same compilation unit, and pretends the constraint is impossible:

$ cat x.c
void *foo(void)
{
        static int x;
        int *addr;
        asm("adrp %0, %1" : "=r" (addr) : "S" (&x));
        return addr;
}
$ ~/Work/gcc-linaro-aarch64-linux-gnu-4.9-2014.09_linux/bin/aarch64-linux-gnu-gcc -S -x c -O2 x.c
x.c: In function ‘foo’:
x.c:5:2: error: impossible constraint in ‘asm’
  asm("adrp %0, %1" : "=r" (addr) : "S" (&x));
  ^
Quoted 7 lines

Boo. Following revisions of the compiler work just fine, though.

We can fallback to the "i" constraint for GCC version prior to 5.0, which *seems* to do the right thing. Hopefully we will be able to remove this at some point, but in the meantime this gets us going.

Quoted 33 lines

---
* From v1: Dropped the detection hack and rely on GCC_VERSION

 arch/arm64/include/asm/kvm_asm.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
arch/arm64/include/asm/kvm_asm.h +7 -2
index 7ccf770c53d9..8a33d83ea843 100644
@@ -199,6 +199,12 @@ extern void __vgic_v3_init_lrs(void);
 
 extern u32 __kvm_get_mdcr_el2(void);
 
+#if defined(GCC_VERSION) && GCC_VERSION < 50000
+#define SYM_CONSTRAINT "i"
+#else
+#define SYM_CONSTRAINT "S"
+#endif
+
 /*
  * Obtain the PC-relative address of a kernel symbol
  * s: symbol
@@ -215,7 +221,7 @@ extern u32 __kvm_get_mdcr_el2(void);
                typeof(s) *addr;                                        \
                asm("adrp       %0, %1\n"                               \
                    "add        %0, %0, :lo12:%1\n"                     \
-                   : "=r" (addr) : "S" (&s));                          \
+                   : "=r" (addr) : SYM_CONSTRAINT (&s));               \
                addr;                                                   \
        })
 
--
Quoted 2 lines

2.29.2

_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

maintainer Applied
#2 lore raw
In reply to Marc Zyngier
Quoted 13 lines · Marc Zyngier

GCC 4.9 seems to have a problem with the "S" asm constraint when the symbol lives in the same compilation unit, and pretends the constraint is impossible:

$ cat x.c
void *foo(void)
{
	static int x;
	int *addr;
	asm("adrp %0, %1" : "=r" (addr) : "S" (&x));
	return addr;
}
Quoted 1 line

[...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: Work around broken GCC 4.9 handling of "S" constraint

      https://git.kernel.org/arm64/c/9fd339a45be5
Signature · 6 lines
Catalin

_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm