瀏覽代碼

make kernel-side POLL... arch-independent

mangle/demangle on the way to/from userland

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Al Viro 7 年之前
父節點
當前提交
c71d227fc4

+ 18 - 1
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>
 

+ 17 - 2
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
-

+ 17 - 0
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>
 

+ 17 - 0
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>
 

+ 20 - 0
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>
 

+ 17 - 0
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>
 

+ 1 - 1
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;

+ 2 - 2
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;

+ 2 - 2
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;
 }

+ 14 - 0
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;