diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2014-03-03 10:06:12 +0100 |
---|---|---|
committer | Heiko Carstens <heiko.carstens@de.ibm.com> | 2014-03-04 09:12:25 +0100 |
commit | c2e7c3d0ef0d1a3765792a35ae9e6f91a3025214 (patch) | |
tree | 8351238e290456d0a9f02368f512b3a9fad037ba /arch/s390/kernel | |
parent | ab4f8bba19323eb78b7473df42b225eb14090fcc (diff) |
s390/compat: partial parameter conversion within syscall wrappers
Parameter conversion within the system call wrappers is only needed
for parameters which differ in size and have a size of eight bytes on
64 bit.
For system call parameters with a size of less than eight byte the
called system call itself will perform parameter conversion anyway.
So we can save the double conversion of e.g. int parameters.
The only types which need to be converted are therefore pointer and
(unsigned) long parameters.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel')
-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 d6a2cac1af12..d123f5d87b82 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__)); \ } |