diff --git a/arch/blackfin/include/uapi/asm/poll.h b/arch/blackfin/include/uapi/asm/poll.h index 961e49056b0a91e5a0ca628fe7a4ca10cc474b06..3b162f2d29703b326ad2583ab04a338a5575a741 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 diff --git a/arch/frv/include/uapi/asm/poll.h b/arch/frv/include/uapi/asm/poll.h index d7053ada7c69502f4344cdadca3ba00b4bfe8286..a44c8f0ebee7961a1d4d47794e822e1f52d5f3eb 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 +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 #undef POLLREMOVE #endif - diff --git a/arch/m68k/include/uapi/asm/poll.h b/arch/m68k/include/uapi/asm/poll.h index 99314937fe5c7313aae0aadc987b2285468f7013..d8be239e81417b4826d1549401b10be1891381a3 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 diff --git a/arch/mips/include/uapi/asm/poll.h b/arch/mips/include/uapi/asm/poll.h index e937f8b1b00754fe90d44edb14a72e969b26aeb1..3173f89171284829631ed179faa18240c884d9a5 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 diff --git a/arch/sparc/include/uapi/asm/poll.h b/arch/sparc/include/uapi/asm/poll.h index 595cb12df1f1ce93f30a3c114ecedbf9542aacf9..2a81e79aa3ea6328fed587e5abd58fef7af1a201 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 diff --git a/arch/xtensa/include/uapi/asm/poll.h b/arch/xtensa/include/uapi/asm/poll.h index 22bbc48b9f85db18194239abb896037eb7a7dbf8..e3246d41182c2b3c9bf6274f3450a22c62500bf7 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 diff --git a/fs/fcntl.c b/fs/fcntl.c index afe731c7a5a864844dafb0091293b15b49f77b80..84bab55b4712774efd8c0e6a7230890a9341d47e 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 fa4ca6bd2c966f1e38501be1b40751ac8656c6a1..e85e974dd211d3f8efb469b06ddc58ea50a0eb46 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 b2deeb215dbeaccba57bac4ac6304ebb6b0c5cfa..ec14171dd78a32c448dada2d8c96029b6e3e0bd0 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 8c0e9dd384b63f74de072c8389920d37bdca56f0..639fade14b2343a776c01993c328487533830696 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;