arm64: Work around broken GCC 4.9 handling of "S" constraint
Marc Zyngier
maintainerPATCH 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
@@ -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
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.
Signed-off-by Marc Zyngier <[email protected]>
Quoted 33 lines
---
* From v1: Dropped the detection hack and rely onGCC_VERSIONarch/arm64/include/asm/kvm_asm.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)arch/arm64/include/asm/kvm_asm.h +7
-2@@ -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
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