aboutsummaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-03-31 17:32:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-03-31 17:32:17 -0400
commit190f918660a69d1c56fd05dc8c6cbb8336a8a0af (patch)
tree2320b4aab7f048d97c35ac6ade5b7dedc71da89d /ipc
parent176ab02d4916f09d5d8cb63372d142df4378cdea (diff)
parent1e4ec6217dcf4b26cf959b70298a3b990479c955 (diff)
Merge branch 'compat' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 compat wrapper rework from Heiko Carstens: "S390 compat system call wrapper simplification work. The intention of this work is to get rid of all hand written assembly compat system call wrappers on s390, which perform proper sign or zero extension, or pointer conversion of compat system call parameters. Instead all of this should be done with C code eg by using Al's COMPAT_SYSCALL_DEFINEx() macro. Therefore all common code and s390 specific compat system calls have been converted to the COMPAT_SYSCALL_DEFINEx() macro. In order to generate correct code all compat system calls may only have eg compat_ulong_t parameters, but no unsigned long parameters. Those patches which change parameter types from unsigned long to compat_ulong_t parameters are separate in this series, but shouldn't cause any harm. The only compat system calls which intentionally have 64 bit parameters (preadv64 and pwritev64) in support of the x86/32 ABI haven't been changed, but are now only available if an architecture defines __ARCH_WANT_COMPAT_SYS_PREADV64/PWRITEV64. System calls which do not have a compat variant but still need proper zero extension on s390, like eg "long sys_brk(unsigned long brk)" will get a proper wrapper function with the new s390 specific COMPAT_SYSCALL_WRAPx() macro: COMPAT_SYSCALL_WRAP1(brk, unsigned long, brk); which generates the following code (simplified): asmlinkage long sys_brk(unsigned long brk); asmlinkage long compat_sys_brk(long brk) { return sys_brk((u32)brk); } Given that the C file which contains all the COMPAT_SYSCALL_WRAP lines includes both linux/syscall.h and linux/compat.h, it will generate build errors, if the declaration of sys_brk() doesn't match, or if there exists a non-matching compat_sys_brk() declaration. In addition this will intentionally result in a link error if somewhere else a compat_sys_brk() function exists, which probably should have been used instead. Two more BUILD_BUG_ONs make sure the size and type of each compat syscall parameter can be handled correctly with the s390 specific macros. I converted the compat system calls step by step to verify the generated code is correct and matches the previous code. In fact it did not always match, however that was always a bug in the hand written asm code. In result we get less code, less bugs, and much more sanity checking" * 'compat' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (44 commits) s390/compat: add copyright statement compat: include linux/unistd.h within linux/compat.h s390/compat: get rid of compat wrapper assembly code s390/compat: build error for large compat syscall args mm/compat: convert to COMPAT_SYSCALL_DEFINE with changing parameter types kexec/compat: convert to COMPAT_SYSCALL_DEFINE with changing parameter types net/compat: convert to COMPAT_SYSCALL_DEFINE with changing parameter types ipc/compat: convert to COMPAT_SYSCALL_DEFINE with changing parameter types fs/compat: convert to COMPAT_SYSCALL_DEFINE with changing parameter types ipc/compat: convert to COMPAT_SYSCALL_DEFINE fs/compat: convert to COMPAT_SYSCALL_DEFINE security/compat: convert to COMPAT_SYSCALL_DEFINE mm/compat: convert to COMPAT_SYSCALL_DEFINE net/compat: convert to COMPAT_SYSCALL_DEFINE kernel/compat: convert to COMPAT_SYSCALL_DEFINE fs/compat: optional preadv64/pwrite64 compat system calls ipc/compat_sys_msgrcv: change msgtyp type from long to compat_long_t s390/compat: partial parameter conversion within syscall wrappers s390/compat: automatic zero, sign and pointer conversion of syscalls s390/compat: add sync_file_range and fallocate compat syscalls ...
Diffstat (limited to 'ipc')
-rw-r--r--ipc/compat.c13
-rw-r--r--ipc/compat_mq.c32
2 files changed, 23 insertions, 22 deletions
diff --git a/ipc/compat.c b/ipc/compat.c
index f486b0096a67..98b9016cab6c 100644
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -430,9 +430,9 @@ COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp,
430} 430}
431 431
432COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp, 432COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp,
433 compat_ssize_t, msgsz, long, msgtyp, int, msgflg) 433 compat_ssize_t, msgsz, compat_long_t, msgtyp, int, msgflg)
434{ 434{
435 return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, msgtyp, 435 return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp,
436 msgflg, compat_do_msg_fill); 436 msgflg, compat_do_msg_fill);
437} 437}
438 438
@@ -498,7 +498,7 @@ static inline int put_compat_msqid_ds(struct msqid64_ds *m,
498 return err; 498 return err;
499} 499}
500 500
501long compat_sys_msgctl(int first, int second, void __user *uptr) 501COMPAT_SYSCALL_DEFINE3(msgctl, int, first, int, second, void __user *, uptr)
502{ 502{
503 int err, err2; 503 int err, err2;
504 struct msqid64_ds m64; 504 struct msqid64_ds m64;
@@ -668,7 +668,7 @@ static inline int put_compat_shm_info(struct shm_info __user *ip,
668 return err; 668 return err;
669} 669}
670 670
671long compat_sys_shmctl(int first, int second, void __user *uptr) 671COMPAT_SYSCALL_DEFINE3(shmctl, int, first, int, second, void __user *, uptr)
672{ 672{
673 void __user *p; 673 void __user *p;
674 struct shmid64_ds s64; 674 struct shmid64_ds s64;
@@ -749,8 +749,9 @@ long compat_sys_shmctl(int first, int second, void __user *uptr)
749 return err; 749 return err;
750} 750}
751 751
752long compat_sys_semtimedop(int semid, struct sembuf __user *tsems, 752COMPAT_SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsems,
753 unsigned nsops, const struct compat_timespec __user *timeout) 753 unsigned, nsops,
754 const struct compat_timespec __user *, timeout)
754{ 755{
755 struct timespec __user *ts64 = NULL; 756 struct timespec __user *ts64 = NULL;
756 if (timeout) { 757 if (timeout) {
diff --git a/ipc/compat_mq.c b/ipc/compat_mq.c
index 63d7c6de335b..d58747293772 100644
--- a/ipc/compat_mq.c
+++ b/ipc/compat_mq.c
@@ -46,9 +46,9 @@ static inline int put_compat_mq_attr(const struct mq_attr *attr,
46 | __put_user(attr->mq_curmsgs, &uattr->mq_curmsgs); 46 | __put_user(attr->mq_curmsgs, &uattr->mq_curmsgs);
47} 47}
48 48
49asmlinkage long compat_sys_mq_open(const char __user *u_name, 49COMPAT_SYSCALL_DEFINE4(mq_open, const char __user *, u_name,
50 int oflag, compat_mode_t mode, 50 int, oflag, compat_mode_t, mode,
51 struct compat_mq_attr __user *u_attr) 51 struct compat_mq_attr __user *, u_attr)
52{ 52{
53 void __user *p = NULL; 53 void __user *p = NULL;
54 if (u_attr && oflag & O_CREAT) { 54 if (u_attr && oflag & O_CREAT) {
@@ -78,10 +78,10 @@ static int compat_prepare_timeout(struct timespec __user **p,
78 return 0; 78 return 0;
79} 79}
80 80
81asmlinkage long compat_sys_mq_timedsend(mqd_t mqdes, 81COMPAT_SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes,
82 const char __user *u_msg_ptr, 82 const char __user *, u_msg_ptr,
83 size_t msg_len, unsigned int msg_prio, 83 compat_size_t, msg_len, unsigned int, msg_prio,
84 const struct compat_timespec __user *u_abs_timeout) 84 const struct compat_timespec __user *, u_abs_timeout)
85{ 85{
86 struct timespec __user *u_ts; 86 struct timespec __user *u_ts;
87 87
@@ -92,10 +92,10 @@ asmlinkage long compat_sys_mq_timedsend(mqd_t mqdes,
92 msg_prio, u_ts); 92 msg_prio, u_ts);
93} 93}
94 94
95asmlinkage ssize_t compat_sys_mq_timedreceive(mqd_t mqdes, 95COMPAT_SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes,
96 char __user *u_msg_ptr, 96 char __user *, u_msg_ptr,
97 size_t msg_len, unsigned int __user *u_msg_prio, 97 compat_size_t, msg_len, unsigned int __user *, u_msg_prio,
98 const struct compat_timespec __user *u_abs_timeout) 98 const struct compat_timespec __user *, u_abs_timeout)
99{ 99{
100 struct timespec __user *u_ts; 100 struct timespec __user *u_ts;
101 if (compat_prepare_timeout(&u_ts, u_abs_timeout)) 101 if (compat_prepare_timeout(&u_ts, u_abs_timeout))
@@ -105,8 +105,8 @@ asmlinkage ssize_t compat_sys_mq_timedreceive(mqd_t mqdes,
105 u_msg_prio, u_ts); 105 u_msg_prio, u_ts);
106} 106}
107 107
108asmlinkage long compat_sys_mq_notify(mqd_t mqdes, 108COMPAT_SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
109 const struct compat_sigevent __user *u_notification) 109 const struct compat_sigevent __user *, u_notification)
110{ 110{
111 struct sigevent __user *p = NULL; 111 struct sigevent __user *p = NULL;
112 if (u_notification) { 112 if (u_notification) {
@@ -122,9 +122,9 @@ asmlinkage long compat_sys_mq_notify(mqd_t mqdes,
122 return sys_mq_notify(mqdes, p); 122 return sys_mq_notify(mqdes, p);
123} 123}
124 124
125asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes, 125COMPAT_SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes,
126 const struct compat_mq_attr __user *u_mqstat, 126 const struct compat_mq_attr __user *, u_mqstat,
127 struct compat_mq_attr __user *u_omqstat) 127 struct compat_mq_attr __user *, u_omqstat)
128{ 128{
129 struct mq_attr mqstat; 129 struct mq_attr mqstat;
130 struct mq_attr __user *p = compat_alloc_user_space(2 * sizeof(*p)); 130 struct mq_attr __user *p = compat_alloc_user_space(2 * sizeof(*p));