xref: /OK3568_Linux_fs/kernel/arch/s390/include/asm/syscall_wrapper.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * syscall_wrapper.h - s390 specific wrappers to syscall definitions
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #ifndef _ASM_S390_SYSCALL_WRAPPER_H
8*4882a593Smuzhiyun #define _ASM_S390_SYSCALL_WRAPPER_H
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #ifdef CONFIG_COMPAT
11*4882a593Smuzhiyun #define __SC_COMPAT_TYPE(t, a) \
12*4882a593Smuzhiyun 	__typeof(__builtin_choose_expr(sizeof(t) > 4, 0L, (t)0)) a
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #define __SC_COMPAT_CAST(t, a)						\
15*4882a593Smuzhiyun ({									\
16*4882a593Smuzhiyun 	long __ReS = a;							\
17*4882a593Smuzhiyun 									\
18*4882a593Smuzhiyun 	BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) &&		\
19*4882a593Smuzhiyun 		     !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t) &&		\
20*4882a593Smuzhiyun 		     !__TYPE_IS_LL(t));					\
21*4882a593Smuzhiyun 	if (__TYPE_IS_L(t))						\
22*4882a593Smuzhiyun 		__ReS = (s32)a;						\
23*4882a593Smuzhiyun 	if (__TYPE_IS_UL(t))						\
24*4882a593Smuzhiyun 		__ReS = (u32)a;						\
25*4882a593Smuzhiyun 	if (__TYPE_IS_PTR(t))						\
26*4882a593Smuzhiyun 		__ReS = a & 0x7fffffff;					\
27*4882a593Smuzhiyun 	if (__TYPE_IS_LL(t))						\
28*4882a593Smuzhiyun 		return -ENOSYS;						\
29*4882a593Smuzhiyun 	(t)__ReS;							\
30*4882a593Smuzhiyun })
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #define __S390_SYS_STUBx(x, name, ...)					\
33*4882a593Smuzhiyun 	asmlinkage long __s390_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__));\
34*4882a593Smuzhiyun 	ALLOW_ERROR_INJECTION(__s390_sys##name, ERRNO);			\
35*4882a593Smuzhiyun 	asmlinkage long __s390_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__))\
36*4882a593Smuzhiyun 	{								\
37*4882a593Smuzhiyun 		long ret = __s390x_sys##name(__MAP(x,__SC_COMPAT_CAST,__VA_ARGS__));\
38*4882a593Smuzhiyun 		__MAP(x,__SC_TEST,__VA_ARGS__);				\
39*4882a593Smuzhiyun 		return ret;						\
40*4882a593Smuzhiyun 	}
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun /*
43*4882a593Smuzhiyun  * To keep the naming coherent, re-define SYSCALL_DEFINE0 to create an alias
44*4882a593Smuzhiyun  * named __s390x_sys_*()
45*4882a593Smuzhiyun  */
46*4882a593Smuzhiyun #define COMPAT_SYSCALL_DEFINE0(sname)					\
47*4882a593Smuzhiyun 	SYSCALL_METADATA(_##sname, 0);					\
48*4882a593Smuzhiyun 	asmlinkage long __s390_compat_sys_##sname(void);		\
49*4882a593Smuzhiyun 	ALLOW_ERROR_INJECTION(__s390_compat_sys_##sname, ERRNO);	\
50*4882a593Smuzhiyun 	asmlinkage long __s390_compat_sys_##sname(void)
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun #define SYSCALL_DEFINE0(sname)						\
53*4882a593Smuzhiyun 	SYSCALL_METADATA(_##sname, 0);					\
54*4882a593Smuzhiyun 	asmlinkage long __s390x_sys_##sname(void);			\
55*4882a593Smuzhiyun 	ALLOW_ERROR_INJECTION(__s390x_sys_##sname, ERRNO);		\
56*4882a593Smuzhiyun 	asmlinkage long __s390_sys_##sname(void)			\
57*4882a593Smuzhiyun 		__attribute__((alias(__stringify(__s390x_sys_##sname)))); \
58*4882a593Smuzhiyun 	asmlinkage long __s390x_sys_##sname(void)
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun #define COND_SYSCALL(name)						\
61*4882a593Smuzhiyun 	cond_syscall(__s390x_sys_##name);				\
62*4882a593Smuzhiyun 	cond_syscall(__s390_sys_##name)
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun #define SYS_NI(name)							\
65*4882a593Smuzhiyun 	SYSCALL_ALIAS(__s390x_sys_##name, sys_ni_posix_timers);		\
66*4882a593Smuzhiyun 	SYSCALL_ALIAS(__s390_sys_##name, sys_ni_posix_timers)
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun #define COMPAT_SYSCALL_DEFINEx(x, name, ...)					\
69*4882a593Smuzhiyun 	__diag_push();								\
70*4882a593Smuzhiyun 	__diag_ignore(GCC, 8, "-Wattribute-alias",				\
71*4882a593Smuzhiyun 		      "Type aliasing is used to sanitize syscall arguments");\
72*4882a593Smuzhiyun 	asmlinkage long __s390_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));	\
73*4882a593Smuzhiyun 	asmlinkage long __s390_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))	\
74*4882a593Smuzhiyun 		__attribute__((alias(__stringify(__se_compat_sys##name))));	\
75*4882a593Smuzhiyun 	ALLOW_ERROR_INJECTION(__s390_compat_sys##name, ERRNO);			\
76*4882a593Smuzhiyun 	static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\
77*4882a593Smuzhiyun 	asmlinkage long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__));	\
78*4882a593Smuzhiyun 	asmlinkage long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__))	\
79*4882a593Smuzhiyun 	{									\
80*4882a593Smuzhiyun 		long ret = __do_compat_sys##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__));\
81*4882a593Smuzhiyun 		__MAP(x,__SC_TEST,__VA_ARGS__);					\
82*4882a593Smuzhiyun 		return ret;							\
83*4882a593Smuzhiyun 	}									\
84*4882a593Smuzhiyun 	__diag_pop();								\
85*4882a593Smuzhiyun 	static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun /*
88*4882a593Smuzhiyun  * As some compat syscalls may not be implemented, we need to expand
89*4882a593Smuzhiyun  * COND_SYSCALL_COMPAT in kernel/sys_ni.c and COMPAT_SYS_NI in
90*4882a593Smuzhiyun  * kernel/time/posix-stubs.c to cover this case as well.
91*4882a593Smuzhiyun  */
92*4882a593Smuzhiyun #define COND_SYSCALL_COMPAT(name)					\
93*4882a593Smuzhiyun 	cond_syscall(__s390_compat_sys_##name)
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun #define COMPAT_SYS_NI(name)						\
96*4882a593Smuzhiyun 	SYSCALL_ALIAS(__s390_compat_sys_##name, sys_ni_posix_timers)
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun #else /* CONFIG_COMPAT */
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun #define __S390_SYS_STUBx(x, fullname, name, ...)
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun #define SYSCALL_DEFINE0(sname)						\
103*4882a593Smuzhiyun 	SYSCALL_METADATA(_##sname, 0);					\
104*4882a593Smuzhiyun 	asmlinkage long __s390x_sys_##sname(void);			\
105*4882a593Smuzhiyun 	ALLOW_ERROR_INJECTION(__s390x_sys_##sname, ERRNO);		\
106*4882a593Smuzhiyun 	asmlinkage long __s390x_sys_##sname(void)
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun #define COND_SYSCALL(name)						\
109*4882a593Smuzhiyun 	cond_syscall(__s390x_sys_##name)
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun #define SYS_NI(name)							\
112*4882a593Smuzhiyun 	SYSCALL_ALIAS(__s390x_sys_##name, sys_ni_posix_timers);
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun #endif /* CONFIG_COMPAT */
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun #define __SYSCALL_DEFINEx(x, name, ...)						\
117*4882a593Smuzhiyun 	__diag_push();								\
118*4882a593Smuzhiyun 	__diag_ignore(GCC, 8, "-Wattribute-alias",				\
119*4882a593Smuzhiyun 		      "Type aliasing is used to sanitize syscall arguments");\
120*4882a593Smuzhiyun 	asmlinkage long __s390x_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))	\
121*4882a593Smuzhiyun 		__attribute__((alias(__stringify(__se_sys##name))));		\
122*4882a593Smuzhiyun 	ALLOW_ERROR_INJECTION(__s390x_sys##name, ERRNO);			\
123*4882a593Smuzhiyun 	long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__));			\
124*4882a593Smuzhiyun 	static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));	\
125*4882a593Smuzhiyun 	__S390_SYS_STUBx(x, name, __VA_ARGS__)					\
126*4882a593Smuzhiyun 	asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__))		\
127*4882a593Smuzhiyun 	{									\
128*4882a593Smuzhiyun 		long ret = __do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__));	\
129*4882a593Smuzhiyun 		__MAP(x,__SC_TEST,__VA_ARGS__);					\
130*4882a593Smuzhiyun 		return ret;							\
131*4882a593Smuzhiyun 	}									\
132*4882a593Smuzhiyun 	__diag_pop();								\
133*4882a593Smuzhiyun 	static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun #endif /* _ASM_X86_SYSCALL_WRAPPER_H */
136