]>
Commit | Line | Data |
---|---|---|
aa0d6e70 AB |
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 | ||
2213d44e HC |
10 | /* Mapping of registers to parameters for syscalls */ |
11 | #define SC_S390_REGS_TO_ARGS(x, ...) \ | |
12 | __MAP(x, __SC_ARGS \ | |
13 | ,, regs->orig_gpr2,, regs->gprs[3],, regs->gprs[4] \ | |
14 | ,, regs->gprs[5],, regs->gprs[6],, regs->gprs[7]) | |
3a790cc1 | 15 | |
aa0d6e70 | 16 | #ifdef CONFIG_COMPAT |
aa0d6e70 AB |
17 | |
18 | #define __SC_COMPAT_CAST(t, a) \ | |
19 | ({ \ | |
20 | long __ReS = a; \ | |
21 | \ | |
22 | BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \ | |
23 | !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t) && \ | |
24 | !__TYPE_IS_LL(t)); \ | |
25 | if (__TYPE_IS_L(t)) \ | |
26 | __ReS = (s32)a; \ | |
27 | if (__TYPE_IS_UL(t)) \ | |
28 | __ReS = (u32)a; \ | |
29 | if (__TYPE_IS_PTR(t)) \ | |
30 | __ReS = a & 0x7fffffff; \ | |
31 | if (__TYPE_IS_LL(t)) \ | |
32 | return -ENOSYS; \ | |
33 | (t)__ReS; \ | |
34 | }) | |
35 | ||
aa0d6e70 AB |
36 | /* |
37 | * To keep the naming coherent, re-define SYSCALL_DEFINE0 to create an alias | |
38 | * named __s390x_sys_*() | |
39 | */ | |
40 | #define COMPAT_SYSCALL_DEFINE0(sname) \ | |
39589ada | 41 | long __s390_compat_sys_##sname(void); \ |
73d6eb48 | 42 | ALLOW_ERROR_INJECTION(__s390_compat_sys_##sname, ERRNO); \ |
39589ada | 43 | long __s390_compat_sys_##sname(void) |
aa0d6e70 AB |
44 | |
45 | #define SYSCALL_DEFINE0(sname) \ | |
46 | SYSCALL_METADATA(_##sname, 0); \ | |
2213d44e HC |
47 | long __s390_sys_##sname(void); \ |
48 | ALLOW_ERROR_INJECTION(__s390_sys_##sname, ERRNO); \ | |
39589ada | 49 | long __s390x_sys_##sname(void); \ |
aa0d6e70 | 50 | ALLOW_ERROR_INJECTION(__s390x_sys_##sname, ERRNO); \ |
2213d44e | 51 | static inline long __do_sys_##sname(void); \ |
39589ada | 52 | long __s390_sys_##sname(void) \ |
2213d44e HC |
53 | { \ |
54 | return __do_sys_##sname(); \ | |
55 | } \ | |
56 | long __s390x_sys_##sname(void) \ | |
57 | { \ | |
58 | return __do_sys_##sname(); \ | |
59 | } \ | |
60 | static inline long __do_sys_##sname(void) | |
aa0d6e70 AB |
61 | |
62 | #define COND_SYSCALL(name) \ | |
63 | cond_syscall(__s390x_sys_##name); \ | |
64 | cond_syscall(__s390_sys_##name) | |
65 | ||
3a790cc1 | 66 | #define COMPAT_SYSCALL_DEFINEx(x, name, ...) \ |
3a790cc1 | 67 | long __s390_compat_sys##name(struct pt_regs *regs); \ |
3a790cc1 | 68 | ALLOW_ERROR_INJECTION(__s390_compat_sys##name, ERRNO); \ |
2213d44e HC |
69 | static inline long __se_compat_sys##name(__MAP(x, __SC_LONG, __VA_ARGS__)); \ |
70 | static inline long __do_compat_sys##name(__MAP(x, __SC_DECL, __VA_ARGS__)); \ | |
71 | long __s390_compat_sys##name(struct pt_regs *regs) \ | |
72 | { \ | |
73 | return __se_compat_sys##name(SC_S390_REGS_TO_ARGS(x, __VA_ARGS__)); \ | |
74 | } \ | |
75 | static inline long __se_compat_sys##name(__MAP(x, __SC_LONG, __VA_ARGS__)) \ | |
3a790cc1 | 76 | { \ |
2213d44e HC |
77 | __MAP(x, __SC_TEST, __VA_ARGS__); \ |
78 | return __do_compat_sys##name(__MAP(x, __SC_DELOUSE, __VA_ARGS__)); \ | |
3a790cc1 | 79 | } \ |
2213d44e | 80 | static inline long __do_compat_sys##name(__MAP(x, __SC_DECL, __VA_ARGS__)) |
aa0d6e70 AB |
81 | |
82 | /* | |
83 | * As some compat syscalls may not be implemented, we need to expand | |
a4aebe93 | 84 | * COND_SYSCALL_COMPAT in kernel/sys_ni.c to cover this case as well. |
aa0d6e70 AB |
85 | */ |
86 | #define COND_SYSCALL_COMPAT(name) \ | |
87 | cond_syscall(__s390_compat_sys_##name) | |
88 | ||
2e4532d4 HC |
89 | #define __S390_SYS_STUBx(x, name, ...) \ |
90 | long __s390_sys##name(struct pt_regs *regs); \ | |
91 | ALLOW_ERROR_INJECTION(__s390_sys##name, ERRNO); \ | |
2213d44e | 92 | static inline long ___se_sys##name(__MAP(x, __SC_LONG, __VA_ARGS__)); \ |
2e4532d4 HC |
93 | long __s390_sys##name(struct pt_regs *regs) \ |
94 | { \ | |
2213d44e HC |
95 | return ___se_sys##name(SC_S390_REGS_TO_ARGS(x, __VA_ARGS__)); \ |
96 | } \ | |
97 | static inline long ___se_sys##name(__MAP(x, __SC_LONG, __VA_ARGS__)) \ | |
98 | { \ | |
99 | __MAP(x, __SC_TEST, __VA_ARGS__); \ | |
100 | return __do_sys##name(__MAP(x, __SC_COMPAT_CAST, __VA_ARGS__)); \ | |
2e4532d4 | 101 | } |
aa0d6e70 | 102 | |
2e4532d4 | 103 | #else /* CONFIG_COMPAT */ |
aa0d6e70 AB |
104 | |
105 | #define SYSCALL_DEFINE0(sname) \ | |
106 | SYSCALL_METADATA(_##sname, 0); \ | |
39589ada | 107 | long __s390x_sys_##sname(void); \ |
aa0d6e70 | 108 | ALLOW_ERROR_INJECTION(__s390x_sys_##sname, ERRNO); \ |
2213d44e HC |
109 | static inline long __do_sys_##sname(void); \ |
110 | long __s390x_sys_##sname(void) \ | |
111 | { \ | |
112 | return __do_sys_##sname(); \ | |
113 | } \ | |
114 | static inline long __do_sys_##sname(void) | |
aa0d6e70 AB |
115 | |
116 | #define COND_SYSCALL(name) \ | |
117 | cond_syscall(__s390x_sys_##name) | |
118 | ||
2e4532d4 HC |
119 | #define __S390_SYS_STUBx(x, fullname, name, ...) |
120 | ||
aa0d6e70 AB |
121 | #endif /* CONFIG_COMPAT */ |
122 | ||
2213d44e HC |
123 | #define __SYSCALL_DEFINEx(x, name, ...) \ |
124 | long __s390x_sys##name(struct pt_regs *regs); \ | |
125 | ALLOW_ERROR_INJECTION(__s390x_sys##name, ERRNO); \ | |
126 | static inline long __se_sys##name(__MAP(x, __SC_LONG, __VA_ARGS__)); \ | |
127 | static inline long __do_sys##name(__MAP(x, __SC_DECL, __VA_ARGS__)); \ | |
128 | __S390_SYS_STUBx(x, name, __VA_ARGS__); \ | |
129 | long __s390x_sys##name(struct pt_regs *regs) \ | |
130 | { \ | |
131 | return __se_sys##name(SC_S390_REGS_TO_ARGS(x, __VA_ARGS__)); \ | |
132 | } \ | |
133 | static inline long __se_sys##name(__MAP(x, __SC_LONG, __VA_ARGS__)) \ | |
134 | { \ | |
135 | __MAP(x, __SC_TEST, __VA_ARGS__); \ | |
136 | return __do_sys##name(__MAP(x, __SC_CAST, __VA_ARGS__)); \ | |
137 | } \ | |
138 | static inline long __do_sys##name(__MAP(x, __SC_DECL, __VA_ARGS__)) | |
aa0d6e70 | 139 | |
6ffbeb3f | 140 | #endif /* _ASM_S390_SYSCALL_WRAPPER_H */ |