.. | .. |
---|
49 | 49 | #include <linux/module.h> |
---|
50 | 50 | #include <linux/ratelimit.h> |
---|
51 | 51 | #include <linux/vmalloc.h> |
---|
| 52 | +#include "tty.h" |
---|
52 | 53 | |
---|
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 | + */ |
---|
55 | 58 | #define WAKEUP_CHARS 256 |
---|
56 | 59 | |
---|
57 | 60 | /* |
---|
.. | .. |
---|
82 | 85 | #ifdef N_TTY_TRACE |
---|
83 | 86 | # define n_tty_trace(f, args...) trace_printk(f, ##args) |
---|
84 | 87 | #else |
---|
85 | | -# define n_tty_trace(f, args...) |
---|
| 88 | +# define n_tty_trace(f, args...) no_printk(f, ##args) |
---|
86 | 89 | #endif |
---|
87 | 90 | |
---|
88 | 91 | struct n_tty_data { |
---|
.. | .. |
---|
162 | 165 | memset(buffer, 0x00, size); |
---|
163 | 166 | } |
---|
164 | 167 | |
---|
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) |
---|
167 | 169 | { |
---|
168 | 170 | struct n_tty_data *ldata = tty->disc_data; |
---|
169 | 171 | size_t size = N_TTY_BUF_SIZE - tail; |
---|
170 | 172 | void *from = read_buf_addr(ldata, tail); |
---|
171 | | - int uncopied; |
---|
172 | 173 | |
---|
173 | 174 | if (n > size) { |
---|
174 | 175 | 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); |
---|
179 | 178 | to += size; |
---|
180 | 179 | n -= size; |
---|
181 | 180 | from = ldata->read_buf; |
---|
182 | 181 | } |
---|
183 | 182 | |
---|
184 | 183 | 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); |
---|
188 | 186 | } |
---|
189 | 187 | |
---|
190 | 188 | /** |
---|
.. | .. |
---|
320 | 318 | |
---|
321 | 319 | /** |
---|
322 | 320 | * reset_buffer_flags - reset buffer state |
---|
323 | | - * @tty: terminal to reset |
---|
| 321 | + * @ldata: line disc data to reset |
---|
324 | 322 | * |
---|
325 | 323 | * Reset the read buffer counters and clear the flags. |
---|
326 | 324 | * Called from n_tty_open() and n_tty_flush_buffer(). |
---|
.. | .. |
---|
548 | 546 | mutex_lock(&ldata->output_lock); |
---|
549 | 547 | |
---|
550 | 548 | space = tty_write_room(tty); |
---|
551 | | - if (!space) { |
---|
| 549 | + if (space <= 0) { |
---|
552 | 550 | mutex_unlock(&ldata->output_lock); |
---|
553 | | - return 0; |
---|
| 551 | + return space; |
---|
554 | 552 | } |
---|
555 | 553 | if (nr > space) |
---|
556 | 554 | nr = space; |
---|
.. | .. |
---|
652 | 650 | op = echo_buf(ldata, tail + 1); |
---|
653 | 651 | |
---|
654 | 652 | switch (op) { |
---|
| 653 | + case ECHO_OP_ERASE_TAB: { |
---|
655 | 654 | unsigned int num_chars, num_bs; |
---|
656 | 655 | |
---|
657 | | - case ECHO_OP_ERASE_TAB: |
---|
658 | 656 | if (MASK(ldata->echo_commit) == MASK(tail + 2)) |
---|
659 | 657 | goto not_yet_stored; |
---|
660 | 658 | num_chars = echo_buf(ldata, tail + 2); |
---|
.. | .. |
---|
685 | 683 | } |
---|
686 | 684 | tail += 3; |
---|
687 | 685 | break; |
---|
688 | | - |
---|
| 686 | + } |
---|
689 | 687 | case ECHO_OP_SET_CANON_COL: |
---|
690 | 688 | ldata->canon_column = ldata->column; |
---|
691 | 689 | tail += 2; |
---|
.. | .. |
---|
904 | 902 | /** |
---|
905 | 903 | * echo_char_raw - echo a character raw |
---|
906 | 904 | * @c: unicode byte to echo |
---|
907 | | - * @tty: terminal device |
---|
| 905 | + * @ldata: line disc data |
---|
908 | 906 | * |
---|
909 | 907 | * Echo user input back onto the screen. This must be called only when |
---|
910 | 908 | * L_ECHO(tty) is true. Called from the driver receive_buf path. |
---|
.. | .. |
---|
1940 | 1938 | /** |
---|
1941 | 1939 | * copy_from_read_buf - copy read data directly |
---|
1942 | 1940 | * @tty: terminal device |
---|
1943 | | - * @b: user data |
---|
| 1941 | + * @kbp: data |
---|
1944 | 1942 | * @nr: size of data |
---|
1945 | 1943 | * |
---|
1946 | 1944 | * 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. |
---|
1952 | 1946 | * |
---|
1953 | 1947 | * 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. |
---|
1954 | 1951 | * |
---|
1955 | 1952 | * n_tty_read()/consumer path: |
---|
1956 | 1953 | * caller holds non-exclusive termios_rwsem |
---|
1957 | 1954 | * read_tail published |
---|
1958 | 1955 | */ |
---|
1959 | 1956 | |
---|
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, |
---|
1962 | 1959 | size_t *nr) |
---|
1963 | 1960 | |
---|
1964 | 1961 | { |
---|
1965 | 1962 | struct n_tty_data *ldata = tty->disc_data; |
---|
1966 | | - int retval; |
---|
1967 | 1963 | size_t n; |
---|
1968 | 1964 | bool is_eof; |
---|
1969 | 1965 | size_t head = smp_load_acquire(&ldata->commit_head); |
---|
1970 | 1966 | size_t tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1); |
---|
1971 | 1967 | |
---|
1972 | | - retval = 0; |
---|
1973 | 1968 | n = min(head - ldata->read_tail, N_TTY_BUF_SIZE - tail); |
---|
1974 | 1969 | n = min(*nr, n); |
---|
1975 | 1970 | if (n) { |
---|
1976 | 1971 | unsigned char *from = read_buf_addr(ldata, tail); |
---|
1977 | | - retval = copy_to_user(*b, from, n); |
---|
1978 | | - n -= retval; |
---|
| 1972 | + memcpy(*kbp, from, n); |
---|
1979 | 1973 | is_eof = n == 1 && *from == EOF_CHAR(tty); |
---|
1980 | 1974 | tty_audit_add_data(tty, from, n); |
---|
1981 | 1975 | zero_buffer(tty, from, n); |
---|
.. | .. |
---|
1983 | 1977 | /* Turn single EOF into zero-length read */ |
---|
1984 | 1978 | if (L_EXTPROC(tty) && ldata->icanon && is_eof && |
---|
1985 | 1979 | (head == ldata->read_tail)) |
---|
1986 | | - n = 0; |
---|
1987 | | - *b += n; |
---|
| 1980 | + return false; |
---|
| 1981 | + *kbp += n; |
---|
1988 | 1982 | *nr -= n; |
---|
| 1983 | + |
---|
| 1984 | + /* If we have more to copy, let the caller know */ |
---|
| 1985 | + return head != ldata->read_tail; |
---|
1989 | 1986 | } |
---|
1990 | | - return retval; |
---|
| 1987 | + return false; |
---|
1991 | 1988 | } |
---|
1992 | 1989 | |
---|
1993 | 1990 | /** |
---|
1994 | 1991 | * canon_copy_from_read_buf - copy read data in canonical mode |
---|
1995 | 1992 | * @tty: terminal device |
---|
1996 | | - * @b: user data |
---|
| 1993 | + * @kbp: data |
---|
1997 | 1994 | * @nr: size of data |
---|
1998 | 1995 | * |
---|
1999 | 1996 | * Helper function for n_tty_read. It is only called when ICANON is on; |
---|
2000 | 1997 | * 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. |
---|
2002 | 1999 | * |
---|
2003 | 2000 | * NB: When termios is changed from non-canonical to canonical mode and |
---|
2004 | 2001 | * the read buffer contains data, n_tty_set_termios() simulates an EOF |
---|
.. | .. |
---|
2013 | 2010 | * read_tail published |
---|
2014 | 2011 | */ |
---|
2015 | 2012 | |
---|
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) |
---|
2019 | 2016 | { |
---|
2020 | 2017 | struct n_tty_data *ldata = tty->disc_data; |
---|
2021 | 2018 | size_t n, size, more, c; |
---|
2022 | 2019 | size_t eol; |
---|
2023 | | - size_t tail; |
---|
2024 | | - int ret, found = 0; |
---|
| 2020 | + size_t tail, canon_head; |
---|
| 2021 | + int found = 0; |
---|
2025 | 2022 | |
---|
2026 | 2023 | /* N.B. avoid overrun if nr == 0 */ |
---|
2027 | 2024 | if (!*nr) |
---|
2028 | | - return 0; |
---|
| 2025 | + return false; |
---|
2029 | 2026 | |
---|
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); |
---|
2031 | 2029 | |
---|
2032 | 2030 | tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1); |
---|
2033 | 2031 | size = min_t(size_t, tail + n, N_TTY_BUF_SIZE); |
---|
.. | .. |
---|
2049 | 2047 | n += N_TTY_BUF_SIZE; |
---|
2050 | 2048 | c = n + found; |
---|
2051 | 2049 | |
---|
2052 | | - if (!found || read_buf(ldata, eol) != __DISABLED_CHAR) { |
---|
2053 | | - c = min(*nr, c); |
---|
| 2050 | + if (!found || read_buf(ldata, eol) != __DISABLED_CHAR) |
---|
2054 | 2051 | n = c; |
---|
2055 | | - } |
---|
2056 | 2052 | |
---|
2057 | 2053 | n_tty_trace("%s: eol:%zu found:%d n:%zu c:%zu tail:%zu more:%zu\n", |
---|
2058 | 2054 | __func__, eol, found, n, c, tail, more); |
---|
2059 | 2055 | |
---|
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; |
---|
2064 | 2058 | *nr -= n; |
---|
2065 | 2059 | |
---|
2066 | 2060 | if (found) |
---|
.. | .. |
---|
2073 | 2067 | else |
---|
2074 | 2068 | ldata->push = 0; |
---|
2075 | 2069 | tty_audit_push(); |
---|
| 2070 | + return false; |
---|
2076 | 2071 | } |
---|
2077 | | - return 0; |
---|
| 2072 | + |
---|
| 2073 | + /* No EOL found - do a continuation retry if there is more data */ |
---|
| 2074 | + return ldata->read_tail != canon_head; |
---|
2078 | 2075 | } |
---|
2079 | 2076 | |
---|
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 | +} |
---|
2082 | 2105 | |
---|
2083 | 2106 | /** |
---|
2084 | 2107 | * job_control - check job control |
---|
.. | .. |
---|
2101 | 2124 | /* NOTE: not yet done after every sleep pending a thorough |
---|
2102 | 2125 | check of the logic of this change. -- jlc */ |
---|
2103 | 2126 | /* 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) |
---|
2105 | 2128 | return 0; |
---|
2106 | 2129 | |
---|
2107 | 2130 | return __tty_check_change(tty, SIGTTIN); |
---|
.. | .. |
---|
2128 | 2151 | */ |
---|
2129 | 2152 | |
---|
2130 | 2153 | 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) |
---|
2132 | 2156 | { |
---|
2133 | 2157 | struct n_tty_data *ldata = tty->disc_data; |
---|
2134 | | - unsigned char __user *b = buf; |
---|
| 2158 | + unsigned char *kb = kbuf; |
---|
2135 | 2159 | DEFINE_WAIT_FUNC(wait, woken_wake_function); |
---|
2136 | 2160 | int c; |
---|
2137 | 2161 | int minimum, time; |
---|
.. | .. |
---|
2139 | 2163 | long timeout; |
---|
2140 | 2164 | int packet; |
---|
2141 | 2165 | 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 | + } |
---|
2142 | 2197 | |
---|
2143 | 2198 | c = job_control(tty, file); |
---|
2144 | 2199 | if (c < 0) |
---|
.. | .. |
---|
2177 | 2232 | /* First test for status change. */ |
---|
2178 | 2233 | if (packet && tty->link->ctrl_status) { |
---|
2179 | 2234 | unsigned char cs; |
---|
2180 | | - if (b != buf) |
---|
| 2235 | + if (kb != kbuf) |
---|
2181 | 2236 | break; |
---|
2182 | 2237 | spin_lock_irq(&tty->link->ctrl_lock); |
---|
2183 | 2238 | cs = tty->link->ctrl_status; |
---|
2184 | 2239 | tty->link->ctrl_status = 0; |
---|
2185 | 2240 | spin_unlock_irq(&tty->link->ctrl_lock); |
---|
2186 | | - if (put_user(cs, b)) { |
---|
2187 | | - retval = -EFAULT; |
---|
2188 | | - break; |
---|
2189 | | - } |
---|
2190 | | - b++; |
---|
| 2241 | + *kb++ = cs; |
---|
2191 | 2242 | nr--; |
---|
2192 | 2243 | break; |
---|
2193 | 2244 | } |
---|
.. | .. |
---|
2230 | 2281 | } |
---|
2231 | 2282 | |
---|
2232 | 2283 | 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; |
---|
2236 | 2286 | } else { |
---|
2237 | | - int uncopied; |
---|
2238 | | - |
---|
2239 | 2287 | /* 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; |
---|
2246 | 2290 | nr--; |
---|
2247 | 2291 | } |
---|
2248 | 2292 | |
---|
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; |
---|
2254 | 2307 | } |
---|
2255 | 2308 | } |
---|
2256 | 2309 | |
---|
2257 | 2310 | n_tty_check_unthrottle(tty); |
---|
2258 | 2311 | |
---|
2259 | | - if (b - buf >= minimum) |
---|
| 2312 | + if (kb - kbuf >= minimum) |
---|
2260 | 2313 | break; |
---|
2261 | 2314 | if (time) |
---|
2262 | 2315 | timeout = time; |
---|
.. | .. |
---|
2268 | 2321 | remove_wait_queue(&tty->read_wait, &wait); |
---|
2269 | 2322 | mutex_unlock(&ldata->atomic_read_lock); |
---|
2270 | 2323 | |
---|
2271 | | - if (b - buf) |
---|
2272 | | - retval = b - buf; |
---|
| 2324 | + if (kb - kbuf) |
---|
| 2325 | + retval = kb - kbuf; |
---|
2273 | 2326 | |
---|
2274 | 2327 | return retval; |
---|
2275 | 2328 | } |
---|
.. | .. |
---|
2305 | 2358 | ssize_t retval = 0; |
---|
2306 | 2359 | |
---|
2307 | 2360 | /* 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) { |
---|
2309 | 2362 | retval = tty_check_change(tty); |
---|
2310 | 2363 | if (retval) |
---|
2311 | 2364 | return retval; |
---|