hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/tty/n_tty.c
....@@ -49,9 +49,12 @@
4949 #include <linux/module.h>
5050 #include <linux/ratelimit.h>
5151 #include <linux/vmalloc.h>
52
+#include "tty.h"
5253
53
-
54
-/* number of characters left in xmit buffer before select has we have room */
54
+/*
55
+ * Until this number of characters is queued in the xmit buffer, select will
56
+ * return "we have room for writes".
57
+ */
5558 #define WAKEUP_CHARS 256
5659
5760 /*
....@@ -82,7 +85,7 @@
8285 #ifdef N_TTY_TRACE
8386 # define n_tty_trace(f, args...) trace_printk(f, ##args)
8487 #else
85
-# define n_tty_trace(f, args...)
88
+# define n_tty_trace(f, args...) no_printk(f, ##args)
8689 #endif
8790
8891 struct n_tty_data {
....@@ -162,29 +165,24 @@
162165 memset(buffer, 0x00, size);
163166 }
164167
165
-static int tty_copy_to_user(struct tty_struct *tty, void __user *to,
166
- size_t tail, size_t n)
168
+static void tty_copy(struct tty_struct *tty, void *to, size_t tail, size_t n)
167169 {
168170 struct n_tty_data *ldata = tty->disc_data;
169171 size_t size = N_TTY_BUF_SIZE - tail;
170172 void *from = read_buf_addr(ldata, tail);
171
- int uncopied;
172173
173174 if (n > size) {
174175 tty_audit_add_data(tty, from, size);
175
- uncopied = copy_to_user(to, from, size);
176
- zero_buffer(tty, from, size - uncopied);
177
- if (uncopied)
178
- return uncopied;
176
+ memcpy(to, from, size);
177
+ zero_buffer(tty, from, size);
179178 to += size;
180179 n -= size;
181180 from = ldata->read_buf;
182181 }
183182
184183 tty_audit_add_data(tty, from, n);
185
- uncopied = copy_to_user(to, from, n);
186
- zero_buffer(tty, from, n - uncopied);
187
- return uncopied;
184
+ memcpy(to, from, n);
185
+ zero_buffer(tty, from, n);
188186 }
189187
190188 /**
....@@ -320,7 +318,7 @@
320318
321319 /**
322320 * reset_buffer_flags - reset buffer state
323
- * @tty: terminal to reset
321
+ * @ldata: line disc data to reset
324322 *
325323 * Reset the read buffer counters and clear the flags.
326324 * Called from n_tty_open() and n_tty_flush_buffer().
....@@ -548,9 +546,9 @@
548546 mutex_lock(&ldata->output_lock);
549547
550548 space = tty_write_room(tty);
551
- if (!space) {
549
+ if (space <= 0) {
552550 mutex_unlock(&ldata->output_lock);
553
- return 0;
551
+ return space;
554552 }
555553 if (nr > space)
556554 nr = space;
....@@ -652,9 +650,9 @@
652650 op = echo_buf(ldata, tail + 1);
653651
654652 switch (op) {
653
+ case ECHO_OP_ERASE_TAB: {
655654 unsigned int num_chars, num_bs;
656655
657
- case ECHO_OP_ERASE_TAB:
658656 if (MASK(ldata->echo_commit) == MASK(tail + 2))
659657 goto not_yet_stored;
660658 num_chars = echo_buf(ldata, tail + 2);
....@@ -685,7 +683,7 @@
685683 }
686684 tail += 3;
687685 break;
688
-
686
+ }
689687 case ECHO_OP_SET_CANON_COL:
690688 ldata->canon_column = ldata->column;
691689 tail += 2;
....@@ -904,7 +902,7 @@
904902 /**
905903 * echo_char_raw - echo a character raw
906904 * @c: unicode byte to echo
907
- * @tty: terminal device
905
+ * @ldata: line disc data
908906 *
909907 * Echo user input back onto the screen. This must be called only when
910908 * L_ECHO(tty) is true. Called from the driver receive_buf path.
....@@ -1940,42 +1938,38 @@
19401938 /**
19411939 * copy_from_read_buf - copy read data directly
19421940 * @tty: terminal device
1943
- * @b: user data
1941
+ * @kbp: data
19441942 * @nr: size of data
19451943 *
19461944 * Helper function to speed up n_tty_read. It is only called when
1947
- * ICANON is off; it copies characters straight from the tty queue to
1948
- * user space directly. It can be profitably called twice; once to
1949
- * drain the space from the tail pointer to the (physical) end of the
1950
- * buffer, and once to drain the space from the (physical) beginning of
1951
- * the buffer to head pointer.
1945
+ * ICANON is off; it copies characters straight from the tty queue.
19521946 *
19531947 * Called under the ldata->atomic_read_lock sem
1948
+ *
1949
+ * Returns true if it successfully copied data, but there is still
1950
+ * more data to be had.
19541951 *
19551952 * n_tty_read()/consumer path:
19561953 * caller holds non-exclusive termios_rwsem
19571954 * read_tail published
19581955 */
19591956
1960
-static int copy_from_read_buf(struct tty_struct *tty,
1961
- unsigned char __user **b,
1957
+static bool copy_from_read_buf(struct tty_struct *tty,
1958
+ unsigned char **kbp,
19621959 size_t *nr)
19631960
19641961 {
19651962 struct n_tty_data *ldata = tty->disc_data;
1966
- int retval;
19671963 size_t n;
19681964 bool is_eof;
19691965 size_t head = smp_load_acquire(&ldata->commit_head);
19701966 size_t tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1);
19711967
1972
- retval = 0;
19731968 n = min(head - ldata->read_tail, N_TTY_BUF_SIZE - tail);
19741969 n = min(*nr, n);
19751970 if (n) {
19761971 unsigned char *from = read_buf_addr(ldata, tail);
1977
- retval = copy_to_user(*b, from, n);
1978
- n -= retval;
1972
+ memcpy(*kbp, from, n);
19791973 is_eof = n == 1 && *from == EOF_CHAR(tty);
19801974 tty_audit_add_data(tty, from, n);
19811975 zero_buffer(tty, from, n);
....@@ -1983,22 +1977,25 @@
19831977 /* Turn single EOF into zero-length read */
19841978 if (L_EXTPROC(tty) && ldata->icanon && is_eof &&
19851979 (head == ldata->read_tail))
1986
- n = 0;
1987
- *b += n;
1980
+ return false;
1981
+ *kbp += n;
19881982 *nr -= n;
1983
+
1984
+ /* If we have more to copy, let the caller know */
1985
+ return head != ldata->read_tail;
19891986 }
1990
- return retval;
1987
+ return false;
19911988 }
19921989
19931990 /**
19941991 * canon_copy_from_read_buf - copy read data in canonical mode
19951992 * @tty: terminal device
1996
- * @b: user data
1993
+ * @kbp: data
19971994 * @nr: size of data
19981995 *
19991996 * Helper function for n_tty_read. It is only called when ICANON is on;
20001997 * it copies one line of input up to and including the line-delimiting
2001
- * character into the user-space buffer.
1998
+ * character into the result buffer.
20021999 *
20032000 * NB: When termios is changed from non-canonical to canonical mode and
20042001 * the read buffer contains data, n_tty_set_termios() simulates an EOF
....@@ -2013,21 +2010,22 @@
20132010 * read_tail published
20142011 */
20152012
2016
-static int canon_copy_from_read_buf(struct tty_struct *tty,
2017
- unsigned char __user **b,
2018
- size_t *nr)
2013
+static bool canon_copy_from_read_buf(struct tty_struct *tty,
2014
+ unsigned char **kbp,
2015
+ size_t *nr)
20192016 {
20202017 struct n_tty_data *ldata = tty->disc_data;
20212018 size_t n, size, more, c;
20222019 size_t eol;
2023
- size_t tail;
2024
- int ret, found = 0;
2020
+ size_t tail, canon_head;
2021
+ int found = 0;
20252022
20262023 /* N.B. avoid overrun if nr == 0 */
20272024 if (!*nr)
2028
- return 0;
2025
+ return false;
20292026
2030
- n = min(*nr + 1, smp_load_acquire(&ldata->canon_head) - ldata->read_tail);
2027
+ canon_head = smp_load_acquire(&ldata->canon_head);
2028
+ n = min(*nr, canon_head - ldata->read_tail);
20312029
20322030 tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1);
20332031 size = min_t(size_t, tail + n, N_TTY_BUF_SIZE);
....@@ -2049,18 +2047,14 @@
20492047 n += N_TTY_BUF_SIZE;
20502048 c = n + found;
20512049
2052
- if (!found || read_buf(ldata, eol) != __DISABLED_CHAR) {
2053
- c = min(*nr, c);
2050
+ if (!found || read_buf(ldata, eol) != __DISABLED_CHAR)
20542051 n = c;
2055
- }
20562052
20572053 n_tty_trace("%s: eol:%zu found:%d n:%zu c:%zu tail:%zu more:%zu\n",
20582054 __func__, eol, found, n, c, tail, more);
20592055
2060
- ret = tty_copy_to_user(tty, *b, tail, n);
2061
- if (ret)
2062
- return -EFAULT;
2063
- *b += n;
2056
+ tty_copy(tty, *kbp, tail, n);
2057
+ *kbp += n;
20642058 *nr -= n;
20652059
20662060 if (found)
....@@ -2073,12 +2067,41 @@
20732067 else
20742068 ldata->push = 0;
20752069 tty_audit_push();
2070
+ return false;
20762071 }
2077
- return 0;
2072
+
2073
+ /* No EOL found - do a continuation retry if there is more data */
2074
+ return ldata->read_tail != canon_head;
20782075 }
20792076
2080
-extern ssize_t redirected_tty_write(struct file *, const char __user *,
2081
- size_t, loff_t *);
2077
+/*
2078
+ * If we finished a read at the exact location of an
2079
+ * EOF (special EOL character that's a __DISABLED_CHAR)
2080
+ * in the stream, silently eat the EOF.
2081
+ */
2082
+static void canon_skip_eof(struct tty_struct *tty)
2083
+{
2084
+ struct n_tty_data *ldata = tty->disc_data;
2085
+ size_t tail, canon_head;
2086
+
2087
+ canon_head = smp_load_acquire(&ldata->canon_head);
2088
+ tail = ldata->read_tail;
2089
+
2090
+ // No data?
2091
+ if (tail == canon_head)
2092
+ return;
2093
+
2094
+ // See if the tail position is EOF in the circular buffer
2095
+ tail &= (N_TTY_BUF_SIZE - 1);
2096
+ if (!test_bit(tail, ldata->read_flags))
2097
+ return;
2098
+ if (read_buf(ldata, tail) != __DISABLED_CHAR)
2099
+ return;
2100
+
2101
+ // Clear the EOL bit, skip the EOF char.
2102
+ clear_bit(tail, ldata->read_flags);
2103
+ smp_store_release(&ldata->read_tail, ldata->read_tail + 1);
2104
+}
20822105
20832106 /**
20842107 * job_control - check job control
....@@ -2101,7 +2124,7 @@
21012124 /* NOTE: not yet done after every sleep pending a thorough
21022125 check of the logic of this change. -- jlc */
21032126 /* don't stop on /dev/console */
2104
- if (file->f_op->write == redirected_tty_write)
2127
+ if (file->f_op->write_iter == redirected_tty_write)
21052128 return 0;
21062129
21072130 return __tty_check_change(tty, SIGTTIN);
....@@ -2128,10 +2151,11 @@
21282151 */
21292152
21302153 static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
2131
- unsigned char __user *buf, size_t nr)
2154
+ unsigned char *kbuf, size_t nr,
2155
+ void **cookie, unsigned long offset)
21322156 {
21332157 struct n_tty_data *ldata = tty->disc_data;
2134
- unsigned char __user *b = buf;
2158
+ unsigned char *kb = kbuf;
21352159 DEFINE_WAIT_FUNC(wait, woken_wake_function);
21362160 int c;
21372161 int minimum, time;
....@@ -2139,6 +2163,37 @@
21392163 long timeout;
21402164 int packet;
21412165 size_t tail;
2166
+
2167
+ /*
2168
+ * Is this a continuation of a read started earler?
2169
+ *
2170
+ * If so, we still hold the atomic_read_lock and the
2171
+ * termios_rwsem, and can just continue to copy data.
2172
+ */
2173
+ if (*cookie) {
2174
+ if (ldata->icanon && !L_EXTPROC(tty)) {
2175
+ /*
2176
+ * If we have filled the user buffer, see
2177
+ * if we should skip an EOF character before
2178
+ * releasing the lock and returning done.
2179
+ */
2180
+ if (!nr)
2181
+ canon_skip_eof(tty);
2182
+ else if (canon_copy_from_read_buf(tty, &kb, &nr))
2183
+ return kb - kbuf;
2184
+ } else {
2185
+ if (copy_from_read_buf(tty, &kb, &nr))
2186
+ return kb - kbuf;
2187
+ }
2188
+
2189
+ /* No more data - release locks and stop retries */
2190
+ n_tty_kick_worker(tty);
2191
+ n_tty_check_unthrottle(tty);
2192
+ up_read(&tty->termios_rwsem);
2193
+ mutex_unlock(&ldata->atomic_read_lock);
2194
+ *cookie = NULL;
2195
+ return kb - kbuf;
2196
+ }
21422197
21432198 c = job_control(tty, file);
21442199 if (c < 0)
....@@ -2177,17 +2232,13 @@
21772232 /* First test for status change. */
21782233 if (packet && tty->link->ctrl_status) {
21792234 unsigned char cs;
2180
- if (b != buf)
2235
+ if (kb != kbuf)
21812236 break;
21822237 spin_lock_irq(&tty->link->ctrl_lock);
21832238 cs = tty->link->ctrl_status;
21842239 tty->link->ctrl_status = 0;
21852240 spin_unlock_irq(&tty->link->ctrl_lock);
2186
- if (put_user(cs, b)) {
2187
- retval = -EFAULT;
2188
- break;
2189
- }
2190
- b++;
2241
+ *kb++ = cs;
21912242 nr--;
21922243 break;
21932244 }
....@@ -2230,33 +2281,35 @@
22302281 }
22312282
22322283 if (ldata->icanon && !L_EXTPROC(tty)) {
2233
- retval = canon_copy_from_read_buf(tty, &b, &nr);
2234
- if (retval)
2235
- break;
2284
+ if (canon_copy_from_read_buf(tty, &kb, &nr))
2285
+ goto more_to_be_read;
22362286 } else {
2237
- int uncopied;
2238
-
22392287 /* Deal with packet mode. */
2240
- if (packet && b == buf) {
2241
- if (put_user(TIOCPKT_DATA, b)) {
2242
- retval = -EFAULT;
2243
- break;
2244
- }
2245
- b++;
2288
+ if (packet && kb == kbuf) {
2289
+ *kb++ = TIOCPKT_DATA;
22462290 nr--;
22472291 }
22482292
2249
- uncopied = copy_from_read_buf(tty, &b, &nr);
2250
- uncopied += copy_from_read_buf(tty, &b, &nr);
2251
- if (uncopied) {
2252
- retval = -EFAULT;
2253
- break;
2293
+ /*
2294
+ * Copy data, and if there is more to be had
2295
+ * and we have nothing more to wait for, then
2296
+ * let's mark us for retries.
2297
+ *
2298
+ * NOTE! We return here with both the termios_sem
2299
+ * and atomic_read_lock still held, the retries
2300
+ * will release them when done.
2301
+ */
2302
+ if (copy_from_read_buf(tty, &kb, &nr) && kb - kbuf >= minimum) {
2303
+more_to_be_read:
2304
+ remove_wait_queue(&tty->read_wait, &wait);
2305
+ *cookie = cookie;
2306
+ return kb - kbuf;
22542307 }
22552308 }
22562309
22572310 n_tty_check_unthrottle(tty);
22582311
2259
- if (b - buf >= minimum)
2312
+ if (kb - kbuf >= minimum)
22602313 break;
22612314 if (time)
22622315 timeout = time;
....@@ -2268,8 +2321,8 @@
22682321 remove_wait_queue(&tty->read_wait, &wait);
22692322 mutex_unlock(&ldata->atomic_read_lock);
22702323
2271
- if (b - buf)
2272
- retval = b - buf;
2324
+ if (kb - kbuf)
2325
+ retval = kb - kbuf;
22732326
22742327 return retval;
22752328 }
....@@ -2305,7 +2358,7 @@
23052358 ssize_t retval = 0;
23062359
23072360 /* Job control check -- must be done at start (POSIX.1 7.1.1.4). */
2308
- if (L_TOSTOP(tty) && file->f_op->write != redirected_tty_write) {
2361
+ if (L_TOSTOP(tty) && file->f_op->write_iter != redirected_tty_write) {
23092362 retval = tty_check_change(tty);
23102363 if (retval)
23112364 return retval;