summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/kernel/compat_wrap.c19
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__)); \
}
OpenPOWER on IntegriCloud