mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 07:12:09 +00:00
[PATCH] Add epoll compat_ code to fs/compat.c
IA64 and ARM-OABI are currently using their own version of epoll compat_ code. An architecture needs epoll_event translation if alignof(u64) in 32 bit mode is different from alignof(u64) in 64 bit mode. If an architecture needs epoll_event translation, it must define struct compat_epoll_event in asm/compat.h and set CONFIG_HAVE_COMPAT_EPOLL_EVENT and use compat_sys_epoll_ctl and compat_sys_epoll_wait. All 64 bit architecture should use compat_sys_epoll_pwait. [sfr: restructure and move to fs/compat.c, remove MIPS version of compat_sys_epoll_pwait, use __put_user_unaligned] Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> Cc: David Woodhouse <dwmw2@infradead.org> Cc: Russell King <rmk@arm.linux.org.uk> Cc: "Luck, Tony" <tony.luck@intel.com> Cc: "David S. Miller" <davem@davemloft.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
b40df5743e
commit
f6dfb4fd7d
3 changed files with 119 additions and 46 deletions
|
@ -564,49 +564,3 @@ _sys32_clone(nabi_no_regargs struct pt_regs regs)
|
|||
return do_fork(clone_flags, newsp, ®s, 0,
|
||||
parent_tidptr, child_tidptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implement the event wait interface for the eventpoll file. It is the kernel
|
||||
* part of the user space epoll_pwait(2).
|
||||
*/
|
||||
asmlinkage long compat_sys_epoll_pwait(int epfd,
|
||||
struct epoll_event __user *events, int maxevents, int timeout,
|
||||
const compat_sigset_t __user *sigmask, size_t sigsetsize)
|
||||
{
|
||||
int error;
|
||||
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(sigset_t))
|
||||
return -EINVAL;
|
||||
if (!access_ok(VERIFY_READ, sigmask, sizeof(ksigmask)))
|
||||
return -EFAULT;
|
||||
if (__copy_conv_sigset_from_user(&ksigmask, sigmask))
|
||||
return -EFAULT;
|
||||
sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
|
||||
sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
|
||||
}
|
||||
|
||||
error = 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 (error == -EINTR) {
|
||||
memcpy(¤t->saved_sigmask, &sigsaved,
|
||||
sizeof(sigsaved));
|
||||
set_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
} else
|
||||
sigprocmask(SIG_SETMASK, &sigsaved, NULL);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue