diff options
-rw-r--r-- | arch/s390/kernel/compat_wrap.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c index d6a2cac..d123f5d 100644 --- a/arch/s390/kernel/compat_wrap.c +++ b/arch/s390/kernel/compat_wrap.c @@ -15,6 +15,9 @@ #define COMPAT_SYSCALL_WRAP6(name, ...) \ COMPAT_SYSCALL_WRAPx(6, _##name, __VA_ARGS__) +#define __SC_COMPAT_TYPE(t, a) \ + __typeof(__builtin_choose_expr(sizeof(t) > 4, 0L, (t)0)) a + #define __SC_COMPAT_CAST(t, a) \ ({ \ long __ReS = a; \ @@ -30,10 +33,22 @@ (t)__ReS; \ }) +/* + * The COMPAT_SYSCALL_WRAP macro generates system call wrappers to be used by + * compat tasks. These wrappers will only be used for system calls where only + * the system call arguments need sign or zero extension or zeroing of the upper + * 33 bits of pointers. + * Note: since the wrapper function will afterwards call a system call which + * again performs zero and sign extension for all system call arguments with + * a size of less than eight bytes, these compat wrappers only touch those + * system call arguments with a size of eight bytes ((unsigned) long and + * pointers). Zero and sign extension for e.g. int parameters will be done by + * the regular system call wrappers. + */ #define COMPAT_SYSCALL_WRAPx(x, name, ...) \ asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ - asmlinkage long compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ - asmlinkage long compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ + asmlinkage long compat_sys##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__));\ + asmlinkage long compat_sys##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__)) \ { \ return sys##name(__MAP(x,__SC_COMPAT_CAST,__VA_ARGS__)); \ } |