From: Jan Kiszka <jan.kis...@siemens.com> Converting them into inline functions helps to avoid clobbering of w8. Without this, the compiler may squeeze function calls between the setup of __scno in w8 and the actually submission of the syscall. Seen with the smokey y2038 testcase.
Signed-off-by: Jan Kiszka <jan.kis...@siemens.com> --- Close to an out-of-line version, possibly even better. I'm not sure, though, if that pattern buys us anything on 32-bit arm. Problem there remains the usage conflict of r7 which static inline may not resolve. .../arch/arm64/include/asm/xenomai/syscall.h | 115 ++++++++++-------- 1 file changed, 61 insertions(+), 54 deletions(-) diff --git a/lib/cobalt/arch/arm64/include/asm/xenomai/syscall.h b/lib/cobalt/arch/arm64/include/asm/xenomai/syscall.h index d2dfda6846..d896977125 100644 --- a/lib/cobalt/arch/arm64/include/asm/xenomai/syscall.h +++ b/lib/cobalt/arch/arm64/include/asm/xenomai/syscall.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2015 Philippe Gerum <r...@xenomai.org>. + * Copyright (C) Siemens AG, 2021 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,76 +23,82 @@ #include <errno.h> #include <cobalt/uapi/syscall.h> -#define __emit_asmdecl0 \ - register unsigned int __scno __asm__ ("w8"); \ - register unsigned long __res __asm__ ("x0") -#define __emit_asmdecl1 \ - __emit_asmdecl0; register unsigned long __x0 __asm__ ("x0") -#define __emit_asmdecl2 \ - __emit_asmdecl1; register unsigned long __x1 __asm__ ("x1") -#define __emit_asmdecl3 \ - __emit_asmdecl2; register unsigned long __x2 __asm__ ("x2") -#define __emit_asmdecl4 \ - __emit_asmdecl3; register unsigned long __x3 __asm__ ("x3") -#define __emit_asmdecl5 \ - __emit_asmdecl4; register unsigned long __x4 __asm__ ("x4") - -#define __load_asminput0(__op) \ - __scno = (unsigned int)__xn_syscode(__op) -#define __load_asminput1(__op, __a1) \ - __load_asminput0(__op); \ - __x0 = (unsigned long)(__a1) -#define __load_asminput2(__op, __a1, __a2) \ - __load_asminput1(__op, __a1); \ - __x1 = (unsigned long)(__a2) -#define __load_asminput3(__op, __a1, __a2, __a3) \ - __load_asminput2(__op, __a1, __a2); \ - __x2 = (unsigned long)(__a3) -#define __load_asminput4(__op, __a1, __a2, __a3, __a4) \ - __load_asminput3(__op, __a1, __a2, __a3); \ - __x3 = (unsigned long)(__a4) -#define __load_asminput5(__op, __a1, __a2, __a3, __a4, __a5) \ - __load_asminput4(__op, __a1, __a2, __a3, __a4); \ - __x4 = (unsigned long)(__a5) +#define __xn_syscall_args0 +#define __xn_syscall_args1 , unsigned long __a1 +#define __xn_syscall_args2 __xn_syscall_args1, unsigned long __a2 +#define __xn_syscall_args3 __xn_syscall_args2, unsigned long __a3 +#define __xn_syscall_args4 __xn_syscall_args3, unsigned long __a4 +#define __xn_syscall_args5 __xn_syscall_args4, unsigned long __a5 #define __emit_syscall0(__args...) \ + register unsigned int __scno __asm__("w8") = __xn_syscode(__op); \ + register unsigned long __res __asm__("x0"); \ __asm__ __volatile__ ( \ "svc 0;\n\t" \ : "=r" (__res) \ : "r" (__scno), ##__args \ : "cc", "memory"); \ - __res -#define __emit_syscall1(__a1, __args...) \ + return __res +#define __emit_syscall1(__args...) \ + register unsigned long __x0 __asm__("x0") = __a1; \ __emit_syscall0("r" (__x0), ##__args) -#define __emit_syscall2(__a1, __a2, __args...) \ - __emit_syscall1(__a1, "r" (__x1), ##__args) -#define __emit_syscall3(__a1, __a2, __a3, __args...) \ - __emit_syscall2(__a1, __a2, "r" (__x2), ##__args) -#define __emit_syscall4(__a1, __a2, __a3, __a4, __args...) \ - __emit_syscall3(__a1, __a2, __a3, "r" (__x3), ##__args) -#define __emit_syscall5(__a1, __a2, __a3, __a4, __a5, __args...) \ - __emit_syscall4(__a1, __a2, __a3, __a4, "r" (__x4), ##__args) +#define __emit_syscall2(__args...) \ + register unsigned long __x1 __asm__("x1") = __a2; \ + __emit_syscall1("r" (__x1), ##__args) +#define __emit_syscall3(__args...) \ + register unsigned long __x2 __asm__("x2") = __a3; \ + __emit_syscall2("r" (__x2), ##__args) +#define __emit_syscall4(__args...) \ + register unsigned long __x3 __asm__("x3") = __a4; \ + __emit_syscall3("r" (__x3), ##__args) +#define __emit_syscall5(__args...) \ + register unsigned long __x4 __asm__("x4") = __a5; \ + __emit_syscall4("r" (__x4), ##__args) + +#define DEFINE_XENOMAI_SYSCALL(__argnr) \ +static inline long __attribute__((always_inline)) \ +__xenomai_do_syscall##__argnr(unsigned int __op \ + __xn_syscall_args##__argnr) \ +{ \ + __emit_syscall##__argnr(); \ +} -#define XENOMAI_DO_SYSCALL(__argnr, __op, __args...) \ - ({ \ - __emit_asmdecl##__argnr; \ - __load_asminput##__argnr(__op, ##__args); \ - __emit_syscall##__argnr(__args); \ - }) +DEFINE_XENOMAI_SYSCALL(0) +DEFINE_XENOMAI_SYSCALL(1) +DEFINE_XENOMAI_SYSCALL(2) +DEFINE_XENOMAI_SYSCALL(3) +DEFINE_XENOMAI_SYSCALL(4) +DEFINE_XENOMAI_SYSCALL(5) #define XENOMAI_SYSCALL0(__op) \ - XENOMAI_DO_SYSCALL(0, __op) + __xenomai_do_syscall0(__op) #define XENOMAI_SYSCALL1(__op, __a1) \ - XENOMAI_DO_SYSCALL(1, __op, __a1) + __xenomai_do_syscall1(__op, \ + (unsigned long)__a1) #define XENOMAI_SYSCALL2(__op, __a1, __a2) \ - XENOMAI_DO_SYSCALL(2, __op, __a1, __a2) + __xenomai_do_syscall2(__op, \ + (unsigned long)__a1, \ + (unsigned long)__a2) #define XENOMAI_SYSCALL3(__op, __a1, __a2, __a3) \ - XENOMAI_DO_SYSCALL(3, __op, __a1, __a2, __a3) + __xenomai_do_syscall3(__op, \ + (unsigned long)__a1, \ + (unsigned long)__a2, \ + (unsigned long)__a3) #define XENOMAI_SYSCALL4(__op, __a1, __a2, __a3, __a4) \ - XENOMAI_DO_SYSCALL(4, __op, __a1, __a2, __a3, __a4) + __xenomai_do_syscall4(__op, \ + (unsigned long)__a1, \ + (unsigned long)__a2, \ + (unsigned long)__a3, \ + (unsigned long)__a4) #define XENOMAI_SYSCALL5(__op, __a1, __a2, __a3, __a4, __a5) \ - XENOMAI_DO_SYSCALL(5, __op, __a1, __a2, __a3, __a4, __a5) + __xenomai_do_syscall5(__op, \ + (unsigned long)__a1, \ + (unsigned long)__a2, \ + (unsigned long)__a3, \ + (unsigned long)__a4, \ + (unsigned long)__a5) #define XENOMAI_SYSBIND(__breq) \ - XENOMAI_DO_SYSCALL(1, sc_cobalt_bind, __breq) + __xenomai_do_syscall1(sc_cobalt_bind, \ + (unsigned long)__breq) #endif /* !_LIB_COBALT_ARM64_SYSCALL_H */ -- 2.31.1