forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/tty/n_tty.c
....@@ -50,8 +50,10 @@
5050 #include <linux/ratelimit.h>
5151 #include <linux/vmalloc.h>
5252
53
-
54
-/* number of characters left in xmit buffer before select has we have room */
53
+/*
54
+ * Until this number of characters is queued in the xmit buffer, select will
55
+ * return "we have room for writes".
56
+ */
5557 #define WAKEUP_CHARS 256
5658
5759 /*
....@@ -82,7 +84,7 @@
8284 #ifdef N_TTY_TRACE
8385 # define n_tty_trace(f, args...) trace_printk(f, ##args)
8486 #else
85
-# define n_tty_trace(f, args...)
87
+# define n_tty_trace(f, args...) no_printk(f, ##args)
8688 #endif
8789
8890 struct n_tty_data {
....@@ -162,29 +164,24 @@
162164 memset(buffer, 0x00, size);
163165 }
164166
165
-static int tty_copy_to_user(struct tty_struct *tty, void __user *to,
166
- size_t tail, size_t n)
167
+static void tty_copy(struct tty_struct *tty, void *to, size_t tail, size_t n)
167168 {
168169 struct n_tty_data *ldata = tty->disc_data;
169170 size_t size = N_TTY_BUF_SIZE - tail;
170171 void *from = read_buf_addr(ldata, tail);
171
- int uncopied;
172172
173173 if (n > size) {
174174 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;
175
+ memcpy(to, from, size);
176
+ zero_buffer(tty, from, size);
179177 to += size;
180178 n -= size;
181179 from = ldata->read_buf;
182180 }
183181
184182 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;
183
+ memcpy(to, from, n);
184
+ zero_buffer(tty, from, n);
188185 }
189186
190187 /**
....@@ -320,7 +317,7 @@
320317
321318 /**
322319 * reset_buffer_flags - reset buffer state
323
- * @tty: terminal to reset
320
+ * @ldata: line disc data to reset
324321 *
325322 * Reset the read buffer counters and clear the flags.
326323 * Called from n_tty_open() and n_tty_flush_buffer().
....@@ -548,9 +545,9 @@
548545 mutex_lock(&ldata->output_lock);
549546
550547 space = tty_write_room(tty);
551
- if (!space) {
548
+ if (space <= 0) {
552549 mutex_unlock(&ldata->output_lock);
553
- return 0;
550
+ return space;
554551 }
555552 if (nr > space)
556553 nr = space;
....@@ -652,9 +649,9 @@
652649 op = echo_buf(ldata, tail + 1);
653650
654651 switch (op) {
652
+ case ECHO_OP_ERASE_TAB: {
655653 unsigned int num_chars, num_bs;
656654
657
- case ECHO_OP_ERASE_TAB:
658655 if (MASK(ldata->echo_commit) == MASK(tail + 2))
659656 goto not_yet_stored;
660657 num_chars = echo_buf(ldata, tail + 2);
....@@ -685,7 +682,7 @@
685682 }
686683 tail += 3;
687684 break;
688
-
685
+ }
689686 case ECHO_OP_SET_CANON_COL:
690687 ldata->canon_column = ldata->column;
691688 tail += 2;
....@@ -904,7 +901,7 @@
904901 /**
905902 * echo_char_raw - echo a character raw
906903 * @c: unicode byte to echo
907
- * @tty: terminal device
904
+ * @ldata: line disc data
908905 *
909906 * Echo user input back onto the screen. This must be called only when
910907 * L_ECHO(tty) is true. Called from the driver receive_buf path.
....@@ -1940,42 +1937,38 @@
19401937 /**
19411938 * copy_from_read_buf - copy read data directly
19421939 * @tty: terminal device
1943
- * @b: user data
1940
+ * @kbp: data
19441941 * @nr: size of data
19451942 *
19461943 * 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.
1944
+ * ICANON is off; it copies characters straight from the tty queue.
19521945 *
19531946 * Called under the ldata->atomic_read_lock sem
1947
+ *
1948
+ * Returns true if it successfully copied data, but there is still
1949
+ * more data to be had.
19541950 *
19551951 * n_tty_read()/consumer path:
19561952 * caller holds non-exclusive termios_rwsem
19571953 * read_tail published
19581954 */
19591955
1960
-static int copy_from_read_buf(struct tty_struct *tty,
1961
- unsigned char __user **b,
1956
+static bool copy_from_read_buf(struct tty_struct *tty,
1957
+ unsigned char **kbp,
19621958 size_t *nr)
19631959
19641960 {
19651961 struct n_tty_data *ldata = tty->disc_data;
1966
- int retval;
19671962 size_t n;
19681963 bool is_eof;
19691964 size_t head = smp_load_acquire(&ldata->commit_head);
19701965 size_t tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1);
19711966
1972
- retval = 0;
19731967 n = min(head - ldata->read_tail, N_TTY_BUF_SIZE - tail);
19741968 n = min(*nr, n);
19751969 if (n) {
19761970 unsigned char *from = read_buf_addr(ldata, tail);
1977
- retval = copy_to_user(*b, from, n);
1978
- n -= retval;
1971
+ memcpy(*kbp, from, n);
19791972 is_eof = n == 1 && *from == EOF_CHAR(tty);
19801973 tty_audit_add_data(tty, from, n);
19811974 zero_buffer(tty, from, n);
....@@ -1983,22 +1976,25 @@
19831976 /* Turn single EOF into zero-length read */
19841977 if (L_EXTPROC(tty) && ldata->icanon && is_eof &&
19851978 (head == ldata->read_tail))
1986
- n = 0;
1987
- *b += n;
1979
+ return false;
1980
+ *kbp += n;
19881981 *nr -= n;
1982
+
1983
+ /* If we have more to copy, let the caller know */
1984
+ return head != ldata->read_tail;
19891985 }
1990
- return retval;
1986
+ return false;
19911987 }
19921988
19931989 /**
19941990 * canon_copy_from_read_buf - copy read data in canonical mode
19951991 * @tty: terminal device
1996
- * @b: user data
1992
+ * @kbp: data
19971993 * @nr: size of data
19981994 *
19991995 * Helper function for n_tty_read. It is only called when ICANON is on;
20001996 * it copies one line of input up to and including the line-delimiting
2001
- * character into the user-space buffer.
1997
+ * character into the result buffer.
20021998 *
20031999 * NB: When termios is changed from non-canonical to canonical mode and
20042000 * the read buffer contains data, n_tty_set_termios() simulates an EOF
....@@ -2013,21 +2009,22 @@
20132009 * read_tail published
20142010 */
20152011
2016
-static int canon_copy_from_read_buf(struct tty_struct *tty,
2017
- unsigned char __user **b,
2018
- size_t *nr)
2012
+static bool canon_copy_from_read_buf(struct tty_struct *tty,
2013
+ unsigned char **kbp,
2014
+ size_t *nr)
20192015 {
20202016 struct n_tty_data *ldata = tty->disc_data;
20212017 size_t n, size, more, c;
20222018 size_t eol;
2023
- size_t tail;
2024
- int ret, found = 0;
2019
+ size_t tail, canon_head;
2020
+ int found = 0;
20252021
20262022 /* N.B. avoid overrun if nr == 0 */
20272023 if (!*nr)
2028
- return 0;
2024
+ return false;
20292025
2030
- n = min(*nr + 1, smp_load_acquire(&ldata->canon_head) - ldata->read_tail);
2026
+ canon_head = smp_load_acquire(&ldata->canon_head);
2027
+ n = min(*nr, canon_head - ldata->read_tail);
20312028
20322029 tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1);
20332030 size = min_t(size_t, tail + n, N_TTY_BUF_SIZE);
....@@ -2049,18 +2046,14 @@
20492046 n += N_TTY_BUF_SIZE;
20502047 c = n + found;
20512048
2052
- if (!found || read_buf(ldata, eol) != __DISABLED_CHAR) {
2053
- c = min(*nr, c);
2049
+ if (!found || read_buf(ldata, eol) != __DISABLED_CHAR)
20542050 n = c;
2055
- }
20562051
20572052 n_tty_trace("%s: eol:%zu found:%d n:%zu c:%zu tail:%zu more:%zu\n",
20582053 __func__, eol, found, n, c, tail, more);
20592054
2060
- ret = tty_copy_to_user(tty, *b, tail, n);
2061
- if (ret)
2062
- return -EFAULT;
2063
- *b += n;
2055
+ tty_copy(tty, *kbp, tail, n);
2056
+ *kbp += n;
20642057 *nr -= n;
20652058
20662059 if (found)
....@@ -2073,12 +2066,41 @@
20732066 else
20742067 ldata->push = 0;
20752068 tty_audit_push();
2069
+ return false;
20762070 }
2077
- return 0;
2071
+
2072
+ /* No EOL found - do a continuation retry if there is more data */
2073
+ return ldata->read_tail != canon_head;
20782074 }
20792075
2080
-extern ssize_t redirected_tty_write(struct file *, const char __user *,
2081
- size_t, loff_t *);
2076
+/*
2077
+ * If we finished a read at the exact location of an
2078
+ * EOF (special EOL character that's a __DISABLED_CHAR)
2079
+ * in the stream, silently eat the EOF.
2080
+ */
2081
+static void canon_skip_eof(struct tty_struct *tty)
2082
+{
2083
+ struct n_tty_data *ldata = tty->disc_data;
2084
+ size_t tail, canon_head;
2085
+
2086
+ canon_head = smp_load_acquire(&ldata->canon_head);
2087
+ tail = ldata->read_tail;
2088
+
2089
+ // No data?
2090
+ if (tail == canon_head)
2091
+ return;
2092
+
2093
+ // See if the tail position is EOF in the circular buffer
2094
+ tail &= (N_TTY_BUF_SIZE - 1);
2095
+ if (!test_bit(tail, ldata->read_flags))
2096
+ return;
2097
+ if (read_buf(ldata, tail) != __DISABLED_CHAR)
2098
+ return;
2099
+
2100
+ // Clear the EOL bit, skip the EOF char.
2101
+ clear_bit(tail, ldata->read_flags);
2102
+ smp_store_release(&ldata->read_tail, ldata->read_tail + 1);
2103
+}
20822104
20832105 /**
20842106 * job_control - check job control
....@@ -2101,7 +2123,7 @@
21012123 /* NOTE: not yet done after every sleep pending a thorough
21022124 check of the logic of this change. -- jlc */
21032125 /* don't stop on /dev/console */
2104
- if (file->f_op->write == redirected_tty_write)
2126
+ if (file->f_op->write_iter == redirected_tty_write)
21052127 return 0;
21062128
21072129 return __tty_check_change(tty, SIGTTIN);
....@@ -2128,10 +2150,11 @@
21282150 */
21292151
21302152 static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
2131
- unsigned char __user *buf, size_t nr)
2153
+ unsigned char *kbuf, size_t nr,
2154
+ void **cookie, unsigned long offset)
21322155 {
21332156 struct n_tty_data *ldata = tty->disc_data;
2134
- unsigned char __user *b = buf;
2157
+ unsigned char *kb = kbuf;
21352158 DEFINE_WAIT_FUNC(wait, woken_wake_function);
21362159 int c;
21372160 int minimum, time;
....@@ -2139,6 +2162,37 @@
21392162 long timeout;
21402163 int packet;
21412164 size_t tail;
2165
+
2166
+ /*
2167
+ * Is this a continuation of a read started earler?
2168
+ *
2169
+ * If so, we still hold the atomic_read_lock and the
2170
+ * termios_rwsem, and can just continue to copy data.
2171
+ */
2172
+ if (*cookie) {
2173
+ if (ldata->icanon && !L_EXTPROC(tty)) {
2174
+ /*
2175
+ * If we have filled the user buffer, see
2176
+ * if we should skip an EOF character before
2177
+ * releasing the lock and returning done.
2178
+ */
2179
+ if (!nr)
2180
+ canon_skip_eof(tty);
2181
+ else if (canon_copy_from_read_buf(tty, &kb, &nr))
2182
+ return kb - kbuf;
2183
+ } else {
2184
+ if (copy_from_read_buf(tty, &kb, &nr))
2185
+ return kb - kbuf;
2186
+ }
2187
+
2188
+ /* No more data - release locks and stop retries */
2189
+ n_tty_kick_worker(tty);
2190
+ n_tty_check_unthrottle(tty);
2191
+ up_read(&tty->termios_rwsem);
2192
+ mutex_unlock(&ldata->atomic_read_lock);
2193
+ *cookie = NULL;
2194
+ return kb - kbuf;
2195
+ }
21422196
21432197 c = job_control(tty, file);
21442198 if (c < 0)
....@@ -2177,17 +2231,13 @@
21772231 /* First test for status change. */
21782232 if (packet && tty->link->ctrl_status) {
21792233 unsigned char cs;
2180
- if (b != buf)
2234
+ if (kb != kbuf)
21812235 break;
21822236 spin_lock_irq(&tty->link->ctrl_lock);
21832237 cs = tty->link->ctrl_status;
21842238 tty->link->ctrl_status = 0;
21852239 spin_unlock_irq(&tty->link->ctrl_lock);
2186
- if (put_user(cs, b)) {
2187
- retval = -EFAULT;
2188
- break;
2189
- }
2190
- b++;
2240
+ *kb++ = cs;
21912241 nr--;
21922242 break;
21932243 }
....@@ -2230,33 +2280,35 @@
22302280 }
22312281
22322282 if (ldata->icanon && !L_EXTPROC(tty)) {
2233
- retval = canon_copy_from_read_buf(tty, &b, &nr);
2234
- if (retval)
2235
- break;
2283
+ if (canon_copy_from_read_buf(tty, &kb, &nr))
2284
+ goto more_to_be_read;
22362285 } else {
2237
- int uncopied;
2238
-
22392286 /* Deal with packet mode. */
2240
- if (packet && b == buf) {
2241
- if (put_user(TIOCPKT_DATA, b)) {
2242
- retval = -EFAULT;
2243
- break;
2244
- }
2245
- b++;
2287
+ if (packet && kb == kbuf) {
2288
+ *kb++ = TIOCPKT_DATA;
22462289 nr--;
22472290 }
22482291
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;
2292
+ /*
2293
+ * Copy data, and if there is more to be had
2294
+ * and we have nothing more to wait for, then
2295
+ * let's mark us for retries.
2296
+ *
2297
+ * NOTE! We return here with both the termios_sem
2298
+ * and atomic_read_lock still held, the retries
2299
+ * will release them when done.
2300
+ */
2301
+ if (copy_from_read_buf(tty, &kb, &nr) && kb - kbuf >= minimum) {
2302
+more_to_be_read:
2303
+ remove_wait_queue(&tty->read_wait, &wait);
2304
+ *cookie = cookie;
2305
+ return kb - kbuf;
22542306 }
22552307 }
22562308
22572309 n_tty_check_unthrottle(tty);
22582310
2259
- if (b - buf >= minimum)
2311
+ if (kb - kbuf >= minimum)
22602312 break;
22612313 if (time)
22622314 timeout = time;
....@@ -2268,8 +2320,8 @@
22682320 remove_wait_queue(&tty->read_wait, &wait);
22692321 mutex_unlock(&ldata->atomic_read_lock);
22702322
2271
- if (b - buf)
2272
- retval = b - buf;
2323
+ if (kb - kbuf)
2324
+ retval = kb - kbuf;
22732325
22742326 return retval;
22752327 }
....@@ -2305,7 +2357,7 @@
23052357 ssize_t retval = 0;
23062358
23072359 /* 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) {
2360
+ if (L_TOSTOP(tty) && file->f_op->write_iter != redirected_tty_write) {
23092361 retval = tty_check_change(tty);
23102362 if (retval)
23112363 return retval;