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 = ¤t->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