aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
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 /include/linux
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 'include/linux')
-rw-r--r--include/linux/compat.h63
-rw-r--r--include/linux/kexec.h6
-rw-r--r--include/linux/syscalls.h2
3 files changed, 44 insertions, 27 deletions
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 3f448c65511b..01c0aa57ccec 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -14,6 +14,7 @@
14#include <linux/if.h> 14#include <linux/if.h>
15#include <linux/fs.h> 15#include <linux/fs.h>
16#include <linux/aio_abi.h> /* for aio_context_t */ 16#include <linux/aio_abi.h> /* for aio_context_t */
17#include <linux/unistd.h>
17 18
18#include <asm/compat.h> 19#include <asm/compat.h>
19#include <asm/siginfo.h> 20#include <asm/siginfo.h>
@@ -27,6 +28,9 @@
27#define __SC_DELOUSE(t,v) ((t)(unsigned long)(v)) 28#define __SC_DELOUSE(t,v) ((t)(unsigned long)(v))
28#endif 29#endif
29 30
31#define COMPAT_SYSCALL_DEFINE0(name) \
32 asmlinkage long compat_sys_##name(void)
33
30#define COMPAT_SYSCALL_DEFINE1(name, ...) \ 34#define COMPAT_SYSCALL_DEFINE1(name, ...) \
31 COMPAT_SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) 35 COMPAT_SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
32#define COMPAT_SYSCALL_DEFINE2(name, ...) \ 36#define COMPAT_SYSCALL_DEFINE2(name, ...) \
@@ -68,6 +72,8 @@ typedef struct compat_sigaltstack {
68typedef __compat_uid32_t compat_uid_t; 72typedef __compat_uid32_t compat_uid_t;
69typedef __compat_gid32_t compat_gid_t; 73typedef __compat_gid32_t compat_gid_t;
70 74
75typedef compat_ulong_t compat_aio_context_t;
76
71struct compat_sel_arg_struct; 77struct compat_sel_arg_struct;
72struct rusage; 78struct rusage;
73 79
@@ -318,7 +324,7 @@ asmlinkage long compat_sys_semctl(int semid, int semnum, int cmd, int arg);
318asmlinkage long compat_sys_msgsnd(int msqid, compat_uptr_t msgp, 324asmlinkage long compat_sys_msgsnd(int msqid, compat_uptr_t msgp,
319 compat_ssize_t msgsz, int msgflg); 325 compat_ssize_t msgsz, int msgflg);
320asmlinkage long compat_sys_msgrcv(int msqid, compat_uptr_t msgp, 326asmlinkage long compat_sys_msgrcv(int msqid, compat_uptr_t msgp,
321 compat_ssize_t msgsz, long msgtyp, int msgflg); 327 compat_ssize_t msgsz, compat_long_t msgtyp, int msgflg);
322long compat_sys_msgctl(int first, int second, void __user *uptr); 328long compat_sys_msgctl(int first, int second, void __user *uptr);
323long compat_sys_shmctl(int first, int second, void __user *uptr); 329long compat_sys_shmctl(int first, int second, void __user *uptr);
324long compat_sys_semtimedop(int semid, struct sembuf __user *tsems, 330long compat_sys_semtimedop(int semid, struct sembuf __user *tsems,
@@ -337,6 +343,19 @@ asmlinkage ssize_t compat_sys_preadv(compat_ulong_t fd,
337asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd, 343asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd,
338 const struct compat_iovec __user *vec, 344 const struct compat_iovec __user *vec,
339 compat_ulong_t vlen, u32 pos_low, u32 pos_high); 345 compat_ulong_t vlen, u32 pos_low, u32 pos_high);
346
347#ifdef __ARCH_WANT_COMPAT_SYS_PREADV64
348asmlinkage long compat_sys_preadv64(unsigned long fd,
349 const struct compat_iovec __user *vec,
350 unsigned long vlen, loff_t pos);
351#endif
352
353#ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64
354asmlinkage long compat_sys_pwritev64(unsigned long fd,
355 const struct compat_iovec __user *vec,
356 unsigned long vlen, loff_t pos);
357#endif
358
340asmlinkage long compat_sys_lseek(unsigned int, compat_off_t, unsigned int); 359asmlinkage long compat_sys_lseek(unsigned int, compat_off_t, unsigned int);
341 360
342asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv, 361asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv,
@@ -451,7 +470,7 @@ asmlinkage long compat_sys_timerfd_settime(int ufd, int flags,
451asmlinkage long compat_sys_timerfd_gettime(int ufd, 470asmlinkage long compat_sys_timerfd_gettime(int ufd,
452 struct compat_itimerspec __user *otmr); 471 struct compat_itimerspec __user *otmr);
453 472
454asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_page, 473asmlinkage long compat_sys_move_pages(pid_t pid, compat_ulong_t nr_pages,
455 __u32 __user *pages, 474 __u32 __user *pages,
456 const int __user *nodes, 475 const int __user *nodes,
457 int __user *status, 476 int __user *status,
@@ -481,20 +500,20 @@ asmlinkage long compat_sys_statfs64(const char __user *pathname,
481asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, 500asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz,
482 struct compat_statfs64 __user *buf); 501 struct compat_statfs64 __user *buf);
483asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd, 502asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd,
484 unsigned long arg); 503 compat_ulong_t arg);
485asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd, 504asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd,
486 unsigned long arg); 505 compat_ulong_t arg);
487asmlinkage long compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p); 506asmlinkage long compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p);
488asmlinkage long compat_sys_io_getevents(aio_context_t ctx_id, 507asmlinkage long compat_sys_io_getevents(compat_aio_context_t ctx_id,
489 unsigned long min_nr, 508 compat_long_t min_nr,
490 unsigned long nr, 509 compat_long_t nr,
491 struct io_event __user *events, 510 struct io_event __user *events,
492 struct compat_timespec __user *timeout); 511 struct compat_timespec __user *timeout);
493asmlinkage long compat_sys_io_submit(aio_context_t ctx_id, int nr, 512asmlinkage long compat_sys_io_submit(compat_aio_context_t ctx_id, int nr,
494 u32 __user *iocb); 513 u32 __user *iocb);
495asmlinkage long compat_sys_mount(const char __user *dev_name, 514asmlinkage long compat_sys_mount(const char __user *dev_name,
496 const char __user *dir_name, 515 const char __user *dir_name,
497 const char __user *type, unsigned long flags, 516 const char __user *type, compat_ulong_t flags,
498 const void __user *data); 517 const void __user *data);
499asmlinkage long compat_sys_old_readdir(unsigned int fd, 518asmlinkage long compat_sys_old_readdir(unsigned int fd,
500 struct compat_old_linux_dirent __user *, 519 struct compat_old_linux_dirent __user *,
@@ -502,9 +521,11 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd,
502asmlinkage long compat_sys_getdents(unsigned int fd, 521asmlinkage long compat_sys_getdents(unsigned int fd,
503 struct compat_linux_dirent __user *dirent, 522 struct compat_linux_dirent __user *dirent,
504 unsigned int count); 523 unsigned int count);
524#ifdef __ARCH_WANT_COMPAT_SYS_GETDENTS64
505asmlinkage long compat_sys_getdents64(unsigned int fd, 525asmlinkage long compat_sys_getdents64(unsigned int fd,
506 struct linux_dirent64 __user *dirent, 526 struct linux_dirent64 __user *dirent,
507 unsigned int count); 527 unsigned int count);
528#endif
508asmlinkage long compat_sys_vmsplice(int fd, const struct compat_iovec __user *, 529asmlinkage long compat_sys_vmsplice(int fd, const struct compat_iovec __user *,
509 unsigned int nr_segs, unsigned int flags); 530 unsigned int nr_segs, unsigned int flags);
510asmlinkage long compat_sys_open(const char __user *filename, int flags, 531asmlinkage long compat_sys_open(const char __user *filename, int flags,
@@ -549,9 +570,9 @@ asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg,
549 unsigned vlen, unsigned int flags); 570 unsigned vlen, unsigned int flags);
550asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, 571asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg,
551 unsigned int flags); 572 unsigned int flags);
552asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, 573asmlinkage long compat_sys_recv(int fd, void __user *buf, compat_size_t len,
553 unsigned flags); 574 unsigned flags);
554asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, size_t len, 575asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, compat_size_t len,
555 unsigned flags, struct sockaddr __user *addr, 576 unsigned flags, struct sockaddr __user *addr,
556 int __user *addrlen); 577 int __user *addrlen);
557asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg, 578asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,
@@ -615,16 +636,16 @@ asmlinkage long compat_sys_rt_sigqueueinfo(compat_pid_t pid, int sig,
615 struct compat_siginfo __user *uinfo); 636 struct compat_siginfo __user *uinfo);
616asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info); 637asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info);
617asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, 638asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
618 unsigned long arg); 639 compat_ulong_t arg);
619asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val, 640asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
620 struct compat_timespec __user *utime, u32 __user *uaddr2, 641 struct compat_timespec __user *utime, u32 __user *uaddr2,
621 u32 val3); 642 u32 val3);
622asmlinkage long compat_sys_getsockopt(int fd, int level, int optname, 643asmlinkage long compat_sys_getsockopt(int fd, int level, int optname,
623 char __user *optval, int __user *optlen); 644 char __user *optval, int __user *optlen);
624asmlinkage long compat_sys_kexec_load(unsigned long entry, 645asmlinkage long compat_sys_kexec_load(compat_ulong_t entry,
625 unsigned long nr_segments, 646 compat_ulong_t nr_segments,
626 struct compat_kexec_segment __user *, 647 struct compat_kexec_segment __user *,
627 unsigned long flags); 648 compat_ulong_t flags);
628asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes, 649asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes,
629 const struct compat_mq_attr __user *u_mqstat, 650 const struct compat_mq_attr __user *u_mqstat,
630 struct compat_mq_attr __user *u_omqstat); 651 struct compat_mq_attr __user *u_omqstat);
@@ -635,11 +656,11 @@ asmlinkage long compat_sys_mq_open(const char __user *u_name,
635 struct compat_mq_attr __user *u_attr); 656 struct compat_mq_attr __user *u_attr);
636asmlinkage long compat_sys_mq_timedsend(mqd_t mqdes, 657asmlinkage long compat_sys_mq_timedsend(mqd_t mqdes,
637 const char __user *u_msg_ptr, 658 const char __user *u_msg_ptr,
638 size_t msg_len, unsigned int msg_prio, 659 compat_size_t msg_len, unsigned int msg_prio,
639 const struct compat_timespec __user *u_abs_timeout); 660 const struct compat_timespec __user *u_abs_timeout);
640asmlinkage ssize_t compat_sys_mq_timedreceive(mqd_t mqdes, 661asmlinkage ssize_t compat_sys_mq_timedreceive(mqd_t mqdes,
641 char __user *u_msg_ptr, 662 char __user *u_msg_ptr,
642 size_t msg_len, unsigned int __user *u_msg_prio, 663 compat_size_t msg_len, unsigned int __user *u_msg_prio,
643 const struct compat_timespec __user *u_abs_timeout); 664 const struct compat_timespec __user *u_abs_timeout);
644asmlinkage long compat_sys_socketcall(int call, u32 __user *args); 665asmlinkage long compat_sys_socketcall(int call, u32 __user *args);
645asmlinkage long compat_sys_sysctl(struct compat_sysctl_args __user *args); 666asmlinkage long compat_sys_sysctl(struct compat_sysctl_args __user *args);
@@ -654,12 +675,12 @@ extern void __user *compat_alloc_user_space(unsigned long len);
654 675
655asmlinkage ssize_t compat_sys_process_vm_readv(compat_pid_t pid, 676asmlinkage ssize_t compat_sys_process_vm_readv(compat_pid_t pid,
656 const struct compat_iovec __user *lvec, 677 const struct compat_iovec __user *lvec,
657 unsigned long liovcnt, const struct compat_iovec __user *rvec, 678 compat_ulong_t liovcnt, const struct compat_iovec __user *rvec,
658 unsigned long riovcnt, unsigned long flags); 679 compat_ulong_t riovcnt, compat_ulong_t flags);
659asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid, 680asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid,
660 const struct compat_iovec __user *lvec, 681 const struct compat_iovec __user *lvec,
661 unsigned long liovcnt, const struct compat_iovec __user *rvec, 682 compat_ulong_t liovcnt, const struct compat_iovec __user *rvec,
662 unsigned long riovcnt, unsigned long flags); 683 compat_ulong_t riovcnt, compat_ulong_t flags);
663 684
664asmlinkage long compat_sys_sendfile(int out_fd, int in_fd, 685asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
665 compat_off_t __user *offset, compat_size_t count); 686 compat_off_t __user *offset, compat_size_t count);
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 6d4066cdb5b5..a75641930049 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -127,12 +127,6 @@ extern asmlinkage long sys_kexec_load(unsigned long entry,
127 struct kexec_segment __user *segments, 127 struct kexec_segment __user *segments,
128 unsigned long flags); 128 unsigned long flags);
129extern int kernel_kexec(void); 129extern int kernel_kexec(void);
130#ifdef CONFIG_COMPAT
131extern asmlinkage long compat_sys_kexec_load(unsigned long entry,
132 unsigned long nr_segments,
133 struct compat_kexec_segment __user *segments,
134 unsigned long flags);
135#endif
136extern struct page *kimage_alloc_control_pages(struct kimage *image, 130extern struct page *kimage_alloc_control_pages(struct kimage *image,
137 unsigned int order); 131 unsigned int order);
138extern void crash_kexec(struct pt_regs *); 132extern void crash_kexec(struct pt_regs *);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index a747a77ea584..1e67b7a5968c 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -98,6 +98,8 @@ struct sigaltstack;
98#define __MAP(n,...) __MAP##n(__VA_ARGS__) 98#define __MAP(n,...) __MAP##n(__VA_ARGS__)
99 99
100#define __SC_DECL(t, a) t a 100#define __SC_DECL(t, a) t a
101#define __TYPE_IS_L(t) (__same_type((t)0, 0L))
102#define __TYPE_IS_UL(t) (__same_type((t)0, 0UL))
101#define __TYPE_IS_LL(t) (__same_type((t)0, 0LL) || __same_type((t)0, 0ULL)) 103#define __TYPE_IS_LL(t) (__same_type((t)0, 0LL) || __same_type((t)0, 0ULL))
102#define __SC_LONG(t, a) __typeof(__builtin_choose_expr(__TYPE_IS_LL(t), 0LL, 0L)) a 104#define __SC_LONG(t, a) __typeof(__builtin_choose_expr(__TYPE_IS_LL(t), 0LL, 0L)) a
103#define __SC_CAST(t, a) (t) a 105#define __SC_CAST(t, a) (t) a