LCOV - code coverage report
Current view: top level - drivers/tty/hvc - hvc_console.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 3 418 0.7 %
Date: 2021-04-22 12:43:58 Functions: 1 31 3.2 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0+
       2             : /*
       3             :  * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
       4             :  * Copyright (C) 2001 Paul Mackerras <paulus@au.ibm.com>, IBM
       5             :  * Copyright (C) 2004 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
       6             :  * Copyright (C) 2004 IBM Corporation
       7             :  *
       8             :  * Additional Author(s):
       9             :  *  Ryan S. Arnold <rsa@us.ibm.com>
      10             :  */
      11             : 
      12             : #include <linux/console.h>
      13             : #include <linux/cpumask.h>
      14             : #include <linux/init.h>
      15             : #include <linux/kbd_kern.h>
      16             : #include <linux/kernel.h>
      17             : #include <linux/kthread.h>
      18             : #include <linux/list.h>
      19             : #include <linux/major.h>
      20             : #include <linux/atomic.h>
      21             : #include <linux/sysrq.h>
      22             : #include <linux/tty.h>
      23             : #include <linux/tty_flip.h>
      24             : #include <linux/sched.h>
      25             : #include <linux/spinlock.h>
      26             : #include <linux/delay.h>
      27             : #include <linux/freezer.h>
      28             : #include <linux/slab.h>
      29             : #include <linux/serial_core.h>
      30             : 
      31             : #include <linux/uaccess.h>
      32             : 
      33             : #include "hvc_console.h"
      34             : 
      35             : #define HVC_MAJOR       229
      36             : #define HVC_MINOR       0
      37             : 
      38             : /*
      39             :  * Wait this long per iteration while trying to push buffered data to the
      40             :  * hypervisor before allowing the tty to complete a close operation.
      41             :  */
      42             : #define HVC_CLOSE_WAIT (HZ/100) /* 1/10 of a second */
      43             : 
      44             : /*
      45             :  * These sizes are most efficient for vio, because they are the
      46             :  * native transfer size. We could make them selectable in the
      47             :  * future to better deal with backends that want other buffer sizes.
      48             :  */
      49             : #define N_OUTBUF        16
      50             : #define N_INBUF         16
      51             : 
      52             : #define __ALIGNED__ __attribute__((__aligned__(sizeof(long))))
      53             : 
      54             : static struct tty_driver *hvc_driver;
      55             : static struct task_struct *hvc_task;
      56             : 
      57             : /* Picks up late kicks after list walk but before schedule() */
      58             : static int hvc_kicked;
      59             : 
      60             : /* hvc_init is triggered from hvc_alloc, i.e. only when actually used */
      61             : static atomic_t hvc_needs_init __read_mostly = ATOMIC_INIT(-1);
      62             : 
      63             : static int hvc_init(void);
      64             : 
      65             : #ifdef CONFIG_MAGIC_SYSRQ
      66             : static int sysrq_pressed;
      67             : #endif
      68             : 
      69             : /* dynamic list of hvc_struct instances */
      70             : static LIST_HEAD(hvc_structs);
      71             : 
      72             : /*
      73             :  * Protect the list of hvc_struct instances from inserts and removals during
      74             :  * list traversal.
      75             :  */
      76             : static DEFINE_MUTEX(hvc_structs_mutex);
      77             : 
      78             : /*
      79             :  * This value is used to assign a tty->index value to a hvc_struct based
      80             :  * upon order of exposure via hvc_probe(), when we can not match it to
      81             :  * a console candidate registered with hvc_instantiate().
      82             :  */
      83             : static int last_hvc = -1;
      84             : 
      85             : /*
      86             :  * Do not call this function with either the hvc_structs_mutex or the hvc_struct
      87             :  * lock held.  If successful, this function increments the kref reference
      88             :  * count against the target hvc_struct so it should be released when finished.
      89             :  */
      90           0 : static struct hvc_struct *hvc_get_by_index(int index)
      91             : {
      92           0 :         struct hvc_struct *hp;
      93           0 :         unsigned long flags;
      94             : 
      95           0 :         mutex_lock(&hvc_structs_mutex);
      96             : 
      97           0 :         list_for_each_entry(hp, &hvc_structs, next) {
      98           0 :                 spin_lock_irqsave(&hp->lock, flags);
      99           0 :                 if (hp->index == index) {
     100           0 :                         tty_port_get(&hp->port);
     101           0 :                         spin_unlock_irqrestore(&hp->lock, flags);
     102           0 :                         mutex_unlock(&hvc_structs_mutex);
     103           0 :                         return hp;
     104             :                 }
     105           0 :                 spin_unlock_irqrestore(&hp->lock, flags);
     106             :         }
     107           0 :         hp = NULL;
     108           0 :         mutex_unlock(&hvc_structs_mutex);
     109             : 
     110           0 :         return hp;
     111             : }
     112             : 
     113           0 : static int __hvc_flush(const struct hv_ops *ops, uint32_t vtermno, bool wait)
     114             : {
     115           0 :         if (wait)
     116           0 :                 might_sleep();
     117             : 
     118           0 :         if (ops->flush)
     119           0 :                 return ops->flush(vtermno, wait);
     120             :         return 0;
     121             : }
     122             : 
     123           0 : static int hvc_console_flush(const struct hv_ops *ops, uint32_t vtermno)
     124             : {
     125           0 :         return __hvc_flush(ops, vtermno, false);
     126             : }
     127             : 
     128             : /*
     129             :  * Wait for the console to flush before writing more to it. This sleeps.
     130             :  */
     131           0 : static int hvc_flush(struct hvc_struct *hp)
     132             : {
     133           0 :         return __hvc_flush(hp->ops, hp->vtermno, true);
     134             : }
     135             : 
     136             : /*
     137             :  * Initial console vtermnos for console API usage prior to full console
     138             :  * initialization.  Any vty adapter outside this range will not have usable
     139             :  * console interfaces but can still be used as a tty device.  This has to be
     140             :  * static because kmalloc will not work during early console init.
     141             :  */
     142             : static const struct hv_ops *cons_ops[MAX_NR_HVC_CONSOLES];
     143             : static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
     144             :         {[0 ... MAX_NR_HVC_CONSOLES - 1] = -1};
     145             : 
     146             : /*
     147             :  * Console APIs, NOT TTY.  These APIs are available immediately when
     148             :  * hvc_console_setup() finds adapters.
     149             :  */
     150             : 
     151           0 : static void hvc_console_print(struct console *co, const char *b,
     152             :                               unsigned count)
     153             : {
     154           0 :         char c[N_OUTBUF] __ALIGNED__;
     155           0 :         unsigned i = 0, n = 0;
     156           0 :         int r, donecr = 0, index = co->index;
     157             : 
     158             :         /* Console access attempt outside of acceptable console range. */
     159           0 :         if (index >= MAX_NR_HVC_CONSOLES)
     160           0 :                 return;
     161             : 
     162             :         /* This console adapter was removed so it is not usable. */
     163           0 :         if (vtermnos[index] == -1)
     164             :                 return;
     165             : 
     166           0 :         while (count > 0 || i > 0) {
     167           0 :                 if (count > 0 && i < sizeof(c)) {
     168           0 :                         if (b[n] == '\n' && !donecr) {
     169           0 :                                 c[i++] = '\r';
     170           0 :                                 donecr = 1;
     171             :                         } else {
     172           0 :                                 c[i++] = b[n++];
     173           0 :                                 donecr = 0;
     174           0 :                                 --count;
     175             :                         }
     176             :                 } else {
     177           0 :                         r = cons_ops[index]->put_chars(vtermnos[index], c, i);
     178           0 :                         if (r <= 0) {
     179             :                                 /* throw away characters on error
     180             :                                  * but spin in case of -EAGAIN */
     181           0 :                                 if (r != -EAGAIN) {
     182             :                                         i = 0;
     183             :                                 } else {
     184           0 :                                         hvc_console_flush(cons_ops[index],
     185             :                                                       vtermnos[index]);
     186             :                                 }
     187           0 :                         } else if (r > 0) {
     188           0 :                                 i -= r;
     189           0 :                                 if (i > 0)
     190           0 :                                         memmove(c, c+r, i);
     191             :                         }
     192             :                 }
     193             :         }
     194           0 :         hvc_console_flush(cons_ops[index], vtermnos[index]);
     195             : }
     196             : 
     197           0 : static struct tty_driver *hvc_console_device(struct console *c, int *index)
     198             : {
     199           0 :         if (vtermnos[c->index] == -1)
     200             :                 return NULL;
     201             : 
     202           0 :         *index = c->index;
     203           0 :         return hvc_driver;
     204             : }
     205             : 
     206           0 : static int hvc_console_setup(struct console *co, char *options)
     207             : {       
     208           0 :         if (co->index < 0 || co->index >= MAX_NR_HVC_CONSOLES)
     209             :                 return -ENODEV;
     210             : 
     211           0 :         if (vtermnos[co->index] == -1)
     212           0 :                 return -ENODEV;
     213             : 
     214             :         return 0;
     215             : }
     216             : 
     217             : static struct console hvc_console = {
     218             :         .name           = "hvc",
     219             :         .write          = hvc_console_print,
     220             :         .device         = hvc_console_device,
     221             :         .setup          = hvc_console_setup,
     222             :         .flags          = CON_PRINTBUFFER,
     223             :         .index          = -1,
     224             : };
     225             : 
     226             : /*
     227             :  * Early console initialization.  Precedes driver initialization.
     228             :  *
     229             :  * (1) we are first, and the user specified another driver
     230             :  * -- index will remain -1
     231             :  * (2) we are first and the user specified no driver
     232             :  * -- index will be set to 0, then we will fail setup.
     233             :  * (3)  we are first and the user specified our driver
     234             :  * -- index will be set to user specified driver, and we will fail
     235             :  * (4) we are after driver, and this initcall will register us
     236             :  * -- if the user didn't specify a driver then the console will match
     237             :  *
     238             :  * Note that for cases 2 and 3, we will match later when the io driver
     239             :  * calls hvc_instantiate() and call register again.
     240             :  */
     241           1 : static int __init hvc_console_init(void)
     242             : {
     243           1 :         register_console(&hvc_console);
     244           1 :         return 0;
     245             : }
     246             : console_initcall(hvc_console_init);
     247             : 
     248             : /* callback when the kboject ref count reaches zero. */
     249           0 : static void hvc_port_destruct(struct tty_port *port)
     250             : {
     251           0 :         struct hvc_struct *hp = container_of(port, struct hvc_struct, port);
     252           0 :         unsigned long flags;
     253             : 
     254           0 :         mutex_lock(&hvc_structs_mutex);
     255             : 
     256           0 :         spin_lock_irqsave(&hp->lock, flags);
     257           0 :         list_del(&(hp->next));
     258           0 :         spin_unlock_irqrestore(&hp->lock, flags);
     259             : 
     260           0 :         mutex_unlock(&hvc_structs_mutex);
     261             : 
     262           0 :         kfree(hp);
     263           0 : }
     264             : 
     265           0 : static void hvc_check_console(int index)
     266             : {
     267             :         /* Already enabled, bail out */
     268           0 :         if (hvc_console.flags & CON_ENABLED)
     269             :                 return;
     270             : 
     271             :         /* If this index is what the user requested, then register
     272             :          * now (setup won't fail at this point).  It's ok to just
     273             :          * call register again if previously .setup failed.
     274             :          */
     275           0 :         if (index == hvc_console.index)
     276           0 :                 register_console(&hvc_console);
     277             : }
     278             : 
     279             : /*
     280             :  * hvc_instantiate() is an early console discovery method which locates
     281             :  * consoles * prior to the vio subsystem discovering them.  Hotplugged
     282             :  * vty adapters do NOT get an hvc_instantiate() callback since they
     283             :  * appear after early console init.
     284             :  */
     285           0 : int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops)
     286             : {
     287           0 :         struct hvc_struct *hp;
     288             : 
     289           0 :         if (index < 0 || index >= MAX_NR_HVC_CONSOLES)
     290             :                 return -1;
     291             : 
     292           0 :         if (vtermnos[index] != -1)
     293             :                 return -1;
     294             : 
     295             :         /* make sure no no tty has been registered in this index */
     296           0 :         hp = hvc_get_by_index(index);
     297           0 :         if (hp) {
     298           0 :                 tty_port_put(&hp->port);
     299           0 :                 return -1;
     300             :         }
     301             : 
     302           0 :         vtermnos[index] = vtermno;
     303           0 :         cons_ops[index] = ops;
     304             : 
     305             :         /* check if we need to re-register the kernel console */
     306           0 :         hvc_check_console(index);
     307             : 
     308           0 :         return 0;
     309             : }
     310             : EXPORT_SYMBOL_GPL(hvc_instantiate);
     311             : 
     312             : /* Wake the sleeping khvcd */
     313           0 : void hvc_kick(void)
     314             : {
     315           0 :         hvc_kicked = 1;
     316           0 :         wake_up_process(hvc_task);
     317           0 : }
     318             : EXPORT_SYMBOL_GPL(hvc_kick);
     319             : 
     320           0 : static void hvc_unthrottle(struct tty_struct *tty)
     321             : {
     322           0 :         hvc_kick();
     323           0 : }
     324             : 
     325           0 : static int hvc_install(struct tty_driver *driver, struct tty_struct *tty)
     326             : {
     327           0 :         struct hvc_struct *hp;
     328           0 :         int rc;
     329             : 
     330             :         /* Auto increments kref reference if found. */
     331           0 :         hp = hvc_get_by_index(tty->index);
     332           0 :         if (!hp)
     333             :                 return -ENODEV;
     334             : 
     335           0 :         tty->driver_data = hp;
     336             : 
     337           0 :         rc = tty_port_install(&hp->port, driver, tty);
     338           0 :         if (rc)
     339           0 :                 tty_port_put(&hp->port);
     340             :         return rc;
     341             : }
     342             : 
     343             : /*
     344             :  * The TTY interface won't be used until after the vio layer has exposed the vty
     345             :  * adapter to the kernel.
     346             :  */
     347           0 : static int hvc_open(struct tty_struct *tty, struct file * filp)
     348             : {
     349           0 :         struct hvc_struct *hp = tty->driver_data;
     350           0 :         unsigned long flags;
     351           0 :         int rc = 0;
     352             : 
     353           0 :         spin_lock_irqsave(&hp->port.lock, flags);
     354             :         /* Check and then increment for fast path open. */
     355           0 :         if (hp->port.count++ > 0) {
     356           0 :                 spin_unlock_irqrestore(&hp->port.lock, flags);
     357           0 :                 hvc_kick();
     358           0 :                 return 0;
     359             :         } /* else count == 0 */
     360           0 :         spin_unlock_irqrestore(&hp->port.lock, flags);
     361             : 
     362           0 :         tty_port_tty_set(&hp->port, tty);
     363             : 
     364           0 :         if (hp->ops->notifier_add)
     365           0 :                 rc = hp->ops->notifier_add(hp, hp->data);
     366             : 
     367             :         /*
     368             :          * If the notifier fails we return an error.  The tty layer
     369             :          * will call hvc_close() after a failed open but we don't want to clean
     370             :          * up there so we'll clean up here and clear out the previously set
     371             :          * tty fields and return the kref reference.
     372             :          */
     373           0 :         if (rc) {
     374           0 :                 printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
     375             :         } else {
     376             :                 /* We are ready... raise DTR/RTS */
     377           0 :                 if (C_BAUD(tty))
     378           0 :                         if (hp->ops->dtr_rts)
     379           0 :                                 hp->ops->dtr_rts(hp, 1);
     380           0 :                 tty_port_set_initialized(&hp->port, true);
     381             :         }
     382             : 
     383             :         /* Force wakeup of the polling thread */
     384           0 :         hvc_kick();
     385             : 
     386           0 :         return rc;
     387             : }
     388             : 
     389           0 : static void hvc_close(struct tty_struct *tty, struct file * filp)
     390             : {
     391           0 :         struct hvc_struct *hp = tty->driver_data;
     392           0 :         unsigned long flags;
     393             : 
     394           0 :         if (tty_hung_up_p(filp))
     395             :                 return;
     396             : 
     397           0 :         spin_lock_irqsave(&hp->port.lock, flags);
     398             : 
     399           0 :         if (--hp->port.count == 0) {
     400           0 :                 spin_unlock_irqrestore(&hp->port.lock, flags);
     401             :                 /* We are done with the tty pointer now. */
     402           0 :                 tty_port_tty_set(&hp->port, NULL);
     403             : 
     404           0 :                 if (!tty_port_initialized(&hp->port))
     405             :                         return;
     406             : 
     407           0 :                 if (C_HUPCL(tty))
     408           0 :                         if (hp->ops->dtr_rts)
     409           0 :                                 hp->ops->dtr_rts(hp, 0);
     410             : 
     411           0 :                 if (hp->ops->notifier_del)
     412           0 :                         hp->ops->notifier_del(hp, hp->data);
     413             : 
     414             :                 /* cancel pending tty resize work */
     415           0 :                 cancel_work_sync(&hp->tty_resize);
     416             : 
     417             :                 /*
     418             :                  * Chain calls chars_in_buffer() and returns immediately if
     419             :                  * there is no buffered data otherwise sleeps on a wait queue
     420             :                  * waking periodically to check chars_in_buffer().
     421             :                  */
     422           0 :                 tty_wait_until_sent(tty, HVC_CLOSE_WAIT);
     423           0 :                 tty_port_set_initialized(&hp->port, false);
     424             :         } else {
     425           0 :                 if (hp->port.count < 0)
     426           0 :                         printk(KERN_ERR "hvc_close %X: oops, count is %d\n",
     427             :                                 hp->vtermno, hp->port.count);
     428           0 :                 spin_unlock_irqrestore(&hp->port.lock, flags);
     429             :         }
     430             : }
     431             : 
     432           0 : static void hvc_cleanup(struct tty_struct *tty)
     433             : {
     434           0 :         struct hvc_struct *hp = tty->driver_data;
     435             : 
     436           0 :         tty_port_put(&hp->port);
     437           0 : }
     438             : 
     439           0 : static void hvc_hangup(struct tty_struct *tty)
     440             : {
     441           0 :         struct hvc_struct *hp = tty->driver_data;
     442           0 :         unsigned long flags;
     443             : 
     444           0 :         if (!hp)
     445             :                 return;
     446             : 
     447             :         /* cancel pending tty resize work */
     448           0 :         cancel_work_sync(&hp->tty_resize);
     449             : 
     450           0 :         spin_lock_irqsave(&hp->port.lock, flags);
     451             : 
     452             :         /*
     453             :          * The N_TTY line discipline has problems such that in a close vs
     454             :          * open->hangup case this can be called after the final close so prevent
     455             :          * that from happening for now.
     456             :          */
     457           0 :         if (hp->port.count <= 0) {
     458           0 :                 spin_unlock_irqrestore(&hp->port.lock, flags);
     459           0 :                 return;
     460             :         }
     461             : 
     462           0 :         hp->port.count = 0;
     463           0 :         spin_unlock_irqrestore(&hp->port.lock, flags);
     464           0 :         tty_port_tty_set(&hp->port, NULL);
     465             : 
     466           0 :         hp->n_outbuf = 0;
     467             : 
     468           0 :         if (hp->ops->notifier_hangup)
     469           0 :                 hp->ops->notifier_hangup(hp, hp->data);
     470             : }
     471             : 
     472             : /*
     473             :  * Push buffered characters whether they were just recently buffered or waiting
     474             :  * on a blocked hypervisor.  Call this function with hp->lock held.
     475             :  */
     476           0 : static int hvc_push(struct hvc_struct *hp)
     477             : {
     478           0 :         int n;
     479             : 
     480           0 :         n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf);
     481           0 :         if (n <= 0) {
     482           0 :                 if (n == 0 || n == -EAGAIN) {
     483           0 :                         hp->do_wakeup = 1;
     484           0 :                         return 0;
     485             :                 }
     486             :                 /* throw away output on error; this happens when
     487             :                    there is no session connected to the vterm. */
     488           0 :                 hp->n_outbuf = 0;
     489             :         } else
     490           0 :                 hp->n_outbuf -= n;
     491           0 :         if (hp->n_outbuf > 0)
     492           0 :                 memmove(hp->outbuf, hp->outbuf + n, hp->n_outbuf);
     493             :         else
     494           0 :                 hp->do_wakeup = 1;
     495             : 
     496             :         return n;
     497             : }
     498             : 
     499           0 : static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count)
     500             : {
     501           0 :         struct hvc_struct *hp = tty->driver_data;
     502           0 :         unsigned long flags;
     503           0 :         int rsize, written = 0;
     504             : 
     505             :         /* This write was probably executed during a tty close. */
     506           0 :         if (!hp)
     507             :                 return -EPIPE;
     508             : 
     509             :         /* FIXME what's this (unprotected) check for? */
     510           0 :         if (hp->port.count <= 0)
     511             :                 return -EIO;
     512             : 
     513           0 :         while (count > 0) {
     514           0 :                 int ret = 0;
     515             : 
     516           0 :                 spin_lock_irqsave(&hp->lock, flags);
     517             : 
     518           0 :                 rsize = hp->outbuf_size - hp->n_outbuf;
     519             : 
     520           0 :                 if (rsize) {
     521           0 :                         if (rsize > count)
     522             :                                 rsize = count;
     523           0 :                         memcpy(hp->outbuf + hp->n_outbuf, buf, rsize);
     524           0 :                         count -= rsize;
     525           0 :                         buf += rsize;
     526           0 :                         hp->n_outbuf += rsize;
     527           0 :                         written += rsize;
     528             :                 }
     529             : 
     530           0 :                 if (hp->n_outbuf > 0)
     531           0 :                         ret = hvc_push(hp);
     532             : 
     533           0 :                 spin_unlock_irqrestore(&hp->lock, flags);
     534             : 
     535           0 :                 if (!ret)
     536             :                         break;
     537             : 
     538           0 :                 if (count) {
     539           0 :                         if (hp->n_outbuf > 0)
     540           0 :                                 hvc_flush(hp);
     541           0 :                         cond_resched();
     542             :                 }
     543             :         }
     544             : 
     545             :         /*
     546             :          * Racy, but harmless, kick thread if there is still pending data.
     547             :          */
     548           0 :         if (hp->n_outbuf)
     549           0 :                 hvc_kick();
     550             : 
     551             :         return written;
     552             : }
     553             : 
     554             : /**
     555             :  * hvc_set_winsz() - Resize the hvc tty terminal window.
     556             :  * @work:       work structure.
     557             :  *
     558             :  * The routine shall not be called within an atomic context because it
     559             :  * might sleep.
     560             :  *
     561             :  * Locking:     hp->lock
     562             :  */
     563           0 : static void hvc_set_winsz(struct work_struct *work)
     564             : {
     565           0 :         struct hvc_struct *hp;
     566           0 :         unsigned long hvc_flags;
     567           0 :         struct tty_struct *tty;
     568           0 :         struct winsize ws;
     569             : 
     570           0 :         hp = container_of(work, struct hvc_struct, tty_resize);
     571             : 
     572           0 :         tty = tty_port_tty_get(&hp->port);
     573           0 :         if (!tty)
     574           0 :                 return;
     575             : 
     576           0 :         spin_lock_irqsave(&hp->lock, hvc_flags);
     577           0 :         ws = hp->ws;
     578           0 :         spin_unlock_irqrestore(&hp->lock, hvc_flags);
     579             : 
     580           0 :         tty_do_resize(tty, &ws);
     581           0 :         tty_kref_put(tty);
     582             : }
     583             : 
     584             : /*
     585             :  * This is actually a contract between the driver and the tty layer outlining
     586             :  * how much write room the driver can guarantee will be sent OR BUFFERED.  This
     587             :  * driver MUST honor the return value.
     588             :  */
     589           0 : static int hvc_write_room(struct tty_struct *tty)
     590             : {
     591           0 :         struct hvc_struct *hp = tty->driver_data;
     592             : 
     593           0 :         if (!hp)
     594             :                 return 0;
     595             : 
     596           0 :         return hp->outbuf_size - hp->n_outbuf;
     597             : }
     598             : 
     599           0 : static int hvc_chars_in_buffer(struct tty_struct *tty)
     600             : {
     601           0 :         struct hvc_struct *hp = tty->driver_data;
     602             : 
     603           0 :         if (!hp)
     604             :                 return 0;
     605           0 :         return hp->n_outbuf;
     606             : }
     607             : 
     608             : /*
     609             :  * timeout will vary between the MIN and MAX values defined here.  By default
     610             :  * and during console activity we will use a default MIN_TIMEOUT of 10.  When
     611             :  * the console is idle, we increase the timeout value on each pass through
     612             :  * msleep until we reach the max.  This may be noticeable as a brief (average
     613             :  * one second) delay on the console before the console responds to input when
     614             :  * there has been no input for some time.
     615             :  */
     616             : #define MIN_TIMEOUT             (10)
     617             : #define MAX_TIMEOUT             (2000)
     618             : static u32 timeout = MIN_TIMEOUT;
     619             : 
     620             : /*
     621             :  * Maximum number of bytes to get from the console driver if hvc_poll is
     622             :  * called from driver (and can't sleep). Any more than this and we break
     623             :  * and start polling with khvcd. This value was derived from from an OpenBMC
     624             :  * console with the OPAL driver that results in about 0.25ms interrupts off
     625             :  * latency.
     626             :  */
     627             : #define HVC_ATOMIC_READ_MAX     128
     628             : 
     629             : #define HVC_POLL_READ   0x00000001
     630             : #define HVC_POLL_WRITE  0x00000002
     631             : 
     632           0 : static int __hvc_poll(struct hvc_struct *hp, bool may_sleep)
     633             : {
     634           0 :         struct tty_struct *tty;
     635           0 :         int i, n, count, poll_mask = 0;
     636           0 :         char buf[N_INBUF] __ALIGNED__;
     637           0 :         unsigned long flags;
     638           0 :         int read_total = 0;
     639           0 :         int written_total = 0;
     640             : 
     641           0 :         spin_lock_irqsave(&hp->lock, flags);
     642             : 
     643             :         /* Push pending writes */
     644           0 :         if (hp->n_outbuf > 0)
     645           0 :                 written_total = hvc_push(hp);
     646             : 
     647             :         /* Reschedule us if still some write pending */
     648           0 :         if (hp->n_outbuf > 0) {
     649           0 :                 poll_mask |= HVC_POLL_WRITE;
     650             :                 /* If hvc_push() was not able to write, sleep a few msecs */
     651           0 :                 timeout = (written_total) ? 0 : MIN_TIMEOUT;
     652             :         }
     653             : 
     654           0 :         if (may_sleep) {
     655           0 :                 spin_unlock_irqrestore(&hp->lock, flags);
     656           0 :                 cond_resched();
     657           0 :                 spin_lock_irqsave(&hp->lock, flags);
     658             :         }
     659             : 
     660             :         /* No tty attached, just skip */
     661           0 :         tty = tty_port_tty_get(&hp->port);
     662           0 :         if (tty == NULL)
     663           0 :                 goto bail;
     664             : 
     665             :         /* Now check if we can get data (are we throttled ?) */
     666           0 :         if (tty_throttled(tty))
     667           0 :                 goto out;
     668             : 
     669             :         /* If we aren't notifier driven and aren't throttled, we always
     670             :          * request a reschedule
     671             :          */
     672           0 :         if (!hp->irq_requested)
     673           0 :                 poll_mask |= HVC_POLL_READ;
     674             : 
     675           0 :  read_again:
     676             :         /* Read data if any */
     677           0 :         count = tty_buffer_request_room(&hp->port, N_INBUF);
     678             : 
     679             :         /* If flip is full, just reschedule a later read */
     680           0 :         if (count == 0) {
     681           0 :                 poll_mask |= HVC_POLL_READ;
     682           0 :                 goto out;
     683             :         }
     684             : 
     685           0 :         n = hp->ops->get_chars(hp->vtermno, buf, count);
     686           0 :         if (n <= 0) {
     687             :                 /* Hangup the tty when disconnected from host */
     688           0 :                 if (n == -EPIPE) {
     689           0 :                         spin_unlock_irqrestore(&hp->lock, flags);
     690           0 :                         tty_hangup(tty);
     691           0 :                         spin_lock_irqsave(&hp->lock, flags);
     692           0 :                 } else if ( n == -EAGAIN ) {
     693             :                         /*
     694             :                          * Some back-ends can only ensure a certain min
     695             :                          * num of bytes read, which may be > 'count'.
     696             :                          * Let the tty clear the flip buff to make room.
     697             :                          */
     698           0 :                         poll_mask |= HVC_POLL_READ;
     699             :                 }
     700           0 :                 goto out;
     701             :         }
     702             : 
     703           0 :         for (i = 0; i < n; ++i) {
     704             : #ifdef CONFIG_MAGIC_SYSRQ
     705           0 :                 if (hp->index == hvc_console.index) {
     706             :                         /* Handle the SysRq Hack */
     707             :                         /* XXX should support a sequence */
     708           0 :                         if (buf[i] == '\x0f') { /* ^O */
     709             :                                 /* if ^O is pressed again, reset
     710             :                                  * sysrq_pressed and flip ^O char */
     711           0 :                                 sysrq_pressed = !sysrq_pressed;
     712           0 :                                 if (sysrq_pressed)
     713           0 :                                         continue;
     714           0 :                         } else if (sysrq_pressed) {
     715           0 :                                 handle_sysrq(buf[i]);
     716           0 :                                 sysrq_pressed = 0;
     717           0 :                                 continue;
     718             :                         }
     719             :                 }
     720             : #endif /* CONFIG_MAGIC_SYSRQ */
     721           0 :                 tty_insert_flip_char(&hp->port, buf[i], 0);
     722             :         }
     723           0 :         read_total += n;
     724             : 
     725           0 :         if (may_sleep) {
     726             :                 /* Keep going until the flip is full */
     727           0 :                 spin_unlock_irqrestore(&hp->lock, flags);
     728           0 :                 cond_resched();
     729           0 :                 spin_lock_irqsave(&hp->lock, flags);
     730           0 :                 goto read_again;
     731           0 :         } else if (read_total < HVC_ATOMIC_READ_MAX) {
     732             :                 /* Break and defer if it's a large read in atomic */
     733           0 :                 goto read_again;
     734             :         }
     735             : 
     736             :         /*
     737             :          * Latency break, schedule another poll immediately.
     738             :          */
     739           0 :         poll_mask |= HVC_POLL_READ;
     740             : 
     741           0 :  out:
     742             :         /* Wakeup write queue if necessary */
     743           0 :         if (hp->do_wakeup) {
     744           0 :                 hp->do_wakeup = 0;
     745           0 :                 tty_wakeup(tty);
     746             :         }
     747           0 :  bail:
     748           0 :         spin_unlock_irqrestore(&hp->lock, flags);
     749             : 
     750           0 :         if (read_total) {
     751             :                 /* Activity is occurring, so reset the polling backoff value to
     752             :                    a minimum for performance. */
     753           0 :                 timeout = MIN_TIMEOUT;
     754             : 
     755           0 :                 tty_flip_buffer_push(&hp->port);
     756             :         }
     757           0 :         tty_kref_put(tty);
     758             : 
     759           0 :         return poll_mask;
     760             : }
     761             : 
     762           0 : int hvc_poll(struct hvc_struct *hp)
     763             : {
     764           0 :         return __hvc_poll(hp, false);
     765             : }
     766             : EXPORT_SYMBOL_GPL(hvc_poll);
     767             : 
     768             : /**
     769             :  * __hvc_resize() - Update terminal window size information.
     770             :  * @hp:         HVC console pointer
     771             :  * @ws:         Terminal window size structure
     772             :  *
     773             :  * Stores the specified window size information in the hvc structure of @hp.
     774             :  * The function schedule the tty resize update.
     775             :  *
     776             :  * Locking:     Locking free; the function MUST be called holding hp->lock
     777             :  */
     778           0 : void __hvc_resize(struct hvc_struct *hp, struct winsize ws)
     779             : {
     780           0 :         hp->ws = ws;
     781           0 :         schedule_work(&hp->tty_resize);
     782           0 : }
     783             : EXPORT_SYMBOL_GPL(__hvc_resize);
     784             : 
     785             : /*
     786             :  * This kthread is either polling or interrupt driven.  This is determined by
     787             :  * calling hvc_poll() who determines whether a console adapter support
     788             :  * interrupts.
     789             :  */
     790           0 : static int khvcd(void *unused)
     791             : {
     792           0 :         int poll_mask;
     793           0 :         struct hvc_struct *hp;
     794             : 
     795           0 :         set_freezable();
     796           0 :         do {
     797           0 :                 poll_mask = 0;
     798           0 :                 hvc_kicked = 0;
     799           0 :                 try_to_freeze();
     800           0 :                 wmb();
     801           0 :                 if (!cpus_are_in_xmon()) {
     802           0 :                         mutex_lock(&hvc_structs_mutex);
     803           0 :                         list_for_each_entry(hp, &hvc_structs, next) {
     804           0 :                                 poll_mask |= __hvc_poll(hp, true);
     805           0 :                                 cond_resched();
     806             :                         }
     807           0 :                         mutex_unlock(&hvc_structs_mutex);
     808             :                 } else
     809             :                         poll_mask |= HVC_POLL_READ;
     810           0 :                 if (hvc_kicked)
     811           0 :                         continue;
     812           0 :                 set_current_state(TASK_INTERRUPTIBLE);
     813           0 :                 if (!hvc_kicked) {
     814           0 :                         if (poll_mask == 0)
     815           0 :                                 schedule();
     816             :                         else {
     817           0 :                                 unsigned long j_timeout;
     818             : 
     819           0 :                                 if (timeout < MAX_TIMEOUT)
     820           0 :                                         timeout += (timeout >> 6) + 1;
     821             : 
     822             :                                 /*
     823             :                                  * We don't use msleep_interruptible otherwise
     824             :                                  * "kick" will fail to wake us up
     825             :                                  */
     826           0 :                                 j_timeout = msecs_to_jiffies(timeout) + 1;
     827           0 :                                 schedule_timeout_interruptible(j_timeout);
     828             :                         }
     829             :                 }
     830           0 :                 __set_current_state(TASK_RUNNING);
     831           0 :         } while (!kthread_should_stop());
     832             : 
     833           0 :         return 0;
     834             : }
     835             : 
     836           0 : static int hvc_tiocmget(struct tty_struct *tty)
     837             : {
     838           0 :         struct hvc_struct *hp = tty->driver_data;
     839             : 
     840           0 :         if (!hp || !hp->ops->tiocmget)
     841             :                 return -EINVAL;
     842           0 :         return hp->ops->tiocmget(hp);
     843             : }
     844             : 
     845           0 : static int hvc_tiocmset(struct tty_struct *tty,
     846             :                         unsigned int set, unsigned int clear)
     847             : {
     848           0 :         struct hvc_struct *hp = tty->driver_data;
     849             : 
     850           0 :         if (!hp || !hp->ops->tiocmset)
     851             :                 return -EINVAL;
     852           0 :         return hp->ops->tiocmset(hp, set, clear);
     853             : }
     854             : 
     855             : #ifdef CONFIG_CONSOLE_POLL
     856             : static int hvc_poll_init(struct tty_driver *driver, int line, char *options)
     857             : {
     858             :         return 0;
     859             : }
     860             : 
     861             : static int hvc_poll_get_char(struct tty_driver *driver, int line)
     862             : {
     863             :         struct tty_struct *tty = driver->ttys[0];
     864             :         struct hvc_struct *hp = tty->driver_data;
     865             :         int n;
     866             :         char ch;
     867             : 
     868             :         n = hp->ops->get_chars(hp->vtermno, &ch, 1);
     869             : 
     870             :         if (n <= 0)
     871             :                 return NO_POLL_CHAR;
     872             : 
     873             :         return ch;
     874             : }
     875             : 
     876             : static void hvc_poll_put_char(struct tty_driver *driver, int line, char ch)
     877             : {
     878             :         struct tty_struct *tty = driver->ttys[0];
     879             :         struct hvc_struct *hp = tty->driver_data;
     880             :         int n;
     881             : 
     882             :         do {
     883             :                 n = hp->ops->put_chars(hp->vtermno, &ch, 1);
     884             :         } while (n <= 0);
     885             : }
     886             : #endif
     887             : 
     888             : static const struct tty_operations hvc_ops = {
     889             :         .install = hvc_install,
     890             :         .open = hvc_open,
     891             :         .close = hvc_close,
     892             :         .cleanup = hvc_cleanup,
     893             :         .write = hvc_write,
     894             :         .hangup = hvc_hangup,
     895             :         .unthrottle = hvc_unthrottle,
     896             :         .write_room = hvc_write_room,
     897             :         .chars_in_buffer = hvc_chars_in_buffer,
     898             :         .tiocmget = hvc_tiocmget,
     899             :         .tiocmset = hvc_tiocmset,
     900             : #ifdef CONFIG_CONSOLE_POLL
     901             :         .poll_init = hvc_poll_init,
     902             :         .poll_get_char = hvc_poll_get_char,
     903             :         .poll_put_char = hvc_poll_put_char,
     904             : #endif
     905             : };
     906             : 
     907             : static const struct tty_port_operations hvc_port_ops = {
     908             :         .destruct = hvc_port_destruct,
     909             : };
     910             : 
     911           0 : struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
     912             :                              const struct hv_ops *ops,
     913             :                              int outbuf_size)
     914             : {
     915           0 :         struct hvc_struct *hp;
     916           0 :         int i;
     917             : 
     918             :         /* We wait until a driver actually comes along */
     919           0 :         if (atomic_inc_not_zero(&hvc_needs_init)) {
     920           0 :                 int err = hvc_init();
     921           0 :                 if (err)
     922           0 :                         return ERR_PTR(err);
     923             :         }
     924             : 
     925           0 :         hp = kzalloc(ALIGN(sizeof(*hp), sizeof(long)) + outbuf_size,
     926             :                         GFP_KERNEL);
     927           0 :         if (!hp)
     928           0 :                 return ERR_PTR(-ENOMEM);
     929             : 
     930           0 :         hp->vtermno = vtermno;
     931           0 :         hp->data = data;
     932           0 :         hp->ops = ops;
     933           0 :         hp->outbuf_size = outbuf_size;
     934           0 :         hp->outbuf = &((char *)hp)[ALIGN(sizeof(*hp), sizeof(long))];
     935             : 
     936           0 :         tty_port_init(&hp->port);
     937           0 :         hp->port.ops = &hvc_port_ops;
     938             : 
     939           0 :         INIT_WORK(&hp->tty_resize, hvc_set_winsz);
     940           0 :         spin_lock_init(&hp->lock);
     941           0 :         mutex_lock(&hvc_structs_mutex);
     942             : 
     943             :         /*
     944             :          * find index to use:
     945             :          * see if this vterm id matches one registered for console.
     946             :          */
     947           0 :         for (i=0; i < MAX_NR_HVC_CONSOLES; i++)
     948           0 :                 if (vtermnos[i] == hp->vtermno &&
     949           0 :                     cons_ops[i] == hp->ops)
     950             :                         break;
     951             : 
     952           0 :         if (i >= MAX_NR_HVC_CONSOLES) {
     953             : 
     954             :                 /* find 'empty' slot for console */
     955           0 :                 for (i = 0; i < MAX_NR_HVC_CONSOLES && vtermnos[i] != -1; i++) {
     956           0 :                 }
     957             : 
     958             :                 /* no matching slot, just use a counter */
     959           0 :                 if (i == MAX_NR_HVC_CONSOLES)
     960           0 :                         i = ++last_hvc + MAX_NR_HVC_CONSOLES;
     961             :         }
     962             : 
     963           0 :         hp->index = i;
     964           0 :         if (i < MAX_NR_HVC_CONSOLES) {
     965           0 :                 cons_ops[i] = ops;
     966           0 :                 vtermnos[i] = vtermno;
     967             :         }
     968             : 
     969           0 :         list_add_tail(&(hp->next), &hvc_structs);
     970           0 :         mutex_unlock(&hvc_structs_mutex);
     971             : 
     972             :         /* check if we need to re-register the kernel console */
     973           0 :         hvc_check_console(i);
     974             : 
     975           0 :         return hp;
     976             : }
     977             : EXPORT_SYMBOL_GPL(hvc_alloc);
     978             : 
     979           0 : int hvc_remove(struct hvc_struct *hp)
     980             : {
     981           0 :         unsigned long flags;
     982           0 :         struct tty_struct *tty;
     983             : 
     984           0 :         tty = tty_port_tty_get(&hp->port);
     985             : 
     986           0 :         console_lock();
     987           0 :         spin_lock_irqsave(&hp->lock, flags);
     988           0 :         if (hp->index < MAX_NR_HVC_CONSOLES) {
     989           0 :                 vtermnos[hp->index] = -1;
     990           0 :                 cons_ops[hp->index] = NULL;
     991             :         }
     992             : 
     993             :         /* Don't whack hp->irq because tty_hangup() will need to free the irq. */
     994             : 
     995           0 :         spin_unlock_irqrestore(&hp->lock, flags);
     996           0 :         console_unlock();
     997             : 
     998             :         /*
     999             :          * We 'put' the instance that was grabbed when the kref instance
    1000             :          * was initialized using kref_init().  Let the last holder of this
    1001             :          * kref cause it to be removed, which will probably be the tty_vhangup
    1002             :          * below.
    1003             :          */
    1004           0 :         tty_port_put(&hp->port);
    1005             : 
    1006             :         /*
    1007             :          * This function call will auto chain call hvc_hangup.
    1008             :          */
    1009           0 :         if (tty) {
    1010           0 :                 tty_vhangup(tty);
    1011           0 :                 tty_kref_put(tty);
    1012             :         }
    1013           0 :         return 0;
    1014             : }
    1015             : EXPORT_SYMBOL_GPL(hvc_remove);
    1016             : 
    1017             : /* Driver initialization: called as soon as someone uses hvc_alloc(). */
    1018           0 : static int hvc_init(void)
    1019             : {
    1020           0 :         struct tty_driver *drv;
    1021           0 :         int err;
    1022             : 
    1023             :         /* We need more than hvc_count adapters due to hotplug additions. */
    1024           0 :         drv = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
    1025           0 :         if (!drv) {
    1026           0 :                 err = -ENOMEM;
    1027           0 :                 goto out;
    1028             :         }
    1029             : 
    1030           0 :         drv->driver_name = "hvc";
    1031           0 :         drv->name = "hvc";
    1032           0 :         drv->major = HVC_MAJOR;
    1033           0 :         drv->minor_start = HVC_MINOR;
    1034           0 :         drv->type = TTY_DRIVER_TYPE_SYSTEM;
    1035           0 :         drv->init_termios = tty_std_termios;
    1036           0 :         drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
    1037           0 :         tty_set_operations(drv, &hvc_ops);
    1038             : 
    1039             :         /* Always start the kthread because there can be hotplug vty adapters
    1040             :          * added later. */
    1041           0 :         hvc_task = kthread_run(khvcd, NULL, "khvcd");
    1042           0 :         if (IS_ERR(hvc_task)) {
    1043           0 :                 printk(KERN_ERR "Couldn't create kthread for console.\n");
    1044           0 :                 err = PTR_ERR(hvc_task);
    1045           0 :                 goto put_tty;
    1046             :         }
    1047             : 
    1048           0 :         err = tty_register_driver(drv);
    1049           0 :         if (err) {
    1050           0 :                 printk(KERN_ERR "Couldn't register hvc console driver\n");
    1051           0 :                 goto stop_thread;
    1052             :         }
    1053             : 
    1054             :         /*
    1055             :          * Make sure tty is fully registered before allowing it to be
    1056             :          * found by hvc_console_device.
    1057             :          */
    1058           0 :         smp_mb();
    1059           0 :         hvc_driver = drv;
    1060           0 :         return 0;
    1061             : 
    1062           0 : stop_thread:
    1063           0 :         kthread_stop(hvc_task);
    1064           0 :         hvc_task = NULL;
    1065           0 : put_tty:
    1066           0 :         put_tty_driver(drv);
    1067             : out:
    1068             :         return err;
    1069             : }

Generated by: LCOV version 1.14