]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
s390/compat: partial parameter conversion within syscall wrappers
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Mon, 3 Mar 2014 09:06:12 +0000 (10:06 +0100)
committerHeiko Carstens <heiko.carstens@de.ibm.com>
Tue, 4 Mar 2014 08:12:25 +0000 (09:12 +0100)
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>
arch/s390/kernel/compat_wrap.c

index d6a2cac1af12246ebe9f25a40e36d79b8dd1e53a..d123f5d87b8219ca380930cb1af70dca6b46988a 100644 (file)
@@ -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;                                                 \
        (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__));        \
        }