| 1 |
|
| 2 | |
| 3 | * syscall_wrapper.h - riscv specific wrappers to syscall definitions
|
| 4 | *
|
| 5 | * Based on arch/arm64/include/syscall_wrapper.h
|
| 6 |
|
| 7 |
|
| 8 | #ifndef __ASM_SYSCALL_WRAPPER_H
|
| 9 | #define __ASM_SYSCALL_WRAPPER_H
|
| 10 |
|
| 11 | #include <asm/ptrace.h>
|
| 12 |
|
| 13 | asmlinkage long __riscv_sys_ni_syscall(const struct pt_regs *);
|
| 14 |
|
| 15 | #ifdef CONFIG_64BIT
|
| 16 |
|
| 17 | #define __SYSCALL_SE_DEFINEx(x, prefix, name, ...) \
|
| 18 | static long __se_##prefix##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \
|
| 19 | static long __se_##prefix##name(__MAP(x,__SC_LONG,__VA_ARGS__))
|
| 20 |
|
| 21 | #define SC_RISCV_REGS_TO_ARGS(x, ...) \
|
| 22 | __MAP(x,__SC_ARGS \
|
| 23 | ,,regs->orig_a0,,regs->a1,,regs->a2 \
|
| 24 | ,,regs->a3,,regs->a4,,regs->a5,,regs->a6)
|
| 25 |
|
| 26 | #else
|
| 27 | |
| 28 | * Use type aliasing to ensure registers a0-a6 are correctly passed to the syscall
|
| 29 | * implementation when >word-size arguments are used.
|
| 30 |
|
| 31 | #define __SYSCALL_SE_DEFINEx(x, prefix, name, ...) \
|
| 32 | __diag_push(); \
|
| 33 | __diag_ignore(GCC, 8, "-Wattribute-alias", \
|
| 34 | "Type aliasing is used to sanitize syscall arguments"); \
|
| 35 | __diag_ignore(clang, 23, "-Wunknown-warning-option", \
|
| 36 | "Avoid breaking versions without -Wattribute-alias"); \
|
| 37 | __diag_ignore(clang, 23, "-Wattribute-alias", \
|
| 38 | "Type aliasing is used to sanitize syscall arguments"); \
|
| 39 | static long __se_##prefix##name(ulong, ulong, ulong, ulong, ulong, ulong, \
|
| 40 | ulong) \
|
| 41 | __attribute__((alias(__stringify(___se_##prefix##name)))); \
|
| 42 | __diag_pop(); \
|
| 43 | static long noinline ___se_##prefix##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
|
| 44 | __used; \
|
| 45 | static long ___se_##prefix##name(__MAP(x,__SC_LONG,__VA_ARGS__))
|
| 46 |
|
| 47 | #define SC_RISCV_REGS_TO_ARGS(x, ...) \
|
| 48 | regs->orig_a0,regs->a1,regs->a2,regs->a3,regs->a4,regs->a5,regs->a6
|
| 49 |
|
| 50 | #endif
|
| 51 |
|
| 52 | #ifdef CONFIG_COMPAT
|
| 53 |
|
| 54 | #define COMPAT_SYSCALL_DEFINEx(x, name, ...) \
|
| 55 | asmlinkage long __riscv_compat_sys##name(const struct pt_regs *regs); \
|
| 56 | ALLOW_ERROR_INJECTION(__riscv_compat_sys##name, ERRNO); \
|
| 57 | static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \
|
| 58 | __SYSCALL_SE_DEFINEx(x, compat_sys, name, __VA_ARGS__) \
|
| 59 | { \
|
| 60 | return __do_compat_sys##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__)); \
|
| 61 | } \
|
| 62 | asmlinkage long __riscv_compat_sys##name(const struct pt_regs *regs) \
|
| 63 | { \
|
| 64 | return __se_compat_sys##name(SC_RISCV_REGS_TO_ARGS(x,__VA_ARGS__)); \
|
| 65 | } \
|
| 66 | static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
|
| 67 |
|
| 68 | #define COMPAT_SYSCALL_DEFINE0(sname) \
|
| 69 | asmlinkage long __riscv_compat_sys_##sname(const struct pt_regs *__unused); \
|
| 70 | ALLOW_ERROR_INJECTION(__riscv_compat_sys_##sname, ERRNO); \
|
| 71 | asmlinkage long __riscv_compat_sys_##sname(const struct pt_regs *__unused)
|
| 72 |
|
| 73 | #define COND_SYSCALL_COMPAT(name) \
|
| 74 | asmlinkage long __weak __riscv_compat_sys_##name(const struct pt_regs *regs); \
|
| 75 | asmlinkage long __weak __riscv_compat_sys_##name(const struct pt_regs *regs) \
|
| 76 | { \
|
| 77 | return sys_ni_syscall(); \
|
| 78 | }
|
| 79 |
|
| 80 | #endif
|
| 81 |
|
| 82 | #define __SYSCALL_DEFINEx(x, name, ...) \
|
| 83 | asmlinkage long __riscv_sys##name(const struct pt_regs *regs); \
|
| 84 | ALLOW_ERROR_INJECTION(__riscv_sys##name, ERRNO); \
|
| 85 | static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \
|
| 86 | __SYSCALL_SE_DEFINEx(x, sys, name, __VA_ARGS__) \
|
| 87 | { \
|
| 88 | long ret = __do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__)); \
|
| 89 | __MAP(x,__SC_TEST,__VA_ARGS__); \
|
| 90 | __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \
|
| 91 | return ret; \
|
| 92 | } \
|
| 93 | asmlinkage long __riscv_sys##name(const struct pt_regs *regs) \
|
| 94 | { \
|
| 95 | return __se_sys##name(SC_RISCV_REGS_TO_ARGS(x,__VA_ARGS__)); \
|
| 96 | } \
|
| 97 | static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
|
| 98 |
|
| 99 | #define SYSCALL_DEFINE0(sname) \
|
| 100 | SYSCALL_METADATA(_##sname, 0); \
|
| 101 | asmlinkage long __riscv_sys_##sname(const struct pt_regs *__unused); \
|
| 102 | ALLOW_ERROR_INJECTION(__riscv_sys_##sname, ERRNO); \
|
| 103 | asmlinkage long __riscv_sys_##sname(const struct pt_regs *__unused)
|
| 104 |
|
| 105 | #define COND_SYSCALL(name) \
|
| 106 | asmlinkage long __weak __riscv_sys_##name(const struct pt_regs *regs); \
|
| 107 | asmlinkage long __weak __riscv_sys_##name(const struct pt_regs *regs) \
|
| 108 | { \
|
| 109 | return sys_ni_syscall(); \
|
| 110 | }
|
| 111 |
|
| 112 | #endif
|