Skip to content

Commit

Permalink
switch epoll_pwait to COMPAT_SYSCALL_DEFINE
Browse files Browse the repository at this point in the history
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
  • Loading branch information
Al Viro committed Mar 4, 2013
1 parent 19f4fc3 commit 35280bd
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 63 deletions.
10 changes: 0 additions & 10 deletions arch/s390/kernel/compat_wrapper.S
Original file line number Diff line number Diff line change
Expand Up @@ -1270,16 +1270,6 @@ ENTRY(sys_getcpu_wrapper)
llgtr %r4,%r4 # struct getcpu_cache *
jg sys_getcpu

ENTRY(compat_sys_epoll_pwait_wrapper)
lgfr %r2,%r2 # int
llgtr %r3,%r3 # struct compat_epoll_event *
lgfr %r4,%r4 # int
lgfr %r5,%r5 # int
llgtr %r6,%r6 # compat_sigset_t *
llgf %r0,164(%r15) # compat_size_t
stg %r0,160(%r15)
jg compat_sys_epoll_pwait

ENTRY(compat_sys_utimes_wrapper)
llgtr %r2,%r2 # char *
llgtr %r3,%r3 # struct compat_timeval *
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/kernel/syscalls.S
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ SYSCALL(sys_tee,sys_tee,sys_tee_wrapper)
SYSCALL(sys_vmsplice,sys_vmsplice,compat_sys_vmsplice_wrapper)
NI_SYSCALL /* 310 sys_move_pages */
SYSCALL(sys_getcpu,sys_getcpu,sys_getcpu_wrapper)
SYSCALL(sys_epoll_pwait,sys_epoll_pwait,compat_sys_epoll_pwait_wrapper)
SYSCALL(sys_epoll_pwait,sys_epoll_pwait,compat_sys_epoll_pwait)
SYSCALL(sys_utimes,sys_utimes,compat_sys_utimes_wrapper)
SYSCALL(sys_s390_fallocate,sys_fallocate,sys_fallocate_wrapper)
SYSCALL(sys_utimensat,sys_utimensat,compat_sys_utimensat_wrapper) /* 315 */
Expand Down
49 changes: 0 additions & 49 deletions fs/compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
#include <linux/signal.h>
#include <linux/poll.h>
#include <linux/mm.h>
#include <linux/eventpoll.h>
#include <linux/fs_struct.h>
#include <linux/slab.h>
#include <linux/pagemap.h>
Expand Down Expand Up @@ -1659,54 +1658,6 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
return ret;
}

#ifdef CONFIG_EPOLL

asmlinkage long compat_sys_epoll_pwait(int epfd,
struct compat_epoll_event __user *events,
int maxevents, int timeout,
const compat_sigset_t __user *sigmask,
compat_size_t sigsetsize)
{
long err;
compat_sigset_t csigmask;
sigset_t ksigmask, sigsaved;

/*
* If the caller wants a certain signal mask to be set during the wait,
* we apply it here.
*/
if (sigmask) {
if (sigsetsize != sizeof(compat_sigset_t))
return -EINVAL;
if (copy_from_user(&csigmask, sigmask, sizeof(csigmask)))
return -EFAULT;
sigset_from_compat(&ksigmask, &csigmask);
sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
}

err = sys_epoll_wait(epfd, events, maxevents, timeout);

/*
* If we changed the signal mask, we need to restore the original one.
* In case we've got a signal while waiting, we do not restore the
* signal mask yet, and we allow do_signal() to deliver the signal on
* the way back to userspace, before the signal mask is restored.
*/
if (sigmask) {
if (err == -EINTR) {
memcpy(&current->saved_sigmask, &sigsaved,
sizeof(sigsaved));
set_restore_sigmask();
} else
sigprocmask(SIG_SETMASK, &sigsaved, NULL);
}

return err;
}

#endif /* CONFIG_EPOLL */

#ifdef CONFIG_FHANDLE
/*
* Exactly like fs/open.c:sys_open_by_handle_at(), except that it
Expand Down
47 changes: 47 additions & 0 deletions fs/eventpoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <linux/atomic.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/compat.h>

/*
* LOCKING:
Expand Down Expand Up @@ -1940,6 +1941,52 @@ SYSCALL_DEFINE6(epoll_pwait, int, epfd, struct epoll_event __user *, events,
return error;
}

#ifdef CONFIG_COMPAT
COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd,
struct epoll_event __user *, events,
int, maxevents, int, timeout,
const compat_sigset_t __user *, sigmask,
compat_size_t, sigsetsize)
{
long err;
compat_sigset_t csigmask;
sigset_t ksigmask, sigsaved;

/*
* If the caller wants a certain signal mask to be set during the wait,
* we apply it here.
*/
if (sigmask) {
if (sigsetsize != sizeof(compat_sigset_t))
return -EINVAL;
if (copy_from_user(&csigmask, sigmask, sizeof(csigmask)))
return -EFAULT;
sigset_from_compat(&ksigmask, &csigmask);
sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
}

err = sys_epoll_wait(epfd, events, maxevents, timeout);

/*
* If we changed the signal mask, we need to restore the original one.
* In case we've got a signal while waiting, we do not restore the
* signal mask yet, and we allow do_signal() to deliver the signal on
* the way back to userspace, before the signal mask is restored.
*/
if (sigmask) {
if (err == -EINTR) {
memcpy(&current->saved_sigmask, &sigsaved,
sizeof(sigsaved));
set_restore_sigmask();
} else
sigprocmask(SIG_SETMASK, &sigsaved, NULL);
}

return err;
}
#endif

static int __init eventpoll_init(void)
{
struct sysinfo si;
Expand Down
5 changes: 2 additions & 3 deletions include/linux/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -432,10 +432,9 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
/*
* epoll (fs/eventpoll.c) compat bits follow ...
*/
struct epoll_event;
#define compat_epoll_event epoll_event
struct epoll_event; /* fortunately, this one is fixed-layout */
asmlinkage long compat_sys_epoll_pwait(int epfd,
struct compat_epoll_event __user *events,
struct epoll_event __user *events,
int maxevents, int timeout,
const compat_sigset_t __user *sigmask,
compat_size_t sigsetsize);
Expand Down

0 comments on commit 35280bd

Please sign in to comment.