Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : #include <linux/types.h>
3 : #include <linux/errno.h>
4 : #include <linux/kmod.h>
5 : #include <linux/sched.h>
6 : #include <linux/interrupt.h>
7 : #include <linux/tty.h>
8 : #include <linux/tty_driver.h>
9 : #include <linux/file.h>
10 : #include <linux/mm.h>
11 : #include <linux/string.h>
12 : #include <linux/slab.h>
13 : #include <linux/poll.h>
14 : #include <linux/proc_fs.h>
15 : #include <linux/module.h>
16 : #include <linux/device.h>
17 : #include <linux/wait.h>
18 : #include <linux/bitops.h>
19 : #include <linux/seq_file.h>
20 : #include <linux/uaccess.h>
21 : #include <linux/ratelimit.h>
22 : #include "tty.h"
23 :
24 : #undef LDISC_DEBUG_HANGUP
25 :
26 : #ifdef LDISC_DEBUG_HANGUP
27 : #define tty_ldisc_debug(tty, f, args...) tty_debug(tty, f, ##args)
28 : #else
29 : #define tty_ldisc_debug(tty, f, args...)
30 : #endif
31 :
32 : /* lockdep nested classes for tty->ldisc_sem */
33 : enum {
34 : LDISC_SEM_NORMAL,
35 : LDISC_SEM_OTHER,
36 : };
37 :
38 :
39 : /*
40 : * This guards the refcounted line discipline lists. The lock
41 : * must be taken with irqs off because there are hangup path
42 : * callers who will do ldisc lookups and cannot sleep.
43 : */
44 :
45 : static DEFINE_RAW_SPINLOCK(tty_ldiscs_lock);
46 : /* Line disc dispatch table */
47 : static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
48 :
49 : /**
50 : * tty_register_ldisc - install a line discipline
51 : * @new_ldisc: pointer to the ldisc object
52 : *
53 : * Installs a new line discipline into the kernel. The discipline is set up as
54 : * unreferenced and then made available to the kernel from this point onwards.
55 : *
56 : * Locking: takes %tty_ldiscs_lock to guard against ldisc races
57 : */
58 3 : int tty_register_ldisc(struct tty_ldisc_ops *new_ldisc)
59 : {
60 : unsigned long flags;
61 3 : int ret = 0;
62 :
63 3 : if (new_ldisc->num < N_TTY || new_ldisc->num >= NR_LDISCS)
64 : return -EINVAL;
65 :
66 3 : raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
67 3 : tty_ldiscs[new_ldisc->num] = new_ldisc;
68 6 : raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
69 :
70 3 : return ret;
71 : }
72 : EXPORT_SYMBOL(tty_register_ldisc);
73 :
74 : /**
75 : * tty_unregister_ldisc - unload a line discipline
76 : * @ldisc: ldisc number
77 : *
78 : * Remove a line discipline from the kernel providing it is not currently in
79 : * use.
80 : *
81 : * Locking: takes %tty_ldiscs_lock to guard against ldisc races
82 : */
83 :
84 0 : void tty_unregister_ldisc(struct tty_ldisc_ops *ldisc)
85 : {
86 : unsigned long flags;
87 :
88 0 : raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
89 0 : tty_ldiscs[ldisc->num] = NULL;
90 0 : raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
91 0 : }
92 : EXPORT_SYMBOL(tty_unregister_ldisc);
93 :
94 0 : static struct tty_ldisc_ops *get_ldops(int disc)
95 : {
96 : unsigned long flags;
97 : struct tty_ldisc_ops *ldops, *ret;
98 :
99 0 : raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
100 0 : ret = ERR_PTR(-EINVAL);
101 0 : ldops = tty_ldiscs[disc];
102 0 : if (ldops) {
103 0 : ret = ERR_PTR(-EAGAIN);
104 0 : if (try_module_get(ldops->owner))
105 0 : ret = ldops;
106 : }
107 0 : raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
108 0 : return ret;
109 : }
110 :
111 : static void put_ldops(struct tty_ldisc_ops *ldops)
112 : {
113 : unsigned long flags;
114 :
115 0 : raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
116 0 : module_put(ldops->owner);
117 0 : raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
118 : }
119 :
120 : int tty_ldisc_autoload = IS_BUILTIN(CONFIG_LDISC_AUTOLOAD);
121 :
122 : /**
123 : * tty_ldisc_get - take a reference to an ldisc
124 : * @tty: tty device
125 : * @disc: ldisc number
126 : *
127 : * Takes a reference to a line discipline. Deals with refcounts and module
128 : * locking counts. If the discipline is not available, its module loaded, if
129 : * possible.
130 : *
131 : * Returns:
132 : * * -%EINVAL if the discipline index is not [%N_TTY .. %NR_LDISCS] or if the
133 : * discipline is not registered
134 : * * -%EAGAIN if request_module() failed to load or register the discipline
135 : * * -%ENOMEM if allocation failure
136 : * * Otherwise, returns a pointer to the discipline and bumps the ref count
137 : *
138 : * Locking: takes %tty_ldiscs_lock to guard against ldisc races
139 : */
140 0 : static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc)
141 : {
142 : struct tty_ldisc *ld;
143 : struct tty_ldisc_ops *ldops;
144 :
145 0 : if (disc < N_TTY || disc >= NR_LDISCS)
146 : return ERR_PTR(-EINVAL);
147 :
148 : /*
149 : * Get the ldisc ops - we may need to request them to be loaded
150 : * dynamically and try again.
151 : */
152 0 : ldops = get_ldops(disc);
153 0 : if (IS_ERR(ldops)) {
154 0 : if (!capable(CAP_SYS_MODULE) && !tty_ldisc_autoload)
155 : return ERR_PTR(-EPERM);
156 0 : request_module("tty-ldisc-%d", disc);
157 0 : ldops = get_ldops(disc);
158 0 : if (IS_ERR(ldops))
159 : return ERR_CAST(ldops);
160 : }
161 :
162 : /*
163 : * There is no way to handle allocation failure of only 16 bytes.
164 : * Let's simplify error handling and save more memory.
165 : */
166 0 : ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL | __GFP_NOFAIL);
167 0 : ld->ops = ldops;
168 0 : ld->tty = tty;
169 :
170 0 : return ld;
171 : }
172 :
173 : /**
174 : * tty_ldisc_put - release the ldisc
175 : * @ld: lisdsc to release
176 : *
177 : * Complement of tty_ldisc_get().
178 : */
179 0 : static void tty_ldisc_put(struct tty_ldisc *ld)
180 : {
181 0 : if (WARN_ON_ONCE(!ld))
182 : return;
183 :
184 0 : put_ldops(ld->ops);
185 0 : kfree(ld);
186 : }
187 :
188 0 : static void *tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
189 : {
190 0 : return (*pos < NR_LDISCS) ? pos : NULL;
191 : }
192 :
193 0 : static void *tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
194 : {
195 0 : (*pos)++;
196 0 : return (*pos < NR_LDISCS) ? pos : NULL;
197 : }
198 :
199 0 : static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
200 : {
201 0 : }
202 :
203 0 : static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
204 : {
205 0 : int i = *(loff_t *)v;
206 : struct tty_ldisc_ops *ldops;
207 :
208 0 : ldops = get_ldops(i);
209 0 : if (IS_ERR(ldops))
210 : return 0;
211 0 : seq_printf(m, "%-10s %2d\n", ldops->name ? ldops->name : "???", i);
212 0 : put_ldops(ldops);
213 0 : return 0;
214 : }
215 :
216 : const struct seq_operations tty_ldiscs_seq_ops = {
217 : .start = tty_ldiscs_seq_start,
218 : .next = tty_ldiscs_seq_next,
219 : .stop = tty_ldiscs_seq_stop,
220 : .show = tty_ldiscs_seq_show,
221 : };
222 :
223 : /**
224 : * tty_ldisc_ref_wait - wait for the tty ldisc
225 : * @tty: tty device
226 : *
227 : * Dereference the line discipline for the terminal and take a reference to it.
228 : * If the line discipline is in flux then wait patiently until it changes.
229 : *
230 : * Returns: %NULL if the tty has been hungup and not re-opened with a new file
231 : * descriptor, otherwise valid ldisc reference
232 : *
233 : * Note 1: Must not be called from an IRQ/timer context. The caller must also
234 : * be careful not to hold other locks that will deadlock against a discipline
235 : * change, such as an existing ldisc reference (which we check for).
236 : *
237 : * Note 2: a file_operations routine (read/poll/write) should use this function
238 : * to wait for any ldisc lifetime events to finish.
239 : */
240 0 : struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
241 : {
242 : struct tty_ldisc *ld;
243 :
244 0 : ldsem_down_read(&tty->ldisc_sem, MAX_SCHEDULE_TIMEOUT);
245 0 : ld = tty->ldisc;
246 0 : if (!ld)
247 0 : ldsem_up_read(&tty->ldisc_sem);
248 0 : return ld;
249 : }
250 : EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
251 :
252 : /**
253 : * tty_ldisc_ref - get the tty ldisc
254 : * @tty: tty device
255 : *
256 : * Dereference the line discipline for the terminal and take a reference to it.
257 : * If the line discipline is in flux then return %NULL. Can be called from IRQ
258 : * and timer functions.
259 : */
260 0 : struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty)
261 : {
262 0 : struct tty_ldisc *ld = NULL;
263 :
264 0 : if (ldsem_down_read_trylock(&tty->ldisc_sem)) {
265 0 : ld = tty->ldisc;
266 0 : if (!ld)
267 0 : ldsem_up_read(&tty->ldisc_sem);
268 : }
269 0 : return ld;
270 : }
271 : EXPORT_SYMBOL_GPL(tty_ldisc_ref);
272 :
273 : /**
274 : * tty_ldisc_deref - free a tty ldisc reference
275 : * @ld: reference to free up
276 : *
277 : * Undoes the effect of tty_ldisc_ref() or tty_ldisc_ref_wait(). May be called
278 : * in IRQ context.
279 : */
280 0 : void tty_ldisc_deref(struct tty_ldisc *ld)
281 : {
282 0 : ldsem_up_read(&ld->tty->ldisc_sem);
283 0 : }
284 : EXPORT_SYMBOL_GPL(tty_ldisc_deref);
285 :
286 :
287 : static inline int
288 : __tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout)
289 : {
290 0 : return ldsem_down_write(&tty->ldisc_sem, timeout);
291 : }
292 :
293 : static inline int
294 : __tty_ldisc_lock_nested(struct tty_struct *tty, unsigned long timeout)
295 : {
296 0 : return ldsem_down_write_nested(&tty->ldisc_sem,
297 : LDISC_SEM_OTHER, timeout);
298 : }
299 :
300 : static inline void __tty_ldisc_unlock(struct tty_struct *tty)
301 : {
302 0 : ldsem_up_write(&tty->ldisc_sem);
303 : }
304 :
305 0 : int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout)
306 : {
307 : int ret;
308 :
309 : /* Kindly asking blocked readers to release the read side */
310 0 : set_bit(TTY_LDISC_CHANGING, &tty->flags);
311 0 : wake_up_interruptible_all(&tty->read_wait);
312 0 : wake_up_interruptible_all(&tty->write_wait);
313 :
314 0 : ret = __tty_ldisc_lock(tty, timeout);
315 0 : if (!ret)
316 : return -EBUSY;
317 0 : set_bit(TTY_LDISC_HALTED, &tty->flags);
318 0 : return 0;
319 : }
320 :
321 0 : void tty_ldisc_unlock(struct tty_struct *tty)
322 : {
323 0 : clear_bit(TTY_LDISC_HALTED, &tty->flags);
324 : /* Can be cleared here - ldisc_unlock will wake up writers firstly */
325 0 : clear_bit(TTY_LDISC_CHANGING, &tty->flags);
326 0 : __tty_ldisc_unlock(tty);
327 0 : }
328 :
329 : static int
330 0 : tty_ldisc_lock_pair_timeout(struct tty_struct *tty, struct tty_struct *tty2,
331 : unsigned long timeout)
332 : {
333 : int ret;
334 :
335 0 : if (tty < tty2) {
336 0 : ret = __tty_ldisc_lock(tty, timeout);
337 0 : if (ret) {
338 0 : ret = __tty_ldisc_lock_nested(tty2, timeout);
339 0 : if (!ret)
340 : __tty_ldisc_unlock(tty);
341 : }
342 : } else {
343 : /* if this is possible, it has lots of implications */
344 0 : WARN_ON_ONCE(tty == tty2);
345 0 : if (tty2 && tty != tty2) {
346 0 : ret = __tty_ldisc_lock(tty2, timeout);
347 0 : if (ret) {
348 0 : ret = __tty_ldisc_lock_nested(tty, timeout);
349 0 : if (!ret)
350 : __tty_ldisc_unlock(tty2);
351 : }
352 : } else
353 0 : ret = __tty_ldisc_lock(tty, timeout);
354 : }
355 :
356 0 : if (!ret)
357 : return -EBUSY;
358 :
359 0 : set_bit(TTY_LDISC_HALTED, &tty->flags);
360 0 : if (tty2)
361 0 : set_bit(TTY_LDISC_HALTED, &tty2->flags);
362 : return 0;
363 : }
364 :
365 : static void tty_ldisc_lock_pair(struct tty_struct *tty, struct tty_struct *tty2)
366 : {
367 0 : tty_ldisc_lock_pair_timeout(tty, tty2, MAX_SCHEDULE_TIMEOUT);
368 : }
369 :
370 : static void tty_ldisc_unlock_pair(struct tty_struct *tty,
371 : struct tty_struct *tty2)
372 : {
373 0 : __tty_ldisc_unlock(tty);
374 0 : if (tty2)
375 : __tty_ldisc_unlock(tty2);
376 : }
377 :
378 : /**
379 : * tty_ldisc_flush - flush line discipline queue
380 : * @tty: tty to flush ldisc for
381 : *
382 : * Flush the line discipline queue (if any) and the tty flip buffers for this
383 : * @tty.
384 : */
385 0 : void tty_ldisc_flush(struct tty_struct *tty)
386 : {
387 0 : struct tty_ldisc *ld = tty_ldisc_ref(tty);
388 :
389 0 : tty_buffer_flush(tty, ld);
390 0 : if (ld)
391 : tty_ldisc_deref(ld);
392 0 : }
393 : EXPORT_SYMBOL_GPL(tty_ldisc_flush);
394 :
395 : /**
396 : * tty_set_termios_ldisc - set ldisc field
397 : * @tty: tty structure
398 : * @disc: line discipline number
399 : *
400 : * This is probably overkill for real world processors but they are not on hot
401 : * paths so a little discipline won't do any harm.
402 : *
403 : * The line discipline-related tty_struct fields are reset to prevent the ldisc
404 : * driver from re-using stale information for the new ldisc instance.
405 : *
406 : * Locking: takes termios_rwsem
407 : */
408 : static void tty_set_termios_ldisc(struct tty_struct *tty, int disc)
409 : {
410 0 : down_write(&tty->termios_rwsem);
411 0 : tty->termios.c_line = disc;
412 0 : up_write(&tty->termios_rwsem);
413 :
414 0 : tty->disc_data = NULL;
415 0 : tty->receive_room = 0;
416 : }
417 :
418 : /**
419 : * tty_ldisc_open - open a line discipline
420 : * @tty: tty we are opening the ldisc on
421 : * @ld: discipline to open
422 : *
423 : * A helper opening method. Also a convenient debugging and check point.
424 : *
425 : * Locking: always called with BTM already held.
426 : */
427 0 : static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
428 : {
429 0 : WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags));
430 0 : if (ld->ops->open) {
431 : int ret;
432 : /* BTM here locks versus a hangup event */
433 0 : ret = ld->ops->open(tty);
434 0 : if (ret)
435 0 : clear_bit(TTY_LDISC_OPEN, &tty->flags);
436 :
437 : tty_ldisc_debug(tty, "%p: opened\n", ld);
438 : return ret;
439 : }
440 : return 0;
441 : }
442 :
443 : /**
444 : * tty_ldisc_close - close a line discipline
445 : * @tty: tty we are opening the ldisc on
446 : * @ld: discipline to close
447 : *
448 : * A helper close method. Also a convenient debugging and check point.
449 : */
450 0 : static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld)
451 : {
452 : lockdep_assert_held_write(&tty->ldisc_sem);
453 0 : WARN_ON(!test_bit(TTY_LDISC_OPEN, &tty->flags));
454 0 : clear_bit(TTY_LDISC_OPEN, &tty->flags);
455 0 : if (ld->ops->close)
456 0 : ld->ops->close(tty);
457 : tty_ldisc_debug(tty, "%p: closed\n", ld);
458 0 : }
459 :
460 : /**
461 : * tty_ldisc_failto - helper for ldisc failback
462 : * @tty: tty to open the ldisc on
463 : * @ld: ldisc we are trying to fail back to
464 : *
465 : * Helper to try and recover a tty when switching back to the old ldisc fails
466 : * and we need something attached.
467 : */
468 0 : static int tty_ldisc_failto(struct tty_struct *tty, int ld)
469 : {
470 0 : struct tty_ldisc *disc = tty_ldisc_get(tty, ld);
471 : int r;
472 :
473 : lockdep_assert_held_write(&tty->ldisc_sem);
474 0 : if (IS_ERR(disc))
475 0 : return PTR_ERR(disc);
476 0 : tty->ldisc = disc;
477 0 : tty_set_termios_ldisc(tty, ld);
478 0 : r = tty_ldisc_open(tty, disc);
479 0 : if (r < 0)
480 0 : tty_ldisc_put(disc);
481 : return r;
482 : }
483 :
484 : /**
485 : * tty_ldisc_restore - helper for tty ldisc change
486 : * @tty: tty to recover
487 : * @old: previous ldisc
488 : *
489 : * Restore the previous line discipline or %N_TTY when a line discipline change
490 : * fails due to an open error
491 : */
492 0 : static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
493 : {
494 : /* There is an outstanding reference here so this is safe */
495 0 : if (tty_ldisc_failto(tty, old->ops->num) < 0) {
496 0 : const char *name = tty_name(tty);
497 :
498 0 : pr_warn("Falling back ldisc for %s.\n", name);
499 : /*
500 : * The traditional behaviour is to fall back to N_TTY, we
501 : * want to avoid falling back to N_NULL unless we have no
502 : * choice to avoid the risk of breaking anything
503 : */
504 0 : if (tty_ldisc_failto(tty, N_TTY) < 0 &&
505 0 : tty_ldisc_failto(tty, N_NULL) < 0)
506 0 : panic("Couldn't open N_NULL ldisc for %s.", name);
507 : }
508 0 : }
509 :
510 : /**
511 : * tty_set_ldisc - set line discipline
512 : * @tty: the terminal to set
513 : * @disc: the line discipline number
514 : *
515 : * Set the discipline of a tty line. Must be called from a process context. The
516 : * ldisc change logic has to protect itself against any overlapping ldisc
517 : * change (including on the other end of pty pairs), the close of one side of a
518 : * tty/pty pair, and eventually hangup.
519 : */
520 0 : int tty_set_ldisc(struct tty_struct *tty, int disc)
521 : {
522 : int retval;
523 : struct tty_ldisc *old_ldisc, *new_ldisc;
524 :
525 0 : new_ldisc = tty_ldisc_get(tty, disc);
526 0 : if (IS_ERR(new_ldisc))
527 0 : return PTR_ERR(new_ldisc);
528 :
529 0 : tty_lock(tty);
530 0 : retval = tty_ldisc_lock(tty, 5 * HZ);
531 0 : if (retval)
532 : goto err;
533 :
534 0 : if (!tty->ldisc) {
535 : retval = -EIO;
536 : goto out;
537 : }
538 :
539 : /* Check the no-op case */
540 0 : if (tty->ldisc->ops->num == disc)
541 : goto out;
542 :
543 0 : if (test_bit(TTY_HUPPED, &tty->flags)) {
544 : /* We were raced by hangup */
545 : retval = -EIO;
546 : goto out;
547 : }
548 :
549 0 : old_ldisc = tty->ldisc;
550 :
551 : /* Shutdown the old discipline. */
552 0 : tty_ldisc_close(tty, old_ldisc);
553 :
554 : /* Now set up the new line discipline. */
555 0 : tty->ldisc = new_ldisc;
556 0 : tty_set_termios_ldisc(tty, disc);
557 :
558 0 : retval = tty_ldisc_open(tty, new_ldisc);
559 0 : if (retval < 0) {
560 : /* Back to the old one or N_TTY if we can't */
561 0 : tty_ldisc_put(new_ldisc);
562 0 : tty_ldisc_restore(tty, old_ldisc);
563 : }
564 :
565 0 : if (tty->ldisc->ops->num != old_ldisc->ops->num && tty->ops->set_ldisc) {
566 0 : down_read(&tty->termios_rwsem);
567 0 : tty->ops->set_ldisc(tty);
568 0 : up_read(&tty->termios_rwsem);
569 : }
570 :
571 : /*
572 : * At this point we hold a reference to the new ldisc and a
573 : * reference to the old ldisc, or we hold two references to
574 : * the old ldisc (if it was restored as part of error cleanup
575 : * above). In either case, releasing a single reference from
576 : * the old ldisc is correct.
577 : */
578 : new_ldisc = old_ldisc;
579 : out:
580 0 : tty_ldisc_unlock(tty);
581 :
582 : /*
583 : * Restart the work queue in case no characters kick it off. Safe if
584 : * already running
585 : */
586 0 : tty_buffer_restart_work(tty->port);
587 : err:
588 0 : tty_ldisc_put(new_ldisc); /* drop the extra reference */
589 0 : tty_unlock(tty);
590 0 : return retval;
591 : }
592 : EXPORT_SYMBOL_GPL(tty_set_ldisc);
593 :
594 : /**
595 : * tty_ldisc_kill - teardown ldisc
596 : * @tty: tty being released
597 : *
598 : * Perform final close of the ldisc and reset @tty->ldisc
599 : */
600 0 : static void tty_ldisc_kill(struct tty_struct *tty)
601 : {
602 : lockdep_assert_held_write(&tty->ldisc_sem);
603 0 : if (!tty->ldisc)
604 : return;
605 : /*
606 : * Now kill off the ldisc
607 : */
608 0 : tty_ldisc_close(tty, tty->ldisc);
609 0 : tty_ldisc_put(tty->ldisc);
610 : /* Force an oops if we mess this up */
611 0 : tty->ldisc = NULL;
612 : }
613 :
614 : /**
615 : * tty_reset_termios - reset terminal state
616 : * @tty: tty to reset
617 : *
618 : * Restore a terminal to the driver default state.
619 : */
620 0 : static void tty_reset_termios(struct tty_struct *tty)
621 : {
622 0 : down_write(&tty->termios_rwsem);
623 0 : tty->termios = tty->driver->init_termios;
624 0 : tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios);
625 0 : tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios);
626 0 : up_write(&tty->termios_rwsem);
627 0 : }
628 :
629 :
630 : /**
631 : * tty_ldisc_reinit - reinitialise the tty ldisc
632 : * @tty: tty to reinit
633 : * @disc: line discipline to reinitialize
634 : *
635 : * Completely reinitialize the line discipline state, by closing the current
636 : * instance, if there is one, and opening a new instance. If an error occurs
637 : * opening the new non-%N_TTY instance, the instance is dropped and @tty->ldisc
638 : * reset to %NULL. The caller can then retry with %N_TTY instead.
639 : *
640 : * Returns: 0 if successful, otherwise error code < 0
641 : */
642 0 : int tty_ldisc_reinit(struct tty_struct *tty, int disc)
643 : {
644 : struct tty_ldisc *ld;
645 : int retval;
646 :
647 : lockdep_assert_held_write(&tty->ldisc_sem);
648 0 : ld = tty_ldisc_get(tty, disc);
649 0 : if (IS_ERR(ld)) {
650 0 : BUG_ON(disc == N_TTY);
651 0 : return PTR_ERR(ld);
652 : }
653 :
654 0 : if (tty->ldisc) {
655 0 : tty_ldisc_close(tty, tty->ldisc);
656 0 : tty_ldisc_put(tty->ldisc);
657 : }
658 :
659 : /* switch the line discipline */
660 0 : tty->ldisc = ld;
661 0 : tty_set_termios_ldisc(tty, disc);
662 0 : retval = tty_ldisc_open(tty, tty->ldisc);
663 0 : if (retval) {
664 0 : tty_ldisc_put(tty->ldisc);
665 0 : tty->ldisc = NULL;
666 : }
667 : return retval;
668 : }
669 :
670 : /**
671 : * tty_ldisc_hangup - hangup ldisc reset
672 : * @tty: tty being hung up
673 : * @reinit: whether to re-initialise the tty
674 : *
675 : * Some tty devices reset their termios when they receive a hangup event. In
676 : * that situation we must also switch back to %N_TTY properly before we reset
677 : * the termios data.
678 : *
679 : * Locking: We can take the ldisc mutex as the rest of the code is careful to
680 : * allow for this.
681 : *
682 : * In the pty pair case this occurs in the close() path of the tty itself so we
683 : * must be careful about locking rules.
684 : */
685 0 : void tty_ldisc_hangup(struct tty_struct *tty, bool reinit)
686 : {
687 : struct tty_ldisc *ld;
688 :
689 : tty_ldisc_debug(tty, "%p: hangup\n", tty->ldisc);
690 :
691 0 : ld = tty_ldisc_ref(tty);
692 0 : if (ld != NULL) {
693 0 : if (ld->ops->flush_buffer)
694 0 : ld->ops->flush_buffer(tty);
695 0 : tty_driver_flush_buffer(tty);
696 0 : if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
697 0 : ld->ops->write_wakeup)
698 0 : ld->ops->write_wakeup(tty);
699 0 : if (ld->ops->hangup)
700 0 : ld->ops->hangup(tty);
701 : tty_ldisc_deref(ld);
702 : }
703 :
704 0 : wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT);
705 0 : wake_up_interruptible_poll(&tty->read_wait, EPOLLIN);
706 :
707 : /*
708 : * Shutdown the current line discipline, and reset it to
709 : * N_TTY if need be.
710 : *
711 : * Avoid racing set_ldisc or tty_ldisc_release
712 : */
713 0 : tty_ldisc_lock(tty, MAX_SCHEDULE_TIMEOUT);
714 :
715 0 : if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS)
716 0 : tty_reset_termios(tty);
717 :
718 0 : if (tty->ldisc) {
719 0 : if (reinit) {
720 0 : if (tty_ldisc_reinit(tty, tty->termios.c_line) < 0 &&
721 0 : tty_ldisc_reinit(tty, N_TTY) < 0)
722 0 : WARN_ON(tty_ldisc_reinit(tty, N_NULL) < 0);
723 : } else
724 0 : tty_ldisc_kill(tty);
725 : }
726 0 : tty_ldisc_unlock(tty);
727 0 : }
728 :
729 : /**
730 : * tty_ldisc_setup - open line discipline
731 : * @tty: tty being shut down
732 : * @o_tty: pair tty for pty/tty pairs
733 : *
734 : * Called during the initial open of a tty/pty pair in order to set up the line
735 : * disciplines and bind them to the @tty. This has no locking issues as the
736 : * device isn't yet active.
737 : */
738 0 : int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
739 : {
740 0 : int retval = tty_ldisc_open(tty, tty->ldisc);
741 :
742 0 : if (retval)
743 : return retval;
744 :
745 0 : if (o_tty) {
746 : /*
747 : * Called without o_tty->ldisc_sem held, as o_tty has been
748 : * just allocated and no one has a reference to it.
749 : */
750 0 : retval = tty_ldisc_open(o_tty, o_tty->ldisc);
751 0 : if (retval) {
752 0 : tty_ldisc_close(tty, tty->ldisc);
753 0 : return retval;
754 : }
755 : }
756 : return 0;
757 : }
758 :
759 : /**
760 : * tty_ldisc_release - release line discipline
761 : * @tty: tty being shut down (or one end of pty pair)
762 : *
763 : * Called during the final close of a tty or a pty pair in order to shut down
764 : * the line discpline layer. On exit, each tty's ldisc is %NULL.
765 : */
766 0 : void tty_ldisc_release(struct tty_struct *tty)
767 : {
768 0 : struct tty_struct *o_tty = tty->link;
769 :
770 : /*
771 : * Shutdown this line discipline. As this is the final close,
772 : * it does not race with the set_ldisc code path.
773 : */
774 :
775 0 : tty_ldisc_lock_pair(tty, o_tty);
776 0 : tty_ldisc_kill(tty);
777 0 : if (o_tty)
778 0 : tty_ldisc_kill(o_tty);
779 0 : tty_ldisc_unlock_pair(tty, o_tty);
780 :
781 : /*
782 : * And the memory resources remaining (buffers, termios) will be
783 : * disposed of when the kref hits zero
784 : */
785 :
786 : tty_ldisc_debug(tty, "released\n");
787 0 : }
788 :
789 : /**
790 : * tty_ldisc_init - ldisc setup for new tty
791 : * @tty: tty being allocated
792 : *
793 : * Set up the line discipline objects for a newly allocated tty. Note that the
794 : * tty structure is not completely set up when this call is made.
795 : */
796 0 : int tty_ldisc_init(struct tty_struct *tty)
797 : {
798 0 : struct tty_ldisc *ld = tty_ldisc_get(tty, N_TTY);
799 :
800 0 : if (IS_ERR(ld))
801 0 : return PTR_ERR(ld);
802 0 : tty->ldisc = ld;
803 0 : return 0;
804 : }
805 :
806 : /**
807 : * tty_ldisc_deinit - ldisc cleanup for new tty
808 : * @tty: tty that was allocated recently
809 : *
810 : * The tty structure must not be completely set up (tty_ldisc_setup()) when
811 : * this call is made.
812 : */
813 0 : void tty_ldisc_deinit(struct tty_struct *tty)
814 : {
815 : /* no ldisc_sem, tty is being destroyed */
816 0 : if (tty->ldisc)
817 0 : tty_ldisc_put(tty->ldisc);
818 0 : tty->ldisc = NULL;
819 0 : }
|