Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * syscall_wrapper.h - s390 specific wrappers to syscall definitions
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  * To keep the naming coherent, re-define SYSCALL_DEFINE0 to create an alias
0072  * named __s390x_sys_*()
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  * As some compat syscalls may not be implemented, we need to expand
0118  * COND_SYSCALL_COMPAT in kernel/sys_ni.c and COMPAT_SYS_NI in
0119  * kernel/time/posix-stubs.c to cover this case as well.
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 /* CONFIG_COMPAT */
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 /* CONFIG_COMPAT */
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 /* _ASM_S390_SYSCALL_WRAPPER_H */