summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2017-11-29 19:00:41 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2017-11-29 19:00:41 -0500
commitc71d227fc4133f949dae620ed5e3a250b43f2415 (patch)
treece12b907996c2acd37e9d86f4ba492b09a0ab0f8
parent69112736e2f025ff3ba280cf81c36e25cf7cc59f (diff)
make kernel-side POLL... arch-independent
mangle/demangle on the way to/from userland Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--arch/blackfin/include/uapi/asm/poll.h19
-rw-r--r--arch/frv/include/uapi/asm/poll.h19
-rw-r--r--arch/m68k/include/uapi/asm/poll.h17
-rw-r--r--arch/mips/include/uapi/asm/poll.h17
-rw-r--r--arch/sparc/include/uapi/asm/poll.h20
-rw-r--r--arch/xtensa/include/uapi/asm/poll.h17
-rw-r--r--fs/fcntl.c2
-rw-r--r--fs/fuse/file.c4
-rw-r--r--fs/select.c4
-rw-r--r--include/uapi/asm-generic/poll.h14
10 files changed, 125 insertions, 8 deletions
diff --git a/arch/blackfin/include/uapi/asm/poll.h b/arch/blackfin/include/uapi/asm/poll.h
index 961e49056b0a..3b162f2d2970 100644
--- a/arch/blackfin/include/uapi/asm/poll.h
+++ b/arch/blackfin/include/uapi/asm/poll.h
@@ -9,8 +9,25 @@
#ifndef _UAPI__BFIN_POLL_H
#define _UAPI__BFIN_POLL_H
-#define POLLWRNORM (__force __poll_t)4 /* POLLOUT */
+#ifndef __KERNEL__
+#define POLLWRNORM POLLOUT
#define POLLWRBAND (__force __poll_t)256
+#else
+#define __ARCH_HAS_MANGLED_POLL
+static inline __u16 mangle_poll(__poll_t val)
+{
+ __u16 v = (__force __u16)val;
+ /* bit 9 -> bit 8, bit 8 -> bit 2 */
+ return (v & ~0x300) | ((v & 0x200) >> 1) | ((v & 0x100) >> 6);
+}
+
+static inline __poll_t demangle_poll(__u16 v)
+{
+ /* bit 8 -> bit 9, bit 2 -> bits 2 and 8 */
+ return (__force __poll_t)((v & ~0x100) | ((v & 0x100) << 1) |
+ ((v & 4) << 6));
+}
+#endif
#include <asm-generic/poll.h>
diff --git a/arch/frv/include/uapi/asm/poll.h b/arch/frv/include/uapi/asm/poll.h
index d7053ada7c69..a44c8f0ebee7 100644
--- a/arch/frv/include/uapi/asm/poll.h
+++ b/arch/frv/include/uapi/asm/poll.h
@@ -2,12 +2,27 @@
#ifndef _ASM_POLL_H
#define _ASM_POLL_H
+#ifndef __KERNEL__
#define POLLWRNORM POLLOUT
#define POLLWRBAND (__force __poll_t)256
+#else
+#define __ARCH_HAS_MANGLED_POLL
+static inline __u16 mangle_poll(__poll_t val)
+{
+ __u16 v = (__force __u16)val;
+ /* bit 9 -> bit 8, bit 8 -> bit 2 */
+ return (v & ~0x300) | ((v & 0x200) >> 1) | ((v & 0x100) >> 6);
+}
-#include <asm-generic/poll.h>
+static inline __poll_t demangle_poll(__u16 v)
+{
+ /* bit 8 -> bit 9, bit 2 -> bits 2 and 8 */
+ return (__force __poll_t)((v & ~0x100) | ((v & 0x100) << 1) |
+ ((v & 4) << 6));
+}
+#endif
+#include <asm-generic/poll.h>
#undef POLLREMOVE
#endif
-
diff --git a/arch/m68k/include/uapi/asm/poll.h b/arch/m68k/include/uapi/asm/poll.h
index 99314937fe5c..d8be239e8141 100644
--- a/arch/m68k/include/uapi/asm/poll.h
+++ b/arch/m68k/include/uapi/asm/poll.h
@@ -2,8 +2,25 @@
#ifndef __m68k_POLL_H
#define __m68k_POLL_H
+#ifndef __KERNEL__
#define POLLWRNORM POLLOUT
#define POLLWRBAND (__force __poll_t)256
+#else
+#define __ARCH_HAS_MANGLED_POLL
+static inline __u16 mangle_poll(__poll_t val)
+{
+ __u16 v = (__force __u16)val;
+ /* bit 9 -> bit 8, bit 8 -> bit 2 */
+ return (v & ~0x300) | ((v & 0x200) >> 1) | ((v & 0x100) >> 6);
+}
+
+static inline __poll_t demangle_poll(__u16 v)
+{
+ /* bit 8 -> bit 9, bit 2 -> bits 2 and 8 */
+ return (__force __poll_t)((v & ~0x100) | ((v & 0x100) << 1) |
+ ((v & 4) << 6));
+}
+#endif
#include <asm-generic/poll.h>
diff --git a/arch/mips/include/uapi/asm/poll.h b/arch/mips/include/uapi/asm/poll.h
index e937f8b1b007..3173f8917128 100644
--- a/arch/mips/include/uapi/asm/poll.h
+++ b/arch/mips/include/uapi/asm/poll.h
@@ -2,8 +2,25 @@
#ifndef __ASM_POLL_H
#define __ASM_POLL_H
+#ifndef __KERNEL__
#define POLLWRNORM POLLOUT
#define POLLWRBAND (__force __poll_t)0x0100
+#else
+#define __ARCH_HAS_MANGLED_POLL
+static inline __u16 mangle_poll(__poll_t val)
+{
+ __u16 v = (__force __u16)val;
+ /* bit 9 -> bit 8, bit 8 -> bit 2 */
+ return (v & ~0x300) | ((v & 0x200) >> 1) | ((v & 0x100) >> 6);
+}
+
+static inline __poll_t demangle_poll(__u16 v)
+{
+ /* bit 8 -> bit 9, bit 2 -> bits 2 and 8 */
+ return (__force __poll_t)((v & ~0x100) | ((v & 0x100) << 1) |
+ ((v & 4) << 6));
+}
+#endif
#include <asm-generic/poll.h>
diff --git a/arch/sparc/include/uapi/asm/poll.h b/arch/sparc/include/uapi/asm/poll.h
index 595cb12df1f1..2a81e79aa3ea 100644
--- a/arch/sparc/include/uapi/asm/poll.h
+++ b/arch/sparc/include/uapi/asm/poll.h
@@ -2,11 +2,31 @@
#ifndef __SPARC_POLL_H
#define __SPARC_POLL_H
+#ifndef __KERNEL__
#define POLLWRNORM POLLOUT
#define POLLWRBAND (__force __poll_t)256
#define POLLMSG (__force __poll_t)512
#define POLLREMOVE (__force __poll_t)1024
#define POLLRDHUP (__force __poll_t)2048
+#else
+#define __ARCH_HAS_MANGLED_POLL
+static inline __u16 mangle_poll(__poll_t val)
+{
+ __u16 v = (__force __u16)val;
+ /* bit 9 -> bit 8, bit 8 -> bit 2, bit 13 -> bit 11 */
+ return (v & ~0x300) | ((v & 0x200) >> 1) | ((v & 0x100) >> 6) |
+ ((v & 0x2000) >> 2);
+
+
+}
+
+static inline __poll_t demangle_poll(__u16 v)
+{
+ /* bit 8 -> bit 9, bit 2 -> bits 2 and 8 */
+ return (__force __poll_t)((v & ~0x100) | ((v & 0x100) << 1) |
+ ((v & 4) << 6) | ((v & 0x800) << 2));
+}
+#endif
#include <asm-generic/poll.h>
diff --git a/arch/xtensa/include/uapi/asm/poll.h b/arch/xtensa/include/uapi/asm/poll.h
index 22bbc48b9f85..e3246d41182c 100644
--- a/arch/xtensa/include/uapi/asm/poll.h
+++ b/arch/xtensa/include/uapi/asm/poll.h
@@ -12,9 +12,26 @@
#ifndef _XTENSA_POLL_H
#define _XTENSA_POLL_H
+#ifndef __KERNEL__
#define POLLWRNORM POLLOUT
#define POLLWRBAND (__force __poll_t)0x0100
#define POLLREMOVE (__force __poll_t)0x0800
+#else
+#define __ARCH_HAS_MANGLED_POLL
+static inline __u16 mangle_poll(__poll_t val)
+{
+ __u16 v = (__force __u16)val;
+ /* bit 9 -> bit 8, bit 8 -> bit 2 */
+ return (v & ~0x300) | ((v & 0x200) >> 1) | ((v & 0x100) >> 6);
+}
+
+static inline __poll_t demangle_poll(__u16 v)
+{
+ /* bit 8 -> bit 9, bit 2 -> bits 2 and 8 */
+ return (__force __poll_t)((v & ~0x100) | ((v & 0x100) << 1) |
+ ((v & 4) << 6));
+}
+#endif
#include <asm-generic/poll.h>
diff --git a/fs/fcntl.c b/fs/fcntl.c
index afe731c7a5a8..84bab55b4712 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -758,7 +758,7 @@ static void send_sigio_to_task(struct task_struct *p,
if (reason - POLL_IN >= NSIGPOLL)
si.si_band = ~0L;
else
- si.si_band = (__force long)band_table[reason - POLL_IN];
+ si.si_band = mangle_poll(band_table[reason - POLL_IN]);
si.si_fd = fd;
if (!do_send_sig_info(signum, &si, p, group))
break;
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index fa4ca6bd2c96..e85e974dd211 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -2764,7 +2764,7 @@ __poll_t fuse_file_poll(struct file *file, poll_table *wait)
return DEFAULT_POLLMASK;
poll_wait(file, &ff->poll_wait, wait);
- inarg.events = (__u32)poll_requested_events(wait);
+ inarg.events = mangle_poll(poll_requested_events(wait));
/*
* Ask for notification iff there's someone waiting for it.
@@ -2786,7 +2786,7 @@ __poll_t fuse_file_poll(struct file *file, poll_table *wait)
err = fuse_simple_request(fc, &args);
if (!err)
- return outarg.revents;
+ return demangle_poll(outarg.revents);
if (err == -ENOSYS) {
fc->no_poll = 1;
return DEFAULT_POLLMASK;
diff --git a/fs/select.c b/fs/select.c
index b2deeb215dbe..ec14171dd78a 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -817,7 +817,7 @@ static inline __poll_t do_pollfd(struct pollfd *pollfd, poll_table *pwait,
mask = POLLNVAL;
if (f.file) {
/* userland u16 ->events contains POLL... bitmap */
- __poll_t filter = (__force __poll_t)pollfd->events |
+ __poll_t filter = demangle_poll(pollfd->events) |
POLLERR | POLLHUP;
mask = DEFAULT_POLLMASK;
if (f.file->f_op->poll) {
@@ -833,7 +833,7 @@ static inline __poll_t do_pollfd(struct pollfd *pollfd, poll_table *pwait,
}
}
/* ... and so does ->revents */
- pollfd->revents = (__force u16)mask;
+ pollfd->revents = mangle_poll(mask);
return mask;
}
diff --git a/include/uapi/asm-generic/poll.h b/include/uapi/asm-generic/poll.h
index 8c0e9dd384b6..639fade14b23 100644
--- a/include/uapi/asm-generic/poll.h
+++ b/include/uapi/asm-generic/poll.h
@@ -33,6 +33,20 @@
#define POLL_BUSY_LOOP (__force __poll_t)0x8000
+#ifdef __KERNEL__
+#ifndef __ARCH_HAS_MANGLED_POLL
+static inline __u16 mangle_poll(__poll_t val)
+{
+ return (__force __u16)val;
+}
+
+static inline __poll_t demangle_poll(__u16 v)
+{
+ return (__force __poll_t)v;
+}
+#endif
+#endif
+
struct pollfd {
int fd;
short events;