VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   33 Branches   57 Tags
b24413180f560 (Greg Kroah-Hartman    2017-11-01 15:07:57 +0100    1) // SPDX-License-Identifier: GPL-2.0
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700    2) /*
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700    3)  * This file contains the procedures for the handling of select and poll
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700    4)  *
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700    5)  * Created for Linux based loosely upon Mathius Lattner's minix
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700    6)  * patches by Peter MacDonald. Heavily edited by Linus.
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700    7)  *
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700    8)  *  4 February 1994
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700    9)  *     COFF/ELF binary emulation. If the process has the STICKY_TIMEOUTS
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   10)  *     flag set in its personality we do *not* modify the given timeout
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   11)  *     parameter to reflect time remaining.
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   12)  *
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   13)  *  24 January 2000
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   14)  *     Changed sys_poll()/do_poll() to use PAGE_SIZE chunk-based allocation 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   15)  *     of fds to overcome nfds < 16390 descriptors limit (Tigran Aivazian).
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   16)  */
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   17) 
022a1692444cd (Milind Arun Choudhary 2007-05-08 00:29:02 -0700   18) #include <linux/kernel.h>
3f07c0144132e (Ingo Molnar           2017-02-08 18:51:30 +0100   19) #include <linux/sched/signal.h>
3f07c0144132e (Ingo Molnar           2017-02-08 18:51:30 +0100   20) #include <linux/sched/rt.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   21) #include <linux/syscalls.h>
630d9c47274aa (Paul Gortmaker        2011-11-16 23:57:37 -0500   22) #include <linux/export.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   23) #include <linux/slab.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   24) #include <linux/poll.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   25) #include <linux/personality.h> /* for STICKY_TIMEOUTS */
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   26) #include <linux/file.h>
9f3acc3140444 (Al Viro               2008-04-24 07:44:08 -0400   27) #include <linux/fdtable.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   28) #include <linux/fs.h>
b835996f628ea (Dipankar Sarma        2005-09-09 13:04:14 -0700   29) #include <linux/rcupdate.h>
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700   30) #include <linux/hrtimer.h>
9745cdb36da83 (Colin Cross           2013-05-06 23:50:17 +0000   31) #include <linux/freezer.h>
076bb0c82a44f (Eliezer Tamir         2013-07-10 17:13:17 +0300   32) #include <net/busy_poll.h>
2d19309cf8688 (Vlastimil Babka       2016-10-11 13:51:14 -0700   33) #include <linux/vmalloc.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   34) 
7c0f6ba682b9c (Linus Torvalds        2016-12-24 11:46:01 -0800   35) #include <linux/uaccess.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   36) 
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   37) 
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   38) /*
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   39)  * Estimate expected accuracy in ns from a timeval.
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   40)  *
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   41)  * After quite a bit of churning around, we've settled on
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   42)  * a simple thing of taking 0.1% of the timeout as the
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   43)  * slack, with a cap of 100 msec.
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   44)  * "nice" tasks get a 0.5% slack instead.
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   45)  *
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   46)  * Consider this comment an open invitation to come up with even
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   47)  * better solutions..
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   48)  */
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   49) 
5ae87e79ecb5b (Guillaume Knispel     2009-09-22 16:43:30 -0700   50) #define MAX_SLACK	(100 * NSEC_PER_MSEC)
5ae87e79ecb5b (Guillaume Knispel     2009-09-22 16:43:30 -0700   51) 
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700   52) static long __estimate_accuracy(struct timespec64 *tv)
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   53) {
96d2ab484e7a9 (Arjan van de Ven      2008-09-07 16:08:55 -0700   54) 	long slack;
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   55) 	int divfactor = 1000;
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   56) 
5ae87e79ecb5b (Guillaume Knispel     2009-09-22 16:43:30 -0700   57) 	if (tv->tv_sec < 0)
5ae87e79ecb5b (Guillaume Knispel     2009-09-22 16:43:30 -0700   58) 		return 0;
5ae87e79ecb5b (Guillaume Knispel     2009-09-22 16:43:30 -0700   59) 
4ce105d30e08f (Arjan van de Ven      2008-09-07 15:31:39 -0700   60) 	if (task_nice(current) > 0)
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   61) 		divfactor = divfactor / 5;
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   62) 
5ae87e79ecb5b (Guillaume Knispel     2009-09-22 16:43:30 -0700   63) 	if (tv->tv_sec > MAX_SLACK / (NSEC_PER_SEC/divfactor))
5ae87e79ecb5b (Guillaume Knispel     2009-09-22 16:43:30 -0700   64) 		return MAX_SLACK;
5ae87e79ecb5b (Guillaume Knispel     2009-09-22 16:43:30 -0700   65) 
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   66) 	slack = tv->tv_nsec / divfactor;
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   67) 	slack += tv->tv_sec * (NSEC_PER_SEC/divfactor);
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   68) 
5ae87e79ecb5b (Guillaume Knispel     2009-09-22 16:43:30 -0700   69) 	if (slack > MAX_SLACK)
5ae87e79ecb5b (Guillaume Knispel     2009-09-22 16:43:30 -0700   70) 		return MAX_SLACK;
96d2ab484e7a9 (Arjan van de Ven      2008-09-07 16:08:55 -0700   71) 
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   72) 	return slack;
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   73) }
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   74) 
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700   75) u64 select_estimate_accuracy(struct timespec64 *tv)
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   76) {
da8b44d5a9f8b (John Stultz           2016-03-17 14:20:51 -0700   77) 	u64 ret;
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700   78) 	struct timespec64 now;
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   79) 
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   80) 	/*
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   81) 	 * Realtime tasks get a slack of 0 for obvious reasons.
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   82) 	 */
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   83) 
4ce105d30e08f (Arjan van de Ven      2008-09-07 15:31:39 -0700   84) 	if (rt_task(current))
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   85) 		return 0;
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   86) 
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700   87) 	ktime_get_ts64(&now);
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700   88) 	now = timespec64_sub(*tv, now);
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   89) 	ret = __estimate_accuracy(&now);
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   90) 	if (ret < current->timer_slack_ns)
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   91) 		return current->timer_slack_ns;
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   92) 	return ret;
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   93) }
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   94) 
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   95) 
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700   96) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   97) struct poll_table_page {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   98) 	struct poll_table_page * next;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   99) 	struct poll_table_entry * entry;
5e01fdff04b7f (Gustavo A. R. Silva   2020-08-31 08:25:42 -0500  100) 	struct poll_table_entry entries[];
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  101) };
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  102) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  103) #define POLL_TABLE_FULL(table) \
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  104) 	((unsigned long)((table)->entry+1) > PAGE_SIZE + (unsigned long)(table))
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  105) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  106) /*
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  107)  * Ok, Peter made a complicated, but straightforward multiple_wait() function.
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  108)  * I have rewritten this, taking some shortcuts: This code may not be easy to
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  109)  * follow, but it should be free of race-conditions, and it's practical. If you
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  110)  * understand what I'm doing here, then you understand how the linux
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  111)  * sleep/wakeup mechanism works.
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  112)  *
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  113)  * Two very simple procedures, poll_wait() and poll_freewait() make all the
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  114)  * work.  poll_wait() is an inline-function defined in <linux/poll.h>,
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  115)  * as all select/poll functions have to call it to add an entry to the
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  116)  * poll table.
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  117)  */
75c96f85845a6 (Adrian Bunk           2005-05-05 16:16:09 -0700  118) static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
75c96f85845a6 (Adrian Bunk           2005-05-05 16:16:09 -0700  119) 		       poll_table *p);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  120) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  121) void poll_initwait(struct poll_wqueues *pwq)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  122) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  123) 	init_poll_funcptr(&pwq->pt, __pollwait);
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  124) 	pwq->polling_task = current;
b2add73dbf93f (Guillaume Knispel     2009-08-15 19:30:24 +0200  125) 	pwq->triggered = 0;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  126) 	pwq->error = 0;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  127) 	pwq->table = NULL;
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  128) 	pwq->inline_index = 0;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  129) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  130) EXPORT_SYMBOL(poll_initwait);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  131) 
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  132) static void free_poll_entry(struct poll_table_entry *entry)
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  133) {
ccf6780dc3d22 (WANG Cong             2007-05-09 07:10:02 +0200  134) 	remove_wait_queue(entry->wait_address, &entry->wait);
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  135) 	fput(entry->filp);
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  136) }
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  137) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  138) void poll_freewait(struct poll_wqueues *pwq)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  139) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  140) 	struct poll_table_page * p = pwq->table;
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  141) 	int i;
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  142) 	for (i = 0; i < pwq->inline_index; i++)
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  143) 		free_poll_entry(pwq->inline_entries + i);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  144) 	while (p) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  145) 		struct poll_table_entry * entry;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  146) 		struct poll_table_page *old;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  147) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  148) 		entry = p->entry;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  149) 		do {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  150) 			entry--;
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  151) 			free_poll_entry(entry);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  152) 		} while (entry > p->entries);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  153) 		old = p;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  154) 		p = p->next;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  155) 		free_page((unsigned long) old);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  156) 	}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  157) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  158) EXPORT_SYMBOL(poll_freewait);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  159) 
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  160) static struct poll_table_entry *poll_get_entry(struct poll_wqueues *p)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  161) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  162) 	struct poll_table_page *table = p->table;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  163) 
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  164) 	if (p->inline_index < N_INLINE_POLL_ENTRIES)
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  165) 		return p->inline_entries + p->inline_index++;
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  166) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  167) 	if (!table || POLL_TABLE_FULL(table)) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  168) 		struct poll_table_page *new_table;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  169) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  170) 		new_table = (struct poll_table_page *) __get_free_page(GFP_KERNEL);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  171) 		if (!new_table) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  172) 			p->error = -ENOMEM;
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  173) 			return NULL;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  174) 		}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  175) 		new_table->entry = new_table->entries;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  176) 		new_table->next = table;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  177) 		p->table = new_table;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  178) 		table = new_table;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  179) 	}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  180) 
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  181) 	return table->entry++;
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  182) }
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  183) 
ac6424b981bce (Ingo Molnar           2017-06-20 12:06:13 +0200  184) static int __pollwake(wait_queue_entry_t *wait, unsigned mode, int sync, void *key)
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  185) {
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  186) 	struct poll_wqueues *pwq = wait->private;
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  187) 	DECLARE_WAITQUEUE(dummy_wait, pwq->polling_task);
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  188) 
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  189) 	/*
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  190) 	 * Although this function is called under waitqueue lock, LOCK
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  191) 	 * doesn't imply write barrier and the users expect write
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  192) 	 * barrier semantics on wakeup functions.  The following
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  193) 	 * smp_wmb() is equivalent to smp_wmb() in try_to_wake_up()
b92b8b35a2e38 (Peter Zijlstra        2015-05-12 10:51:55 +0200  194) 	 * and is paired with smp_store_mb() in poll_schedule_timeout.
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  195) 	 */
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  196) 	smp_wmb();
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  197) 	pwq->triggered = 1;
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  198) 
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  199) 	/*
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  200) 	 * Perform the default wake up operation using a dummy
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  201) 	 * waitqueue.
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  202) 	 *
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  203) 	 * TODO: This is hacky but there currently is no interface to
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  204) 	 * pass in @sync.  @sync is scheduled to be removed and once
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  205) 	 * that happens, wake_up_process() can be used directly.
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  206) 	 */
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  207) 	return default_wake_function(&dummy_wait, mode, sync, key);
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  208) }
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  209) 
ac6424b981bce (Ingo Molnar           2017-06-20 12:06:13 +0200  210) static int pollwake(wait_queue_entry_t *wait, unsigned mode, int sync, void *key)
4938d7e0233a4 (Eric Dumazet          2009-06-16 15:33:36 -0700  211) {
4938d7e0233a4 (Eric Dumazet          2009-06-16 15:33:36 -0700  212) 	struct poll_table_entry *entry;
4938d7e0233a4 (Eric Dumazet          2009-06-16 15:33:36 -0700  213) 
4938d7e0233a4 (Eric Dumazet          2009-06-16 15:33:36 -0700  214) 	entry = container_of(wait, struct poll_table_entry, wait);
3ad6f93e98d6d (Al Viro               2017-07-03 20:14:56 -0400  215) 	if (key && !(key_to_poll(key) & entry->key))
4938d7e0233a4 (Eric Dumazet          2009-06-16 15:33:36 -0700  216) 		return 0;
4938d7e0233a4 (Eric Dumazet          2009-06-16 15:33:36 -0700  217) 	return __pollwake(wait, mode, sync, key);
4938d7e0233a4 (Eric Dumazet          2009-06-16 15:33:36 -0700  218) }
4938d7e0233a4 (Eric Dumazet          2009-06-16 15:33:36 -0700  219) 
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  220) /* Add a new entry */
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  221) static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  222) 				poll_table *p)
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  223) {
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  224) 	struct poll_wqueues *pwq = container_of(p, struct poll_wqueues, pt);
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  225) 	struct poll_table_entry *entry = poll_get_entry(pwq);
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  226) 	if (!entry)
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  227) 		return;
cb0942b812497 (Al Viro               2012-08-27 14:48:26 -0400  228) 	entry->filp = get_file(filp);
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  229) 	entry->wait_address = wait_address;
626cf23660850 (Hans Verkuil          2012-03-23 15:02:27 -0700  230) 	entry->key = p->_key;
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  231) 	init_waitqueue_func_entry(&entry->wait, pollwake);
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  232) 	entry->wait.private = pwq;
ccf6780dc3d22 (WANG Cong             2007-05-09 07:10:02 +0200  233) 	add_wait_queue(wait_address, &entry->wait);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  234) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  235) 
8f546ae1fc5ce (Christoph Hellwig     2018-01-11 12:23:05 +0100  236) static int poll_schedule_timeout(struct poll_wqueues *pwq, int state,
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  237) 			  ktime_t *expires, unsigned long slack)
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  238) {
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  239) 	int rc = -EINTR;
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  240) 
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  241) 	set_current_state(state);
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  242) 	if (!pwq->triggered)
59612d1879127 (Rafael J. Wysocki     2013-10-29 23:43:08 +0100  243) 		rc = schedule_hrtimeout_range(expires, slack, HRTIMER_MODE_ABS);
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  244) 	__set_current_state(TASK_RUNNING);
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  245) 
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  246) 	/*
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  247) 	 * Prepare for the next iteration.
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  248) 	 *
b92b8b35a2e38 (Peter Zijlstra        2015-05-12 10:51:55 +0200  249) 	 * The following smp_store_mb() serves two purposes.  First, it's
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  250) 	 * the counterpart rmb of the wmb in pollwake() such that data
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  251) 	 * written before wake up is always visible after wake up.
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  252) 	 * Second, the full barrier guarantees that triggered clearing
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  253) 	 * doesn't pass event check of the next iteration.  Note that
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  254) 	 * this problem doesn't exist for the first iteration as
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  255) 	 * add_wait_queue() has full barrier semantics.
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  256) 	 */
b92b8b35a2e38 (Peter Zijlstra        2015-05-12 10:51:55 +0200  257) 	smp_store_mb(pwq->triggered, 0);
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  258) 
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  259) 	return rc;
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  260) }
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  261) 
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  262) /**
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  263)  * poll_select_set_timeout - helper function to setup the timeout value
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700  264)  * @to:		pointer to timespec64 variable for the final timeout
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  265)  * @sec:	seconds (from user space)
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  266)  * @nsec:	nanoseconds (from user space)
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  267)  *
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  268)  * Note, we do not use a timespec for the user space value here, That
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  269)  * way we can use the function for timeval and compat interfaces as well.
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  270)  *
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  271)  * Returns -EINVAL if sec/nsec are not normalized. Otherwise 0.
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  272)  */
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700  273) int poll_select_set_timeout(struct timespec64 *to, time64_t sec, long nsec)
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  274) {
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700  275) 	struct timespec64 ts = {.tv_sec = sec, .tv_nsec = nsec};
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  276) 
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700  277) 	if (!timespec64_valid(&ts))
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  278) 		return -EINVAL;
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  279) 
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  280) 	/* Optimize for the zero timeout value here */
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  281) 	if (!sec && !nsec) {
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  282) 		to->tv_sec = to->tv_nsec = 0;
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  283) 	} else {
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700  284) 		ktime_get_ts64(to);
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700  285) 		*to = timespec64_add_safe(*to, ts);
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  286) 	}
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  287) 	return 0;
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  288) }
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  289) 
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  290) enum poll_time_type {
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  291) 	PT_TIMEVAL = 0,
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  292) 	PT_OLD_TIMEVAL = 1,
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  293) 	PT_TIMESPEC = 2,
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  294) 	PT_OLD_TIMESPEC = 3,
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  295) };
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  296) 
ac301020627e2 (Oleg Nesterov         2019-07-16 16:29:59 -0700  297) static int poll_select_finish(struct timespec64 *end_time,
ac301020627e2 (Oleg Nesterov         2019-07-16 16:29:59 -0700  298) 			      void __user *p,
ac301020627e2 (Oleg Nesterov         2019-07-16 16:29:59 -0700  299) 			      enum poll_time_type pt_type, int ret)
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  300) {
36819ad093e16 (Deepa Dinamani        2017-08-04 21:12:31 -0700  301) 	struct timespec64 rts;
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  302) 
ac301020627e2 (Oleg Nesterov         2019-07-16 16:29:59 -0700  303) 	restore_saved_sigmask_unless(ret == -ERESTARTNOHAND);
ac301020627e2 (Oleg Nesterov         2019-07-16 16:29:59 -0700  304) 
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  305) 	if (!p)
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  306) 		return ret;
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  307) 
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  308) 	if (current->personality & STICKY_TIMEOUTS)
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  309) 		goto sticky;
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  310) 
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  311) 	/* No update for zero timeout */
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  312) 	if (!end_time->tv_sec && !end_time->tv_nsec)
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  313) 		return ret;
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  314) 
36819ad093e16 (Deepa Dinamani        2017-08-04 21:12:31 -0700  315) 	ktime_get_ts64(&rts);
36819ad093e16 (Deepa Dinamani        2017-08-04 21:12:31 -0700  316) 	rts = timespec64_sub(*end_time, rts);
36819ad093e16 (Deepa Dinamani        2017-08-04 21:12:31 -0700  317) 	if (rts.tv_sec < 0)
36819ad093e16 (Deepa Dinamani        2017-08-04 21:12:31 -0700  318) 		rts.tv_sec = rts.tv_nsec = 0;
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700  319) 
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  320) 
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  321) 	switch (pt_type) {
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  322) 	case PT_TIMEVAL:
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  323) 		{
75d319c06e6a7 (Arnd Bergmann         2019-10-25 22:56:17 +0200  324) 			struct __kernel_old_timeval rtv;
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  325) 
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  326) 			if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec))
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  327) 				memset(&rtv, 0, sizeof(rtv));
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  328) 			rtv.tv_sec = rts.tv_sec;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  329) 			rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  330) 			if (!copy_to_user(p, &rtv, sizeof(rtv)))
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  331) 				return ret;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  332) 		}
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  333) 		break;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  334) 	case PT_OLD_TIMEVAL:
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  335) 		{
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  336) 			struct old_timeval32 rtv;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  337) 
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  338) 			rtv.tv_sec = rts.tv_sec;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  339) 			rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  340) 			if (!copy_to_user(p, &rtv, sizeof(rtv)))
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  341) 				return ret;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  342) 		}
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  343) 		break;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  344) 	case PT_TIMESPEC:
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  345) 		if (!put_timespec64(&rts, p))
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  346) 			return ret;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  347) 		break;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  348) 	case PT_OLD_TIMESPEC:
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  349) 		if (!put_old_timespec32(&rts, p))
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  350) 			return ret;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  351) 		break;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  352) 	default:
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  353) 		BUG();
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700  354) 	}
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  355) 	/*
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  356) 	 * If an application puts its timeval in read-only memory, we
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  357) 	 * don't want the Linux-specific update to the timeval to
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  358) 	 * cause a fault after the select has completed
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  359) 	 * successfully. However, because we're not updating the
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  360) 	 * timeval, we can't restart the system call.
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  361) 	 */
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  362) 
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  363) sticky:
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  364) 	if (ret == -ERESTARTNOHAND)
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  365) 		ret = -EINTR;
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  366) 	return ret;
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  367) }
b773ad40aca5b (Thomas Gleixner       2008-08-31 08:16:57 -0700  368) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  369) /*
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  370)  * Scalable version of the fd_set.
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  371)  */
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  372) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  373) typedef struct {
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  374) 	unsigned long *in, *out, *ex;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  375) 	unsigned long *res_in, *res_out, *res_ex;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  376) } fd_set_bits;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  377) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  378) /*
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  379)  * How many longwords for "nr" bits?
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  380)  */
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  381) #define FDS_BITPERLONG	(8*sizeof(long))
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  382) #define FDS_LONGS(nr)	(((nr)+FDS_BITPERLONG-1)/FDS_BITPERLONG)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  383) #define FDS_BYTES(nr)	(FDS_LONGS(nr)*sizeof(long))
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  384) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  385) /*
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  386)  * Use "unsigned long" accesses to let user-mode fd_set's be long-aligned.
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  387)  */
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  388) static inline
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  389) int get_fd_set(unsigned long nr, void __user *ufdset, unsigned long *fdset)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  390) {
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  391) 	nr = FDS_BYTES(nr);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  392) 	if (ufdset)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  393) 		return copy_from_user(fdset, ufdset, nr) ? -EFAULT : 0;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  394) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  395) 	memset(fdset, 0, nr);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  396) 	return 0;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  397) }
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  398) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  399) static inline unsigned long __must_check
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  400) set_fd_set(unsigned long nr, void __user *ufdset, unsigned long *fdset)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  401) {
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  402) 	if (ufdset)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  403) 		return __copy_to_user(ufdset, fdset, FDS_BYTES(nr));
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  404) 	return 0;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  405) }
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  406) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  407) static inline
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  408) void zero_fd_set(unsigned long nr, unsigned long *fdset)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  409) {
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  410) 	memset(fdset, 0, FDS_BYTES(nr));
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  411) }
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  412) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  413) #define FDS_IN(fds, n)		(fds->in + n)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  414) #define FDS_OUT(fds, n)		(fds->out + n)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  415) #define FDS_EX(fds, n)		(fds->ex + n)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  416) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  417) #define BITS(fds, n)	(*FDS_IN(fds, n)|*FDS_OUT(fds, n)|*FDS_EX(fds, n))
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  418) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  419) static int max_select_fd(unsigned long n, fd_set_bits *fds)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  420) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  421) 	unsigned long *open_fds;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  422) 	unsigned long set;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  423) 	int max;
badf16621c1f9 (Dipankar Sarma        2005-09-09 13:04:10 -0700  424) 	struct fdtable *fdt;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  425) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  426) 	/* handle last in-complete long-word first */
8ded2bbc1845e (Josh Boyer            2012-07-25 10:40:34 -0400  427) 	set = ~(~0UL << (n & (BITS_PER_LONG-1)));
8ded2bbc1845e (Josh Boyer            2012-07-25 10:40:34 -0400  428) 	n /= BITS_PER_LONG;
badf16621c1f9 (Dipankar Sarma        2005-09-09 13:04:10 -0700  429) 	fdt = files_fdtable(current->files);
1fd36adcd98c1 (David Howells         2012-02-16 17:49:54 +0000  430) 	open_fds = fdt->open_fds + n;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  431) 	max = 0;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  432) 	if (set) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  433) 		set &= BITS(fds, n);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  434) 		if (set) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  435) 			if (!(set & ~*open_fds))
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  436) 				goto get_max;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  437) 			return -EBADF;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  438) 		}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  439) 	}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  440) 	while (n) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  441) 		open_fds--;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  442) 		n--;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  443) 		set = BITS(fds, n);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  444) 		if (!set)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  445) 			continue;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  446) 		if (set & ~*open_fds)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  447) 			return -EBADF;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  448) 		if (max)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  449) 			continue;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  450) get_max:
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  451) 		do {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  452) 			max++;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  453) 			set >>= 1;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  454) 		} while (set);
8ded2bbc1845e (Josh Boyer            2012-07-25 10:40:34 -0400  455) 		max += n * BITS_PER_LONG;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  456) 	}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  457) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  458) 	return max;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  459) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  460) 
a9a08845e9acb (Linus Torvalds        2018-02-11 14:34:03 -0800  461) #define POLLIN_SET (EPOLLRDNORM | EPOLLRDBAND | EPOLLIN | EPOLLHUP | EPOLLERR)
a9a08845e9acb (Linus Torvalds        2018-02-11 14:34:03 -0800  462) #define POLLOUT_SET (EPOLLWRBAND | EPOLLWRNORM | EPOLLOUT | EPOLLERR)
a9a08845e9acb (Linus Torvalds        2018-02-11 14:34:03 -0800  463) #define POLLEX_SET (EPOLLPRI)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  464) 
4938d7e0233a4 (Eric Dumazet          2009-06-16 15:33:36 -0700  465) static inline void wait_key_set(poll_table *wait, unsigned long in,
2d48d67fa8cd1 (Eliezer Tamir         2013-06-24 10:28:03 +0300  466) 				unsigned long out, unsigned long bit,
0169943775832 (Al Viro               2017-07-03 03:14:15 -0400  467) 				__poll_t ll_flag)
4938d7e0233a4 (Eric Dumazet          2009-06-16 15:33:36 -0700  468) {
2d48d67fa8cd1 (Eliezer Tamir         2013-06-24 10:28:03 +0300  469) 	wait->_key = POLLEX_SET | ll_flag;
626cf23660850 (Hans Verkuil          2012-03-23 15:02:27 -0700  470) 	if (in & bit)
626cf23660850 (Hans Verkuil          2012-03-23 15:02:27 -0700  471) 		wait->_key |= POLLIN_SET;
626cf23660850 (Hans Verkuil          2012-03-23 15:02:27 -0700  472) 	if (out & bit)
626cf23660850 (Hans Verkuil          2012-03-23 15:02:27 -0700  473) 		wait->_key |= POLLOUT_SET;
4938d7e0233a4 (Eric Dumazet          2009-06-16 15:33:36 -0700  474) }
4938d7e0233a4 (Eric Dumazet          2009-06-16 15:33:36 -0700  475) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  476) static int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  477) {
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  478) 	ktime_t expire, *to = NULL;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  479) 	struct poll_wqueues table;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  480) 	poll_table *wait;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  481) 	int retval, i, timed_out = 0;
da8b44d5a9f8b (John Stultz           2016-03-17 14:20:51 -0700  482) 	u64 slack = 0;
0169943775832 (Al Viro               2017-07-03 03:14:15 -0400  483) 	__poll_t busy_flag = net_busy_loop_on() ? POLL_BUSY_LOOP : 0;
37056719bba50 (Alexander Duyck       2017-03-24 10:08:18 -0700  484) 	unsigned long busy_start = 0;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  485) 
b835996f628ea (Dipankar Sarma        2005-09-09 13:04:14 -0700  486) 	rcu_read_lock();
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  487) 	retval = max_select_fd(n, fds);
b835996f628ea (Dipankar Sarma        2005-09-09 13:04:14 -0700  488) 	rcu_read_unlock();
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  489) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  490) 	if (retval < 0)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  491) 		return retval;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  492) 	n = retval;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  493) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  494) 	poll_initwait(&table);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  495) 	wait = &table.pt;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  496) 	if (end_time && !end_time->tv_sec && !end_time->tv_nsec) {
626cf23660850 (Hans Verkuil          2012-03-23 15:02:27 -0700  497) 		wait->_qproc = NULL;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  498) 		timed_out = 1;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  499) 	}
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  500) 
96d2ab484e7a9 (Arjan van de Ven      2008-09-07 16:08:55 -0700  501) 	if (end_time && !timed_out)
231f3d393f63f (Andrew Morton         2010-10-27 15:34:53 -0700  502) 		slack = select_estimate_accuracy(end_time);
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700  503) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  504) 	retval = 0;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  505) 	for (;;) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  506) 		unsigned long *rinp, *routp, *rexp, *inp, *outp, *exp;
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  507) 		bool can_busy_loop = false;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  508) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  509) 		inp = fds->in; outp = fds->out; exp = fds->ex;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  510) 		rinp = fds->res_in; routp = fds->res_out; rexp = fds->res_ex;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  511) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  512) 		for (i = 0; i < n; ++rinp, ++routp, ++rexp) {
e6c8adca20ba4 (Al Viro               2017-07-03 22:25:56 -0400  513) 			unsigned long in, out, ex, all_bits, bit = 1, j;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  514) 			unsigned long res_in = 0, res_out = 0, res_ex = 0;
e6c8adca20ba4 (Al Viro               2017-07-03 22:25:56 -0400  515) 			__poll_t mask;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  516) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  517) 			in = *inp++; out = *outp++; ex = *exp++;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  518) 			all_bits = in | out | ex;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  519) 			if (all_bits == 0) {
8ded2bbc1845e (Josh Boyer            2012-07-25 10:40:34 -0400  520) 				i += BITS_PER_LONG;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  521) 				continue;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  522) 			}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  523) 
8ded2bbc1845e (Josh Boyer            2012-07-25 10:40:34 -0400  524) 			for (j = 0; j < BITS_PER_LONG; ++j, ++i, bit <<= 1) {
2903ff019b346 (Al Viro               2012-08-28 12:52:22 -0400  525) 				struct fd f;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  526) 				if (i >= n)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  527) 					break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  528) 				if (!(bit & all_bits))
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  529) 					continue;
2903ff019b346 (Al Viro               2012-08-28 12:52:22 -0400  530) 				f = fdget(i);
2903ff019b346 (Al Viro               2012-08-28 12:52:22 -0400  531) 				if (f.file) {
9965ed174e7d3 (Christoph Hellwig     2018-03-05 07:26:05 -0800  532) 					wait_key_set(wait, in, out, bit,
9965ed174e7d3 (Christoph Hellwig     2018-03-05 07:26:05 -0800  533) 						     busy_flag);
9965ed174e7d3 (Christoph Hellwig     2018-03-05 07:26:05 -0800  534) 					mask = vfs_poll(f.file, wait);
9965ed174e7d3 (Christoph Hellwig     2018-03-05 07:26:05 -0800  535) 
2903ff019b346 (Al Viro               2012-08-28 12:52:22 -0400  536) 					fdput(f);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  537) 					if ((mask & POLLIN_SET) && (in & bit)) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  538) 						res_in |= bit;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  539) 						retval++;
626cf23660850 (Hans Verkuil          2012-03-23 15:02:27 -0700  540) 						wait->_qproc = NULL;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  541) 					}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  542) 					if ((mask & POLLOUT_SET) && (out & bit)) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  543) 						res_out |= bit;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  544) 						retval++;
626cf23660850 (Hans Verkuil          2012-03-23 15:02:27 -0700  545) 						wait->_qproc = NULL;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  546) 					}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  547) 					if ((mask & POLLEX_SET) && (ex & bit)) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  548) 						res_ex |= bit;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  549) 						retval++;
626cf23660850 (Hans Verkuil          2012-03-23 15:02:27 -0700  550) 						wait->_qproc = NULL;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  551) 					}
2d48d67fa8cd1 (Eliezer Tamir         2013-06-24 10:28:03 +0300  552) 					/* got something, stop busy polling */
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  553) 					if (retval) {
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  554) 						can_busy_loop = false;
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  555) 						busy_flag = 0;
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  556) 
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  557) 					/*
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  558) 					 * only remember a returned
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  559) 					 * POLL_BUSY_LOOP if we asked for it
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  560) 					 */
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  561) 					} else if (busy_flag & mask)
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  562) 						can_busy_loop = true;
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  563) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  564) 				}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  565) 			}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  566) 			if (res_in)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  567) 				*rinp = res_in;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  568) 			if (res_out)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  569) 				*routp = res_out;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  570) 			if (res_ex)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  571) 				*rexp = res_ex;
55d8538498f62 (Linus Torvalds        2008-06-22 12:23:15 -0700  572) 			cond_resched();
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  573) 		}
626cf23660850 (Hans Verkuil          2012-03-23 15:02:27 -0700  574) 		wait->_qproc = NULL;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  575) 		if (retval || timed_out || signal_pending(current))
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  576) 			break;
f5264481c8049 (Pavel Machek          2008-04-21 22:15:06 +0000  577) 		if (table.error) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  578) 			retval = table.error;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  579) 			break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  580) 		}
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  581) 
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  582) 		/* only if found POLL_BUSY_LOOP sockets && not out of time */
76b1e9b9813e4 (Eliezer Tamir         2013-07-09 13:09:21 +0300  583) 		if (can_busy_loop && !need_resched()) {
37056719bba50 (Alexander Duyck       2017-03-24 10:08:18 -0700  584) 			if (!busy_start) {
37056719bba50 (Alexander Duyck       2017-03-24 10:08:18 -0700  585) 				busy_start = busy_loop_current_time();
76b1e9b9813e4 (Eliezer Tamir         2013-07-09 13:09:21 +0300  586) 				continue;
76b1e9b9813e4 (Eliezer Tamir         2013-07-09 13:09:21 +0300  587) 			}
37056719bba50 (Alexander Duyck       2017-03-24 10:08:18 -0700  588) 			if (!busy_loop_timeout(busy_start))
76b1e9b9813e4 (Eliezer Tamir         2013-07-09 13:09:21 +0300  589) 				continue;
76b1e9b9813e4 (Eliezer Tamir         2013-07-09 13:09:21 +0300  590) 		}
76b1e9b9813e4 (Eliezer Tamir         2013-07-09 13:09:21 +0300  591) 		busy_flag = 0;
2d48d67fa8cd1 (Eliezer Tamir         2013-06-24 10:28:03 +0300  592) 
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  593) 		/*
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  594) 		 * If this is the first loop and we have a timeout
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  595) 		 * given, then we convert to ktime_t and set the to
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  596) 		 * pointer to the expiry value.
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  597) 		 */
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  598) 		if (end_time && !to) {
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700  599) 			expire = timespec64_to_ktime(*end_time);
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  600) 			to = &expire;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  601) 		}
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  602) 
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  603) 		if (!poll_schedule_timeout(&table, TASK_INTERRUPTIBLE,
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  604) 					   to, slack))
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  605) 			timed_out = 1;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  606) 	}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  607) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  608) 	poll_freewait(&table);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  609) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  610) 	return retval;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  611) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  612) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  613) /*
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  614)  * We can actually return ERESTARTSYS instead of EINTR, but I'd
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  615)  * like to be certain this leads to no problems. So I return
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  616)  * EINTR just for safety.
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  617)  *
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  618)  * Update: ERESTARTSYS breaks at least the xview clock binary, so
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  619)  * I'm trying ERESTARTNOHAND which restart only when you want to.
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  620)  */
a2dcb44c3c5a8 (Al Viro               2008-04-23 14:05:15 -0400  621) int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700  622) 			   fd_set __user *exp, struct timespec64 *end_time)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  623) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  624) 	fd_set_bits fds;
29ff2db551967 (Andrew Morton         2006-04-10 22:52:46 -0700  625) 	void *bits;
bbea9f69668a3 (Vadim Lobanov         2006-12-10 02:21:12 -0800  626) 	int ret, max_fds;
2d19309cf8688 (Vlastimil Babka       2016-10-11 13:51:14 -0700  627) 	size_t size, alloc_size;
badf16621c1f9 (Dipankar Sarma        2005-09-09 13:04:10 -0700  628) 	struct fdtable *fdt;
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  629) 	/* Allocate small arguments on the stack to save memory and be faster */
30c14e40ed854 (Jes Sorensen          2006-03-31 11:18:57 -0500  630) 	long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  631) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  632) 	ret = -EINVAL;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  633) 	if (n < 0)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  634) 		goto out_nofds;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  635) 
bbea9f69668a3 (Vadim Lobanov         2006-12-10 02:21:12 -0800  636) 	/* max_fds can increase, so grab it once to avoid race */
b835996f628ea (Dipankar Sarma        2005-09-09 13:04:14 -0700  637) 	rcu_read_lock();
badf16621c1f9 (Dipankar Sarma        2005-09-09 13:04:10 -0700  638) 	fdt = files_fdtable(current->files);
bbea9f69668a3 (Vadim Lobanov         2006-12-10 02:21:12 -0800  639) 	max_fds = fdt->max_fds;
b835996f628ea (Dipankar Sarma        2005-09-09 13:04:14 -0700  640) 	rcu_read_unlock();
bbea9f69668a3 (Vadim Lobanov         2006-12-10 02:21:12 -0800  641) 	if (n > max_fds)
bbea9f69668a3 (Vadim Lobanov         2006-12-10 02:21:12 -0800  642) 		n = max_fds;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  643) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  644) 	/*
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  645) 	 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  646) 	 * since we used fdset we need to allocate memory in units of
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  647) 	 * long-words. 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  648) 	 */
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  649) 	size = FDS_BYTES(n);
b04eb6aa08ecc (Mitchell Blank Jr     2006-04-10 22:54:08 -0700  650) 	bits = stack_fds;
b04eb6aa08ecc (Mitchell Blank Jr     2006-04-10 22:54:08 -0700  651) 	if (size > sizeof(stack_fds) / 6) {
b04eb6aa08ecc (Mitchell Blank Jr     2006-04-10 22:54:08 -0700  652) 		/* Not enough space in on-stack array; must use kmalloc */
b04eb6aa08ecc (Mitchell Blank Jr     2006-04-10 22:54:08 -0700  653) 		ret = -ENOMEM;
2d19309cf8688 (Vlastimil Babka       2016-10-11 13:51:14 -0700  654) 		if (size > (SIZE_MAX / 6))
2d19309cf8688 (Vlastimil Babka       2016-10-11 13:51:14 -0700  655) 			goto out_nofds;
2d19309cf8688 (Vlastimil Babka       2016-10-11 13:51:14 -0700  656) 
2d19309cf8688 (Vlastimil Babka       2016-10-11 13:51:14 -0700  657) 		alloc_size = 6 * size;
752ade68cbd81 (Michal Hocko          2017-05-08 15:57:27 -0700  658) 		bits = kvmalloc(alloc_size, GFP_KERNEL);
b04eb6aa08ecc (Mitchell Blank Jr     2006-04-10 22:54:08 -0700  659) 		if (!bits)
b04eb6aa08ecc (Mitchell Blank Jr     2006-04-10 22:54:08 -0700  660) 			goto out_nofds;
b04eb6aa08ecc (Mitchell Blank Jr     2006-04-10 22:54:08 -0700  661) 	}
29ff2db551967 (Andrew Morton         2006-04-10 22:52:46 -0700  662) 	fds.in      = bits;
29ff2db551967 (Andrew Morton         2006-04-10 22:52:46 -0700  663) 	fds.out     = bits +   size;
29ff2db551967 (Andrew Morton         2006-04-10 22:52:46 -0700  664) 	fds.ex      = bits + 2*size;
29ff2db551967 (Andrew Morton         2006-04-10 22:52:46 -0700  665) 	fds.res_in  = bits + 3*size;
29ff2db551967 (Andrew Morton         2006-04-10 22:52:46 -0700  666) 	fds.res_out = bits + 4*size;
29ff2db551967 (Andrew Morton         2006-04-10 22:52:46 -0700  667) 	fds.res_ex  = bits + 5*size;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  668) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  669) 	if ((ret = get_fd_set(n, inp, fds.in)) ||
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  670) 	    (ret = get_fd_set(n, outp, fds.out)) ||
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  671) 	    (ret = get_fd_set(n, exp, fds.ex)))
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  672) 		goto out;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  673) 	zero_fd_set(n, fds.res_in);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  674) 	zero_fd_set(n, fds.res_out);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  675) 	zero_fd_set(n, fds.res_ex);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  676) 
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  677) 	ret = do_select(n, &fds, end_time);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  678) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  679) 	if (ret < 0)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  680) 		goto out;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  681) 	if (!ret) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  682) 		ret = -ERESTARTNOHAND;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  683) 		if (signal_pending(current))
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  684) 			goto out;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  685) 		ret = 0;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  686) 	}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  687) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  688) 	if (set_fd_set(n, inp, fds.res_in) ||
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  689) 	    set_fd_set(n, outp, fds.res_out) ||
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  690) 	    set_fd_set(n, exp, fds.res_ex))
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  691) 		ret = -EFAULT;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  692) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  693) out:
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  694) 	if (bits != stack_fds)
2d19309cf8688 (Vlastimil Babka       2016-10-11 13:51:14 -0700  695) 		kvfree(bits);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  696) out_nofds:
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  697) 	return ret;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  698) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  699) 
4bdb9acabff2d (Dominik Brodowski     2018-03-18 07:53:04 +0100  700) static int kern_select(int n, fd_set __user *inp, fd_set __user *outp,
75d319c06e6a7 (Arnd Bergmann         2019-10-25 22:56:17 +0200  701) 		       fd_set __user *exp, struct __kernel_old_timeval __user *tvp)
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  702) {
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700  703) 	struct timespec64 end_time, *to = NULL;
75d319c06e6a7 (Arnd Bergmann         2019-10-25 22:56:17 +0200  704) 	struct __kernel_old_timeval tv;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  705) 	int ret;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  706) 
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  707) 	if (tvp) {
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  708) 		if (copy_from_user(&tv, tvp, sizeof(tv)))
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  709) 			return -EFAULT;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  710) 
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  711) 		to = &end_time;
4d36a9e65d496 (Arjan van de Ven      2008-10-25 12:41:41 -0700  712) 		if (poll_select_set_timeout(to,
4d36a9e65d496 (Arjan van de Ven      2008-10-25 12:41:41 -0700  713) 				tv.tv_sec + (tv.tv_usec / USEC_PER_SEC),
4d36a9e65d496 (Arjan van de Ven      2008-10-25 12:41:41 -0700  714) 				(tv.tv_usec % USEC_PER_SEC) * NSEC_PER_USEC))
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  715) 			return -EINVAL;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  716) 	}
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  717) 
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  718) 	ret = core_sys_select(n, inp, outp, exp, to);
ac301020627e2 (Oleg Nesterov         2019-07-16 16:29:59 -0700  719) 	return poll_select_finish(&end_time, tvp, PT_TIMEVAL, ret);
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  720) }
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  721) 
4bdb9acabff2d (Dominik Brodowski     2018-03-18 07:53:04 +0100  722) SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp,
75d319c06e6a7 (Arnd Bergmann         2019-10-25 22:56:17 +0200  723) 		fd_set __user *, exp, struct __kernel_old_timeval __user *, tvp)
4bdb9acabff2d (Dominik Brodowski     2018-03-18 07:53:04 +0100  724) {
4bdb9acabff2d (Dominik Brodowski     2018-03-18 07:53:04 +0100  725) 	return kern_select(n, inp, outp, exp, tvp);
4bdb9acabff2d (Dominik Brodowski     2018-03-18 07:53:04 +0100  726) }
4bdb9acabff2d (Dominik Brodowski     2018-03-18 07:53:04 +0100  727) 
c9da9f2129d6a (Heiko Carstens        2009-01-14 14:13:57 +0100  728) static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  729) 		       fd_set __user *exp, void __user *tsp,
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  730) 		       const sigset_t __user *sigmask, size_t sigsetsize,
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  731) 		       enum poll_time_type type)
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  732) {
36819ad093e16 (Deepa Dinamani        2017-08-04 21:12:31 -0700  733) 	struct timespec64 ts, end_time, *to = NULL;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  734) 	int ret;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  735) 
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  736) 	if (tsp) {
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  737) 		switch (type) {
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  738) 		case PT_TIMESPEC:
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  739) 			if (get_timespec64(&ts, tsp))
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  740) 				return -EFAULT;
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  741) 			break;
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  742) 		case PT_OLD_TIMESPEC:
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  743) 			if (get_old_timespec32(&ts, tsp))
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  744) 				return -EFAULT;
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  745) 			break;
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  746) 		default:
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  747) 			BUG();
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  748) 		}
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  749) 
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  750) 		to = &end_time;
36819ad093e16 (Deepa Dinamani        2017-08-04 21:12:31 -0700  751) 		if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  752) 			return -EINVAL;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  753) 	}
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  754) 
b772434be0891 (Oleg Nesterov         2019-07-16 16:29:53 -0700  755) 	ret = set_user_sigmask(sigmask, sigsetsize);
ded653ccbec03 (Deepa Dinamani        2018-09-19 21:41:04 -0700  756) 	if (ret)
ded653ccbec03 (Deepa Dinamani        2018-09-19 21:41:04 -0700  757) 		return ret;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  758) 
62568510b8e26 (Bernd Schmidt         2009-01-13 22:14:48 +0100  759) 	ret = core_sys_select(n, inp, outp, exp, to);
ac301020627e2 (Oleg Nesterov         2019-07-16 16:29:59 -0700  760) 	return poll_select_finish(&end_time, tsp, type, ret);
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  761) }
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  762) 
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  763) /*
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  764)  * Most architectures can't handle 7-argument syscalls. So we provide a
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  765)  * 6-argument version where the sixth argument is a pointer to a structure
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  766)  * which has a pointer to the sigset_t itself followed by a size_t containing
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  767)  * the sigset size.
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  768)  */
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  769) struct sigset_argpack {
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  770) 	sigset_t __user *p;
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  771) 	size_t size;
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  772) };
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  773) 
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  774) static inline int get_sigset_argpack(struct sigset_argpack *to,
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  775) 				     struct sigset_argpack __user *from)
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  776) {
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  777) 	// the path is hot enough for overhead of copy_from_user() to matter
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  778) 	if (from) {
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  779) 		if (!user_read_access_begin(from, sizeof(*from)))
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  780) 			return -EFAULT;
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  781) 		unsafe_get_user(to->p, &from->p, Efault);
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  782) 		unsafe_get_user(to->size, &from->size, Efault);
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  783) 		user_read_access_end();
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  784) 	}
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  785) 	return 0;
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  786) Efault:
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  787) 	user_access_end();
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  788) 	return -EFAULT;
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  789) }
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  790) 
d4e82042c4cfa (Heiko Carstens        2009-01-14 14:14:34 +0100  791) SYSCALL_DEFINE6(pselect6, int, n, fd_set __user *, inp, fd_set __user *, outp,
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  792) 		fd_set __user *, exp, struct __kernel_timespec __user *, tsp,
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  793) 		void __user *, sig)
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  794) {
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  795) 	struct sigset_argpack x = {NULL, 0};
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  796) 
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  797) 	if (get_sigset_argpack(&x, sig))
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  798) 		return -EFAULT;
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  799) 
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  800) 	return do_pselect(n, inp, outp, exp, tsp, x.p, x.size, PT_TIMESPEC);
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  801) }
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  802) 
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  803) #if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT)
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  804) 
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  805) SYSCALL_DEFINE6(pselect6_time32, int, n, fd_set __user *, inp, fd_set __user *, outp,
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  806) 		fd_set __user *, exp, struct old_timespec32 __user *, tsp,
d4e82042c4cfa (Heiko Carstens        2009-01-14 14:14:34 +0100  807) 		void __user *, sig)
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  808) {
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  809) 	struct sigset_argpack x = {NULL, 0};
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  810) 
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  811) 	if (get_sigset_argpack(&x, sig))
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  812) 		return -EFAULT;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  813) 
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500  814) 	return do_pselect(n, inp, outp, exp, tsp, x.p, x.size, PT_OLD_TIMESPEC);
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  815) }
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  816) 
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  817) #endif
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700  818) 
5d0e52830e9ae (Christoph Hellwig     2010-03-10 15:21:13 -0800  819) #ifdef __ARCH_WANT_SYS_OLD_SELECT
5d0e52830e9ae (Christoph Hellwig     2010-03-10 15:21:13 -0800  820) struct sel_arg_struct {
5d0e52830e9ae (Christoph Hellwig     2010-03-10 15:21:13 -0800  821) 	unsigned long n;
5d0e52830e9ae (Christoph Hellwig     2010-03-10 15:21:13 -0800  822) 	fd_set __user *inp, *outp, *exp;
75d319c06e6a7 (Arnd Bergmann         2019-10-25 22:56:17 +0200  823) 	struct __kernel_old_timeval __user *tvp;
5d0e52830e9ae (Christoph Hellwig     2010-03-10 15:21:13 -0800  824) };
5d0e52830e9ae (Christoph Hellwig     2010-03-10 15:21:13 -0800  825) 
5d0e52830e9ae (Christoph Hellwig     2010-03-10 15:21:13 -0800  826) SYSCALL_DEFINE1(old_select, struct sel_arg_struct __user *, arg)
5d0e52830e9ae (Christoph Hellwig     2010-03-10 15:21:13 -0800  827) {
5d0e52830e9ae (Christoph Hellwig     2010-03-10 15:21:13 -0800  828) 	struct sel_arg_struct a;
5d0e52830e9ae (Christoph Hellwig     2010-03-10 15:21:13 -0800  829) 
5d0e52830e9ae (Christoph Hellwig     2010-03-10 15:21:13 -0800  830) 	if (copy_from_user(&a, arg, sizeof(a)))
5d0e52830e9ae (Christoph Hellwig     2010-03-10 15:21:13 -0800  831) 		return -EFAULT;
4bdb9acabff2d (Dominik Brodowski     2018-03-18 07:53:04 +0100  832) 	return kern_select(a.n, a.inp, a.outp, a.exp, a.tvp);
5d0e52830e9ae (Christoph Hellwig     2010-03-10 15:21:13 -0800  833) }
5d0e52830e9ae (Christoph Hellwig     2010-03-10 15:21:13 -0800  834) #endif
5d0e52830e9ae (Christoph Hellwig     2010-03-10 15:21:13 -0800  835) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  836) struct poll_list {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  837) 	struct poll_list *next;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  838) 	int len;
5e01fdff04b7f (Gustavo A. R. Silva   2020-08-31 08:25:42 -0500  839) 	struct pollfd entries[];
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  840) };
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  841) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  842) #define POLLFD_PER_PAGE  ((PAGE_SIZE-sizeof(struct poll_list)) / sizeof(struct pollfd))
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  843) 
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  844) /*
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  845)  * Fish for pollable events on the pollfd->fd file descriptor. We're only
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  846)  * interested in events matching the pollfd->events mask, and the result
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  847)  * matching that mask is both recorded in pollfd->revents and returned. The
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  848)  * pwait poll_table will be used by the fd-provided poll handler for waiting,
626cf23660850 (Hans Verkuil          2012-03-23 15:02:27 -0700  849)  * if pwait->_qproc is non-NULL.
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  850)  */
fb3679372bd79 (Al Viro               2017-07-16 23:51:03 -0400  851) static inline __poll_t do_pollfd(struct pollfd *pollfd, poll_table *pwait,
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  852) 				     bool *can_busy_poll,
fb3679372bd79 (Al Viro               2017-07-16 23:51:03 -0400  853) 				     __poll_t busy_flag)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  854) {
a0f8dcfc607d8 (Christoph Hellwig     2018-03-05 07:15:25 -0800  855) 	int fd = pollfd->fd;
a0f8dcfc607d8 (Christoph Hellwig     2018-03-05 07:15:25 -0800  856) 	__poll_t mask = 0, filter;
a0f8dcfc607d8 (Christoph Hellwig     2018-03-05 07:15:25 -0800  857) 	struct fd f;
a0f8dcfc607d8 (Christoph Hellwig     2018-03-05 07:15:25 -0800  858) 
a0f8dcfc607d8 (Christoph Hellwig     2018-03-05 07:15:25 -0800  859) 	if (fd < 0)
a0f8dcfc607d8 (Christoph Hellwig     2018-03-05 07:15:25 -0800  860) 		goto out;
a0f8dcfc607d8 (Christoph Hellwig     2018-03-05 07:15:25 -0800  861) 	mask = EPOLLNVAL;
a0f8dcfc607d8 (Christoph Hellwig     2018-03-05 07:15:25 -0800  862) 	f = fdget(fd);
a0f8dcfc607d8 (Christoph Hellwig     2018-03-05 07:15:25 -0800  863) 	if (!f.file)
a0f8dcfc607d8 (Christoph Hellwig     2018-03-05 07:15:25 -0800  864) 		goto out;
a0f8dcfc607d8 (Christoph Hellwig     2018-03-05 07:15:25 -0800  865) 
a0f8dcfc607d8 (Christoph Hellwig     2018-03-05 07:15:25 -0800  866) 	/* userland u16 ->events contains POLL... bitmap */
a0f8dcfc607d8 (Christoph Hellwig     2018-03-05 07:15:25 -0800  867) 	filter = demangle_poll(pollfd->events) | EPOLLERR | EPOLLHUP;
9965ed174e7d3 (Christoph Hellwig     2018-03-05 07:26:05 -0800  868) 	pwait->_key = filter | busy_flag;
9965ed174e7d3 (Christoph Hellwig     2018-03-05 07:26:05 -0800  869) 	mask = vfs_poll(f.file, pwait);
9965ed174e7d3 (Christoph Hellwig     2018-03-05 07:26:05 -0800  870) 	if (mask & busy_flag)
9965ed174e7d3 (Christoph Hellwig     2018-03-05 07:26:05 -0800  871) 		*can_busy_poll = true;
a0f8dcfc607d8 (Christoph Hellwig     2018-03-05 07:15:25 -0800  872) 	mask &= filter;		/* Mask out unneeded events. */
a0f8dcfc607d8 (Christoph Hellwig     2018-03-05 07:15:25 -0800  873) 	fdput(f);
a0f8dcfc607d8 (Christoph Hellwig     2018-03-05 07:15:25 -0800  874) 
a0f8dcfc607d8 (Christoph Hellwig     2018-03-05 07:15:25 -0800  875) out:
fb3679372bd79 (Al Viro               2017-07-16 23:51:03 -0400  876) 	/* ... and so does ->revents */
c71d227fc4133 (Al Viro               2017-11-29 19:00:41 -0500  877) 	pollfd->revents = mangle_poll(mask);
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  878) 	return mask;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  879) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  880) 
ccec5ee302d5c (Mateusz Guzik         2016-01-06 06:41:53 +0100  881) static int do_poll(struct poll_list *list, struct poll_wqueues *wait,
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700  882) 		   struct timespec64 *end_time)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  883) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  884) 	poll_table* pt = &wait->pt;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  885) 	ktime_t expire, *to = NULL;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  886) 	int timed_out = 0, count = 0;
da8b44d5a9f8b (John Stultz           2016-03-17 14:20:51 -0700  887) 	u64 slack = 0;
fb3679372bd79 (Al Viro               2017-07-16 23:51:03 -0400  888) 	__poll_t busy_flag = net_busy_loop_on() ? POLL_BUSY_LOOP : 0;
37056719bba50 (Alexander Duyck       2017-03-24 10:08:18 -0700  889) 	unsigned long busy_start = 0;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  890) 
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  891) 	/* Optimise the no-wait case */
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  892) 	if (end_time && !end_time->tv_sec && !end_time->tv_nsec) {
626cf23660850 (Hans Verkuil          2012-03-23 15:02:27 -0700  893) 		pt->_qproc = NULL;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  894) 		timed_out = 1;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  895) 	}
9bf084f70ffde (Oleg Nesterov         2007-10-16 23:26:18 -0700  896) 
96d2ab484e7a9 (Arjan van de Ven      2008-09-07 16:08:55 -0700  897) 	if (end_time && !timed_out)
231f3d393f63f (Andrew Morton         2010-10-27 15:34:53 -0700  898) 		slack = select_estimate_accuracy(end_time);
90d6e24a36863 (Arjan van de Ven      2008-09-01 15:55:35 -0700  899) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  900) 	for (;;) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  901) 		struct poll_list *walk;
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  902) 		bool can_busy_loop = false;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  903) 
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  904) 		for (walk = list; walk != NULL; walk = walk->next) {
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  905) 			struct pollfd * pfd, * pfd_end;
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  906) 
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  907) 			pfd = walk->entries;
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  908) 			pfd_end = pfd + walk->len;
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  909) 			for (; pfd != pfd_end; pfd++) {
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  910) 				/*
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  911) 				 * Fish for events. If we found one, record it
626cf23660850 (Hans Verkuil          2012-03-23 15:02:27 -0700  912) 				 * and kill poll_table->_qproc, so we don't
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  913) 				 * needlessly register any other waiters after
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  914) 				 * this. They'll get immediately deregistered
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  915) 				 * when we break out and return.
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  916) 				 */
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  917) 				if (do_pollfd(pfd, pt, &can_busy_loop,
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  918) 					      busy_flag)) {
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  919) 					count++;
626cf23660850 (Hans Verkuil          2012-03-23 15:02:27 -0700  920) 					pt->_qproc = NULL;
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  921) 					/* found something, stop busy polling */
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  922) 					busy_flag = 0;
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  923) 					can_busy_loop = false;
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  924) 				}
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  925) 			}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  926) 		}
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  927) 		/*
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  928) 		 * All waiters have already been registered, so don't provide
626cf23660850 (Hans Verkuil          2012-03-23 15:02:27 -0700  929) 		 * a poll_table->_qproc to them on the next loop iteration.
4a4b69f79ba72 (Vadim Lobanov         2006-06-23 02:05:16 -0700  930) 		 */
626cf23660850 (Hans Verkuil          2012-03-23 15:02:27 -0700  931) 		pt->_qproc = NULL;
9bf084f70ffde (Oleg Nesterov         2007-10-16 23:26:18 -0700  932) 		if (!count) {
9bf084f70ffde (Oleg Nesterov         2007-10-16 23:26:18 -0700  933) 			count = wait->error;
9bf084f70ffde (Oleg Nesterov         2007-10-16 23:26:18 -0700  934) 			if (signal_pending(current))
8cf8b5539a414 (Oleg Nesterov         2019-07-16 16:29:56 -0700  935) 				count = -ERESTARTNOHAND;
9bf084f70ffde (Oleg Nesterov         2007-10-16 23:26:18 -0700  936) 		}
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  937) 		if (count || timed_out)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  938) 			break;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  939) 
cbf55001b2ddb (Eliezer Tamir         2013-07-08 16:20:34 +0300  940) 		/* only if found POLL_BUSY_LOOP sockets && not out of time */
76b1e9b9813e4 (Eliezer Tamir         2013-07-09 13:09:21 +0300  941) 		if (can_busy_loop && !need_resched()) {
37056719bba50 (Alexander Duyck       2017-03-24 10:08:18 -0700  942) 			if (!busy_start) {
37056719bba50 (Alexander Duyck       2017-03-24 10:08:18 -0700  943) 				busy_start = busy_loop_current_time();
76b1e9b9813e4 (Eliezer Tamir         2013-07-09 13:09:21 +0300  944) 				continue;
76b1e9b9813e4 (Eliezer Tamir         2013-07-09 13:09:21 +0300  945) 			}
37056719bba50 (Alexander Duyck       2017-03-24 10:08:18 -0700  946) 			if (!busy_loop_timeout(busy_start))
76b1e9b9813e4 (Eliezer Tamir         2013-07-09 13:09:21 +0300  947) 				continue;
76b1e9b9813e4 (Eliezer Tamir         2013-07-09 13:09:21 +0300  948) 		}
76b1e9b9813e4 (Eliezer Tamir         2013-07-09 13:09:21 +0300  949) 		busy_flag = 0;
91e2fd3378393 (Eliezer Tamir         2013-06-28 15:59:35 +0300  950) 
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  951) 		/*
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  952) 		 * If this is the first loop and we have a timeout
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  953) 		 * given, then we convert to ktime_t and set the to
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  954) 		 * pointer to the expiry value.
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  955) 		 */
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  956) 		if (end_time && !to) {
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700  957) 			expire = timespec64_to_ktime(*end_time);
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  958) 			to = &expire;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  959) 		}
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800  960) 
5f820f648c92a (Tejun Heo             2009-01-06 14:40:59 -0800  961) 		if (!poll_schedule_timeout(wait, TASK_INTERRUPTIBLE, to, slack))
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700  962) 			timed_out = 1;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  963) 	}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  964) 	return count;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  965) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  966) 
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  967) #define N_STACK_PPS ((sizeof(stack_pps) - sizeof(struct poll_list))  / \
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  968) 			sizeof(struct pollfd))
70674f95c0a2e (Andi Kleen            2006-03-28 01:56:33 -0800  969) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400  970) static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700  971) 		struct timespec64 *end_time)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  972) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  973) 	struct poll_wqueues table;
43e11fa2d1d3b (Gustavo A. R. Silva   2019-07-16 16:30:58 -0700  974) 	int err = -EFAULT, fdcount, len;
30c14e40ed854 (Jes Sorensen          2006-03-31 11:18:57 -0500  975) 	/* Allocate small arguments on the stack to save memory and be
30c14e40ed854 (Jes Sorensen          2006-03-31 11:18:57 -0500  976) 	   faster - use long to make sure the buffer is aligned properly
30c14e40ed854 (Jes Sorensen          2006-03-31 11:18:57 -0500  977) 	   on 64 bit archs to avoid unaligned access */
30c14e40ed854 (Jes Sorensen          2006-03-31 11:18:57 -0500  978) 	long stack_pps[POLL_STACK_ALLOC/sizeof(long)];
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700  979) 	struct poll_list *const head = (struct poll_list *)stack_pps;
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700  980)  	struct poll_list *walk = head;
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700  981)  	unsigned long todo = nfds;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  982) 
d554ed895dc8f (Jiri Slaby            2010-03-05 13:42:42 -0800  983) 	if (nfds > rlimit(RLIMIT_NOFILE))
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  984) 		return -EINVAL;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  985) 
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700  986) 	len = min_t(unsigned int, nfds, N_STACK_PPS);
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700  987) 	for (;;) {
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700  988) 		walk->next = NULL;
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700  989) 		walk->len = len;
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700  990) 		if (!len)
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700  991) 			break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  992) 
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700  993) 		if (copy_from_user(walk->entries, ufds + nfds-todo,
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700  994) 					sizeof(struct pollfd) * walk->len))
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700  995) 			goto out_fds;
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700  996) 
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700  997) 		todo -= walk->len;
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700  998) 		if (!todo)
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700  999) 			break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1000) 
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700 1001) 		len = min(todo, POLLFD_PER_PAGE);
43e11fa2d1d3b (Gustavo A. R. Silva   2019-07-16 16:30:58 -0700 1002) 		walk = walk->next = kmalloc(struct_size(walk, entries, len),
43e11fa2d1d3b (Gustavo A. R. Silva   2019-07-16 16:30:58 -0700 1003) 					    GFP_KERNEL);
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700 1004) 		if (!walk) {
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700 1005) 			err = -ENOMEM;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1006) 			goto out_fds;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1007) 		}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1008) 	}
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800 1009) 
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700 1010) 	poll_initwait(&table);
ccec5ee302d5c (Mateusz Guzik         2016-01-06 06:41:53 +0100 1011) 	fdcount = do_poll(head, &table, end_time);
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700 1012) 	poll_freewait(&table);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1013) 
ef0ba05538299 (Linus Torvalds        2021-01-07 09:43:54 -0800 1014) 	if (!user_write_access_begin(ufds, nfds * sizeof(*ufds)))
ef0ba05538299 (Linus Torvalds        2021-01-07 09:43:54 -0800 1015) 		goto out_fds;
ef0ba05538299 (Linus Torvalds        2021-01-07 09:43:54 -0800 1016) 
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700 1017) 	for (walk = head; walk; walk = walk->next) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1018) 		struct pollfd *fds = walk->entries;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1019) 		int j;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1020) 
ef0ba05538299 (Linus Torvalds        2021-01-07 09:43:54 -0800 1021) 		for (j = walk->len; j; fds++, ufds++, j--)
ef0ba05538299 (Linus Torvalds        2021-01-07 09:43:54 -0800 1022) 			unsafe_put_user(fds->revents, &ufds->revents, Efault);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1023)   	}
ef0ba05538299 (Linus Torvalds        2021-01-07 09:43:54 -0800 1024) 	user_write_access_end();
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700 1025) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1026) 	err = fdcount;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1027) out_fds:
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700 1028) 	walk = head->next;
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700 1029) 	while (walk) {
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700 1030) 		struct poll_list *pos = walk;
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700 1031) 		walk = walk->next;
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700 1032) 		kfree(pos);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1033) 	}
252e5725cfb55 (Oleg Nesterov         2007-10-16 23:26:17 -0700 1034) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1035) 	return err;
ef0ba05538299 (Linus Torvalds        2021-01-07 09:43:54 -0800 1036) 
ef0ba05538299 (Linus Torvalds        2021-01-07 09:43:54 -0800 1037) Efault:
ef0ba05538299 (Linus Torvalds        2021-01-07 09:43:54 -0800 1038) 	user_write_access_end();
ef0ba05538299 (Linus Torvalds        2021-01-07 09:43:54 -0800 1039) 	err = -EFAULT;
ef0ba05538299 (Linus Torvalds        2021-01-07 09:43:54 -0800 1040) 	goto out_fds;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1041) }
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800 1042) 
3075d9da0b4cc (Chris Wright          2007-10-16 23:27:18 -0700 1043) static long do_restart_poll(struct restart_block *restart_block)
3075d9da0b4cc (Chris Wright          2007-10-16 23:27:18 -0700 1044) {
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1045) 	struct pollfd __user *ufds = restart_block->poll.ufds;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1046) 	int nfds = restart_block->poll.nfds;
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700 1047) 	struct timespec64 *to = NULL, end_time;
3075d9da0b4cc (Chris Wright          2007-10-16 23:27:18 -0700 1048) 	int ret;
3075d9da0b4cc (Chris Wright          2007-10-16 23:27:18 -0700 1049) 
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1050) 	if (restart_block->poll.has_timeout) {
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1051) 		end_time.tv_sec = restart_block->poll.tv_sec;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1052) 		end_time.tv_nsec = restart_block->poll.tv_nsec;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1053) 		to = &end_time;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1054) 	}
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1055) 
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1056) 	ret = do_sys_poll(ufds, nfds, to);
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1057) 
5abbe51a52625 (Oleg Nesterov         2021-02-01 18:46:41 +0100 1058) 	if (ret == -ERESTARTNOHAND)
5abbe51a52625 (Oleg Nesterov         2021-02-01 18:46:41 +0100 1059) 		ret = set_restart_fn(restart_block, do_restart_poll);
5abbe51a52625 (Oleg Nesterov         2021-02-01 18:46:41 +0100 1060) 
3075d9da0b4cc (Chris Wright          2007-10-16 23:27:18 -0700 1061) 	return ret;
3075d9da0b4cc (Chris Wright          2007-10-16 23:27:18 -0700 1062) }
3075d9da0b4cc (Chris Wright          2007-10-16 23:27:18 -0700 1063) 
5a8a82b1d306a (Heiko Carstens        2009-01-14 14:14:25 +0100 1064) SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds,
faf309009e2e1 (Linus Torvalds        2012-02-21 17:24:20 -0800 1065) 		int, timeout_msecs)
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800 1066) {
766b9f928bd5b (Deepa Dinamani        2016-05-19 17:09:05 -0700 1067) 	struct timespec64 end_time, *to = NULL;
3075d9da0b4cc (Chris Wright          2007-10-16 23:27:18 -0700 1068) 	int ret;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800 1069) 
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1070) 	if (timeout_msecs >= 0) {
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1071) 		to = &end_time;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1072) 		poll_select_set_timeout(to, timeout_msecs / MSEC_PER_SEC,
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1073) 			NSEC_PER_MSEC * (timeout_msecs % MSEC_PER_SEC));
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800 1074) 	}
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800 1075) 
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1076) 	ret = do_sys_poll(ufds, nfds, to);
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1077) 
8cf8b5539a414 (Oleg Nesterov         2019-07-16 16:29:56 -0700 1078) 	if (ret == -ERESTARTNOHAND) {
3075d9da0b4cc (Chris Wright          2007-10-16 23:27:18 -0700 1079) 		struct restart_block *restart_block;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1080) 
f56141e3e2d9a (Andy Lutomirski       2015-02-12 15:01:14 -0800 1081) 		restart_block = &current->restart_block;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1082) 		restart_block->poll.ufds = ufds;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1083) 		restart_block->poll.nfds = nfds;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1084) 
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1085) 		if (timeout_msecs >= 0) {
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1086) 			restart_block->poll.tv_sec = end_time.tv_sec;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1087) 			restart_block->poll.tv_nsec = end_time.tv_nsec;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1088) 			restart_block->poll.has_timeout = 1;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1089) 		} else
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1090) 			restart_block->poll.has_timeout = 0;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1091) 
5abbe51a52625 (Oleg Nesterov         2021-02-01 18:46:41 +0100 1092) 		ret = set_restart_fn(restart_block, do_restart_poll);
3075d9da0b4cc (Chris Wright          2007-10-16 23:27:18 -0700 1093) 	}
3075d9da0b4cc (Chris Wright          2007-10-16 23:27:18 -0700 1094) 	return ret;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800 1095) }
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800 1096) 
d4e82042c4cfa (Heiko Carstens        2009-01-14 14:14:34 +0100 1097) SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1098) 		struct __kernel_timespec __user *, tsp, const sigset_t __user *, sigmask,
d4e82042c4cfa (Heiko Carstens        2009-01-14 14:14:34 +0100 1099) 		size_t, sigsetsize)
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800 1100) {
36819ad093e16 (Deepa Dinamani        2017-08-04 21:12:31 -0700 1101) 	struct timespec64 ts, end_time, *to = NULL;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800 1102) 	int ret;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800 1103) 
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800 1104) 	if (tsp) {
36819ad093e16 (Deepa Dinamani        2017-08-04 21:12:31 -0700 1105) 		if (get_timespec64(&ts, tsp))
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800 1106) 			return -EFAULT;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800 1107) 
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1108) 		to = &end_time;
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1109) 		if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1110) 			return -EINVAL;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800 1111) 	}
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800 1112) 
b772434be0891 (Oleg Nesterov         2019-07-16 16:29:53 -0700 1113) 	ret = set_user_sigmask(sigmask, sigsetsize);
ded653ccbec03 (Deepa Dinamani        2018-09-19 21:41:04 -0700 1114) 	if (ret)
ded653ccbec03 (Deepa Dinamani        2018-09-19 21:41:04 -0700 1115) 		return ret;
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800 1116) 
8ff3e8e85fa6c (Arjan van de Ven      2008-08-31 08:26:40 -0700 1117) 	ret = do_sys_poll(ufds, nfds, to);
ac301020627e2 (Oleg Nesterov         2019-07-16 16:29:59 -0700 1118) 	return poll_select_finish(&end_time, tsp, PT_TIMESPEC, ret);
9f72949f679df (David Woodhouse       2006-01-18 17:44:05 -0800 1119) }
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1120) 
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1121) #if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1122) 
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1123) SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, unsigned int, nfds,
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1124) 		struct old_timespec32 __user *, tsp, const sigset_t __user *, sigmask,
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1125) 		size_t, sigsetsize)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1126) {
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1127) 	struct timespec64 ts, end_time, *to = NULL;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1128) 	int ret;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1129) 
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1130) 	if (tsp) {
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1131) 		if (get_old_timespec32(&ts, tsp))
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1132) 			return -EFAULT;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1133) 
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1134) 		to = &end_time;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1135) 		if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1136) 			return -EINVAL;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1137) 	}
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1138) 
b772434be0891 (Oleg Nesterov         2019-07-16 16:29:53 -0700 1139) 	ret = set_user_sigmask(sigmask, sigsetsize);
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1140) 	if (ret)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1141) 		return ret;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1142) 
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1143) 	ret = do_sys_poll(ufds, nfds, to);
ac301020627e2 (Oleg Nesterov         2019-07-16 16:29:59 -0700 1144) 	return poll_select_finish(&end_time, tsp, PT_OLD_TIMESPEC, ret);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1145) }
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1146) #endif
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1147) 
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1148) #ifdef CONFIG_COMPAT
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1149) #define __COMPAT_NFDBITS       (8 * sizeof(compat_ulong_t))
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1150) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1151) /*
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1152)  * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1153)  * 64-bit unsigned longs.
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1154)  */
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1155) static
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1156) int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1157) 			unsigned long *fdset)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1158) {
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1159) 	if (ufdset) {
464d62421cb8b (Al Viro               2017-06-04 03:24:26 -0400 1160) 		return compat_get_bitmap(fdset, ufdset, nr);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1161) 	} else {
79de3cbe9a974 (Helge Deller          2017-08-23 22:37:00 +0200 1162) 		zero_fd_set(nr, fdset);
464d62421cb8b (Al Viro               2017-06-04 03:24:26 -0400 1163) 		return 0;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1164) 	}
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1165) }
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1166) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1167) static
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1168) int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1169) 		      unsigned long *fdset)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1170) {
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1171) 	if (!ufdset)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1172) 		return 0;
464d62421cb8b (Al Viro               2017-06-04 03:24:26 -0400 1173) 	return compat_put_bitmap(ufdset, fdset, nr);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1174) }
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1175) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1176) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1177) /*
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1178)  * This is a virtual copy of sys_select from fs/select.c and probably
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1179)  * should be compared to it from time to time
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1180)  */
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1181) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1182) /*
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1183)  * We can actually return ERESTARTSYS instead of EINTR, but I'd
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1184)  * like to be certain this leads to no problems. So I return
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1185)  * EINTR just for safety.
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1186)  *
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1187)  * Update: ERESTARTSYS breaks at least the xview clock binary, so
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1188)  * I'm trying ERESTARTNOHAND which restart only when you want to.
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1189)  */
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1190) static int compat_core_sys_select(int n, compat_ulong_t __user *inp,
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1191) 	compat_ulong_t __user *outp, compat_ulong_t __user *exp,
36819ad093e16 (Deepa Dinamani        2017-08-04 21:12:31 -0700 1192) 	struct timespec64 *end_time)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1193) {
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1194) 	fd_set_bits fds;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1195) 	void *bits;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1196) 	int size, max_fds, ret = -EINVAL;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1197) 	struct fdtable *fdt;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1198) 	long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1199) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1200) 	if (n < 0)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1201) 		goto out_nofds;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1202) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1203) 	/* max_fds can increase, so grab it once to avoid race */
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1204) 	rcu_read_lock();
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1205) 	fdt = files_fdtable(current->files);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1206) 	max_fds = fdt->max_fds;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1207) 	rcu_read_unlock();
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1208) 	if (n > max_fds)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1209) 		n = max_fds;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1210) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1211) 	/*
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1212) 	 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1213) 	 * since we used fdset we need to allocate memory in units of
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1214) 	 * long-words.
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1215) 	 */
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1216) 	size = FDS_BYTES(n);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1217) 	bits = stack_fds;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1218) 	if (size > sizeof(stack_fds) / 6) {
6da2ec56059c3 (Kees Cook             2018-06-12 13:55:00 -0700 1219) 		bits = kmalloc_array(6, size, GFP_KERNEL);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1220) 		ret = -ENOMEM;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1221) 		if (!bits)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1222) 			goto out_nofds;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1223) 	}
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1224) 	fds.in      = (unsigned long *)  bits;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1225) 	fds.out     = (unsigned long *) (bits +   size);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1226) 	fds.ex      = (unsigned long *) (bits + 2*size);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1227) 	fds.res_in  = (unsigned long *) (bits + 3*size);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1228) 	fds.res_out = (unsigned long *) (bits + 4*size);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1229) 	fds.res_ex  = (unsigned long *) (bits + 5*size);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1230) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1231) 	if ((ret = compat_get_fd_set(n, inp, fds.in)) ||
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1232) 	    (ret = compat_get_fd_set(n, outp, fds.out)) ||
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1233) 	    (ret = compat_get_fd_set(n, exp, fds.ex)))
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1234) 		goto out;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1235) 	zero_fd_set(n, fds.res_in);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1236) 	zero_fd_set(n, fds.res_out);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1237) 	zero_fd_set(n, fds.res_ex);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1238) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1239) 	ret = do_select(n, &fds, end_time);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1240) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1241) 	if (ret < 0)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1242) 		goto out;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1243) 	if (!ret) {
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1244) 		ret = -ERESTARTNOHAND;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1245) 		if (signal_pending(current))
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1246) 			goto out;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1247) 		ret = 0;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1248) 	}
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1249) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1250) 	if (compat_set_fd_set(n, inp, fds.res_in) ||
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1251) 	    compat_set_fd_set(n, outp, fds.res_out) ||
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1252) 	    compat_set_fd_set(n, exp, fds.res_ex))
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1253) 		ret = -EFAULT;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1254) out:
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1255) 	if (bits != stack_fds)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1256) 		kfree(bits);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1257) out_nofds:
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1258) 	return ret;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1259) }
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1260) 
05585e449572d (Dominik Brodowski     2018-03-20 19:33:48 +0100 1261) static int do_compat_select(int n, compat_ulong_t __user *inp,
05585e449572d (Dominik Brodowski     2018-03-20 19:33:48 +0100 1262) 	compat_ulong_t __user *outp, compat_ulong_t __user *exp,
9afc5eee65ca7 (Arnd Bergmann         2018-07-13 12:52:28 +0200 1263) 	struct old_timeval32 __user *tvp)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1264) {
36819ad093e16 (Deepa Dinamani        2017-08-04 21:12:31 -0700 1265) 	struct timespec64 end_time, *to = NULL;
9afc5eee65ca7 (Arnd Bergmann         2018-07-13 12:52:28 +0200 1266) 	struct old_timeval32 tv;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1267) 	int ret;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1268) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1269) 	if (tvp) {
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1270) 		if (copy_from_user(&tv, tvp, sizeof(tv)))
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1271) 			return -EFAULT;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1272) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1273) 		to = &end_time;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1274) 		if (poll_select_set_timeout(to,
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1275) 				tv.tv_sec + (tv.tv_usec / USEC_PER_SEC),
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1276) 				(tv.tv_usec % USEC_PER_SEC) * NSEC_PER_USEC))
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1277) 			return -EINVAL;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1278) 	}
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1279) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1280) 	ret = compat_core_sys_select(n, inp, outp, exp, to);
ac301020627e2 (Oleg Nesterov         2019-07-16 16:29:59 -0700 1281) 	return poll_select_finish(&end_time, tvp, PT_OLD_TIMEVAL, ret);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1282) }
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1283) 
05585e449572d (Dominik Brodowski     2018-03-20 19:33:48 +0100 1284) COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp,
05585e449572d (Dominik Brodowski     2018-03-20 19:33:48 +0100 1285) 	compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
9afc5eee65ca7 (Arnd Bergmann         2018-07-13 12:52:28 +0200 1286) 	struct old_timeval32 __user *, tvp)
05585e449572d (Dominik Brodowski     2018-03-20 19:33:48 +0100 1287) {
05585e449572d (Dominik Brodowski     2018-03-20 19:33:48 +0100 1288) 	return do_compat_select(n, inp, outp, exp, tvp);
05585e449572d (Dominik Brodowski     2018-03-20 19:33:48 +0100 1289) }
05585e449572d (Dominik Brodowski     2018-03-20 19:33:48 +0100 1290) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1291) struct compat_sel_arg_struct {
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1292) 	compat_ulong_t n;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1293) 	compat_uptr_t inp;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1294) 	compat_uptr_t outp;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1295) 	compat_uptr_t exp;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1296) 	compat_uptr_t tvp;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1297) };
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1298) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1299) COMPAT_SYSCALL_DEFINE1(old_select, struct compat_sel_arg_struct __user *, arg)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1300) {
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1301) 	struct compat_sel_arg_struct a;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1302) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1303) 	if (copy_from_user(&a, arg, sizeof(a)))
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1304) 		return -EFAULT;
05585e449572d (Dominik Brodowski     2018-03-20 19:33:48 +0100 1305) 	return do_compat_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp),
05585e449572d (Dominik Brodowski     2018-03-20 19:33:48 +0100 1306) 				compat_ptr(a.exp), compat_ptr(a.tvp));
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1307) }
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1308) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1309) static long do_compat_pselect(int n, compat_ulong_t __user *inp,
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1310) 	compat_ulong_t __user *outp, compat_ulong_t __user *exp,
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1311) 	void __user *tsp, compat_sigset_t __user *sigmask,
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1312) 	compat_size_t sigsetsize, enum poll_time_type type)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1313) {
36819ad093e16 (Deepa Dinamani        2017-08-04 21:12:31 -0700 1314) 	struct timespec64 ts, end_time, *to = NULL;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1315) 	int ret;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1316) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1317) 	if (tsp) {
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1318) 		switch (type) {
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1319) 		case PT_OLD_TIMESPEC:
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1320) 			if (get_old_timespec32(&ts, tsp))
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1321) 				return -EFAULT;
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1322) 			break;
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1323) 		case PT_TIMESPEC:
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1324) 			if (get_timespec64(&ts, tsp))
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1325) 				return -EFAULT;
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1326) 			break;
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1327) 		default:
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1328) 			BUG();
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1329) 		}
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1330) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1331) 		to = &end_time;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1332) 		if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1333) 			return -EINVAL;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1334) 	}
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1335) 
b772434be0891 (Oleg Nesterov         2019-07-16 16:29:53 -0700 1336) 	ret = set_compat_user_sigmask(sigmask, sigsetsize);
ded653ccbec03 (Deepa Dinamani        2018-09-19 21:41:04 -0700 1337) 	if (ret)
ded653ccbec03 (Deepa Dinamani        2018-09-19 21:41:04 -0700 1338) 		return ret;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1339) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1340) 	ret = compat_core_sys_select(n, inp, outp, exp, to);
ac301020627e2 (Oleg Nesterov         2019-07-16 16:29:59 -0700 1341) 	return poll_select_finish(&end_time, tsp, type, ret);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1342) }
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1343) 
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1344) struct compat_sigset_argpack {
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1345) 	compat_uptr_t p;
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1346) 	compat_size_t size;
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1347) };
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1348) static inline int get_compat_sigset_argpack(struct compat_sigset_argpack *to,
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1349) 					    struct compat_sigset_argpack __user *from)
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1350) {
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1351) 	if (from) {
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1352) 		if (!user_read_access_begin(from, sizeof(*from)))
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1353) 			return -EFAULT;
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1354) 		unsafe_get_user(to->p, &from->p, Efault);
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1355) 		unsafe_get_user(to->size, &from->size, Efault);
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1356) 		user_read_access_end();
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1357) 	}
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1358) 	return 0;
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1359) Efault:
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1360) 	user_access_end();
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1361) 	return -EFAULT;
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1362) }
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1363) 
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1364) COMPAT_SYSCALL_DEFINE6(pselect6_time64, int, n, compat_ulong_t __user *, inp,
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1365) 	compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1366) 	struct __kernel_timespec __user *, tsp, void __user *, sig)
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1367) {
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1368) 	struct compat_sigset_argpack x = {0, 0};
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1369) 
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1370) 	if (get_compat_sigset_argpack(&x, sig))
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1371) 		return -EFAULT;
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1372) 
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1373) 	return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(x.p),
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1374) 				 x.size, PT_TIMESPEC);
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1375) }
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1376) 
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1377) #if defined(CONFIG_COMPAT_32BIT_TIME)
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1378) 
8dabe7245bbc1 (Arnd Bergmann         2019-01-07 00:33:08 +0100 1379) COMPAT_SYSCALL_DEFINE6(pselect6_time32, int, n, compat_ulong_t __user *, inp,
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1380) 	compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
9afc5eee65ca7 (Arnd Bergmann         2018-07-13 12:52:28 +0200 1381) 	struct old_timespec32 __user *, tsp, void __user *, sig)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1382) {
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1383) 	struct compat_sigset_argpack x = {0, 0};
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1384) 
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1385) 	if (get_compat_sigset_argpack(&x, sig))
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1386) 		return -EFAULT;
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1387) 
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1388) 	return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(x.p),
7e71609f64ec8 (Al Viro               2020-02-19 09:54:24 -0500 1389) 				 x.size, PT_OLD_TIMESPEC);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1390) }
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1391) 
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1392) #endif
e024707bccae1 (Deepa Dinamani        2018-09-19 21:41:07 -0700 1393) 
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1394) #if defined(CONFIG_COMPAT_32BIT_TIME)
8dabe7245bbc1 (Arnd Bergmann         2019-01-07 00:33:08 +0100 1395) COMPAT_SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds,
9afc5eee65ca7 (Arnd Bergmann         2018-07-13 12:52:28 +0200 1396) 	unsigned int,  nfds, struct old_timespec32 __user *, tsp,
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1397) 	const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize)
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1398) {
36819ad093e16 (Deepa Dinamani        2017-08-04 21:12:31 -0700 1399) 	struct timespec64 ts, end_time, *to = NULL;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1400) 	int ret;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1401) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1402) 	if (tsp) {
9afc5eee65ca7 (Arnd Bergmann         2018-07-13 12:52:28 +0200 1403) 		if (get_old_timespec32(&ts, tsp))
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1404) 			return -EFAULT;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1405) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1406) 		to = &end_time;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1407) 		if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1408) 			return -EINVAL;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1409) 	}
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1410) 
b772434be0891 (Oleg Nesterov         2019-07-16 16:29:53 -0700 1411) 	ret = set_compat_user_sigmask(sigmask, sigsetsize);
ded653ccbec03 (Deepa Dinamani        2018-09-19 21:41:04 -0700 1412) 	if (ret)
ded653ccbec03 (Deepa Dinamani        2018-09-19 21:41:04 -0700 1413) 		return ret;
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1414) 
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1415) 	ret = do_sys_poll(ufds, nfds, to);
ac301020627e2 (Oleg Nesterov         2019-07-16 16:29:59 -0700 1416) 	return poll_select_finish(&end_time, tsp, PT_OLD_TIMESPEC, ret);
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1417) }
e99ca56ce03dd (Al Viro               2017-04-08 16:50:24 -0400 1418) #endif
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1419) 
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1420) /* New compat syscall for 64 bit time_t*/
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1421) COMPAT_SYSCALL_DEFINE5(ppoll_time64, struct pollfd __user *, ufds,
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1422) 	unsigned int,  nfds, struct __kernel_timespec __user *, tsp,
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1423) 	const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize)
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1424) {
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1425) 	struct timespec64 ts, end_time, *to = NULL;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1426) 	int ret;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1427) 
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1428) 	if (tsp) {
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1429) 		if (get_timespec64(&ts, tsp))
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1430) 			return -EFAULT;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1431) 
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1432) 		to = &end_time;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1433) 		if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1434) 			return -EINVAL;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1435) 	}
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1436) 
b772434be0891 (Oleg Nesterov         2019-07-16 16:29:53 -0700 1437) 	ret = set_compat_user_sigmask(sigmask, sigsetsize);
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1438) 	if (ret)
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1439) 		return ret;
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1440) 
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1441) 	ret = do_sys_poll(ufds, nfds, to);
ac301020627e2 (Oleg Nesterov         2019-07-16 16:29:59 -0700 1442) 	return poll_select_finish(&end_time, tsp, PT_TIMESPEC, ret);
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1443) }
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1444) 
8bd27a3004e80 (Deepa Dinamani        2018-09-19 21:41:06 -0700 1445) #endif