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