0001
0002
0003
0004
0005
0006
0007 #ifndef _ASM_S390_SYSCALL_WRAPPER_H
0008 #define _ASM_S390_SYSCALL_WRAPPER_H
0009
0010 #define __SC_TYPE(t, a) t
0011
0012 #define SYSCALL_PT_ARG6(regs, m, t1, t2, t3, t4, t5, t6)\
0013 SYSCALL_PT_ARG5(regs, m, t1, t2, t3, t4, t5), \
0014 m(t6, (regs->gprs[7]))
0015
0016 #define SYSCALL_PT_ARG5(regs, m, t1, t2, t3, t4, t5) \
0017 SYSCALL_PT_ARG4(regs, m, t1, t2, t3, t4), \
0018 m(t5, (regs->gprs[6]))
0019
0020 #define SYSCALL_PT_ARG4(regs, m, t1, t2, t3, t4) \
0021 SYSCALL_PT_ARG3(regs, m, t1, t2, t3), \
0022 m(t4, (regs->gprs[5]))
0023
0024 #define SYSCALL_PT_ARG3(regs, m, t1, t2, t3) \
0025 SYSCALL_PT_ARG2(regs, m, t1, t2), \
0026 m(t3, (regs->gprs[4]))
0027
0028 #define SYSCALL_PT_ARG2(regs, m, t1, t2) \
0029 SYSCALL_PT_ARG1(regs, m, t1), \
0030 m(t2, (regs->gprs[3]))
0031
0032 #define SYSCALL_PT_ARG1(regs, m, t1) \
0033 m(t1, (regs->orig_gpr2))
0034
0035 #define SYSCALL_PT_ARGS(x, ...) SYSCALL_PT_ARG##x(__VA_ARGS__)
0036
0037 #ifdef CONFIG_COMPAT
0038 #define __SC_COMPAT_TYPE(t, a) \
0039 __typeof(__builtin_choose_expr(sizeof(t) > 4, 0L, (t)0)) a
0040
0041 #define __SC_COMPAT_CAST(t, a) \
0042 ({ \
0043 long __ReS = a; \
0044 \
0045 BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \
0046 !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t) && \
0047 !__TYPE_IS_LL(t)); \
0048 if (__TYPE_IS_L(t)) \
0049 __ReS = (s32)a; \
0050 if (__TYPE_IS_UL(t)) \
0051 __ReS = (u32)a; \
0052 if (__TYPE_IS_PTR(t)) \
0053 __ReS = a & 0x7fffffff; \
0054 if (__TYPE_IS_LL(t)) \
0055 return -ENOSYS; \
0056 (t)__ReS; \
0057 })
0058
0059 #define __S390_SYS_STUBx(x, name, ...) \
0060 long __s390_sys##name(struct pt_regs *regs); \
0061 ALLOW_ERROR_INJECTION(__s390_sys##name, ERRNO); \
0062 long __s390_sys##name(struct pt_regs *regs) \
0063 { \
0064 long ret = __do_sys##name(SYSCALL_PT_ARGS(x, regs, \
0065 __SC_COMPAT_CAST, __MAP(x, __SC_TYPE, __VA_ARGS__))); \
0066 __MAP(x,__SC_TEST,__VA_ARGS__); \
0067 return ret; \
0068 }
0069
0070
0071
0072
0073
0074 #define COMPAT_SYSCALL_DEFINE0(sname) \
0075 SYSCALL_METADATA(_##sname, 0); \
0076 long __s390_compat_sys_##sname(void); \
0077 ALLOW_ERROR_INJECTION(__s390_compat_sys_##sname, ERRNO); \
0078 long __s390_compat_sys_##sname(void)
0079
0080 #define SYSCALL_DEFINE0(sname) \
0081 SYSCALL_METADATA(_##sname, 0); \
0082 long __s390x_sys_##sname(void); \
0083 ALLOW_ERROR_INJECTION(__s390x_sys_##sname, ERRNO); \
0084 long __s390_sys_##sname(void) \
0085 __attribute__((alias(__stringify(__s390x_sys_##sname)))); \
0086 long __s390x_sys_##sname(void)
0087
0088 #define COND_SYSCALL(name) \
0089 cond_syscall(__s390x_sys_##name); \
0090 cond_syscall(__s390_sys_##name)
0091
0092 #define SYS_NI(name) \
0093 SYSCALL_ALIAS(__s390x_sys_##name, sys_ni_posix_timers); \
0094 SYSCALL_ALIAS(__s390_sys_##name, sys_ni_posix_timers)
0095
0096 #define COMPAT_SYSCALL_DEFINEx(x, name, ...) \
0097 __diag_push(); \
0098 __diag_ignore(GCC, 8, "-Wattribute-alias", \
0099 "Type aliasing is used to sanitize syscall arguments"); \
0100 long __s390_compat_sys##name(struct pt_regs *regs); \
0101 long __s390_compat_sys##name(struct pt_regs *regs) \
0102 __attribute__((alias(__stringify(__se_compat_sys##name)))); \
0103 ALLOW_ERROR_INJECTION(__s390_compat_sys##name, ERRNO); \
0104 static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \
0105 long __se_compat_sys##name(struct pt_regs *regs); \
0106 long __se_compat_sys##name(struct pt_regs *regs) \
0107 { \
0108 long ret = __do_compat_sys##name(SYSCALL_PT_ARGS(x, regs, __SC_DELOUSE, \
0109 __MAP(x, __SC_TYPE, __VA_ARGS__))); \
0110 __MAP(x,__SC_TEST,__VA_ARGS__); \
0111 return ret; \
0112 } \
0113 __diag_pop(); \
0114 static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
0115
0116
0117
0118
0119
0120
0121 #define COND_SYSCALL_COMPAT(name) \
0122 cond_syscall(__s390_compat_sys_##name)
0123
0124 #define COMPAT_SYS_NI(name) \
0125 SYSCALL_ALIAS(__s390_compat_sys_##name, sys_ni_posix_timers)
0126
0127 #else
0128
0129 #define __S390_SYS_STUBx(x, fullname, name, ...)
0130
0131 #define SYSCALL_DEFINE0(sname) \
0132 SYSCALL_METADATA(_##sname, 0); \
0133 long __s390x_sys_##sname(void); \
0134 ALLOW_ERROR_INJECTION(__s390x_sys_##sname, ERRNO); \
0135 long __s390x_sys_##sname(void)
0136
0137 #define COND_SYSCALL(name) \
0138 cond_syscall(__s390x_sys_##name)
0139
0140 #define SYS_NI(name) \
0141 SYSCALL_ALIAS(__s390x_sys_##name, sys_ni_posix_timers);
0142
0143 #endif
0144
0145 #define __SYSCALL_DEFINEx(x, name, ...) \
0146 __diag_push(); \
0147 __diag_ignore(GCC, 8, "-Wattribute-alias", \
0148 "Type aliasing is used to sanitize syscall arguments"); \
0149 long __s390x_sys##name(struct pt_regs *regs) \
0150 __attribute__((alias(__stringify(__se_sys##name)))); \
0151 ALLOW_ERROR_INJECTION(__s390x_sys##name, ERRNO); \
0152 static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \
0153 long __se_sys##name(struct pt_regs *regs); \
0154 __S390_SYS_STUBx(x, name, __VA_ARGS__) \
0155 long __se_sys##name(struct pt_regs *regs) \
0156 { \
0157 long ret = __do_sys##name(SYSCALL_PT_ARGS(x, regs, \
0158 __SC_CAST, __MAP(x, __SC_TYPE, __VA_ARGS__))); \
0159 __MAP(x,__SC_TEST,__VA_ARGS__); \
0160 return ret; \
0161 } \
0162 __diag_pop(); \
0163 static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
0164
0165 #endif