make kernel-side POLL... arch-independent
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 30 Nov 2017 00:00:41 +0000 (19:00 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 30 Nov 2017 00:00:41 +0000 (19:00 -0500)
mangle/demangle on the way to/from userland

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
arch/blackfin/include/uapi/asm/poll.h
arch/frv/include/uapi/asm/poll.h
arch/m68k/include/uapi/asm/poll.h
arch/mips/include/uapi/asm/poll.h
arch/sparc/include/uapi/asm/poll.h
arch/xtensa/include/uapi/asm/poll.h
fs/fcntl.c
fs/fuse/file.c
fs/select.c
include/uapi/asm-generic/poll.h

index 961e490..3b162f2 100644 (file)
@@ -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>
 
index d7053ad..a44c8f0 100644 (file)
@@ -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
-
index 9931493..d8be239 100644 (file)
@@ -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>
 
index e937f8b..3173f89 100644 (file)
@@ -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>
 
index 595cb12..2a81e79 100644 (file)
@@ -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>
 
index 22bbc48..e3246d4 100644 (file)
 #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>
 
index afe731c..84bab55 100644 (file)
@@ -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;
index fa4ca6b..e85e974 100644 (file)
@@ -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;
index b2deeb2..ec14171 100644 (file)
@@ -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;
 }
index 8c0e9dd..639fade 100644 (file)
 
 #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;