LCOV - code coverage report
Current view: top level - drivers/tty/serial - kgdboc.c (source / functions) Hit Total Coverage
Test: Real Lines: 26 143 18.2 %
Date: 2020-10-17 15:46:43 Functions: 0 18 0.0 %
Legend: Neither, QEMU, Real, Both Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : /*
       3                 :            :  * Based on the same principle as kgdboe using the NETPOLL api, this
       4                 :            :  * driver uses a console polling api to implement a gdb serial inteface
       5                 :            :  * which is multiplexed on a console port.
       6                 :            :  *
       7                 :            :  * Maintainer: Jason Wessel <jason.wessel@windriver.com>
       8                 :            :  *
       9                 :            :  * 2007-2008 (c) Jason Wessel - Wind River Systems, Inc.
      10                 :            :  */
      11                 :            : 
      12                 :            : #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      13                 :            : 
      14                 :            : #include <linux/kernel.h>
      15                 :            : #include <linux/ctype.h>
      16                 :            : #include <linux/kgdb.h>
      17                 :            : #include <linux/kdb.h>
      18                 :            : #include <linux/tty.h>
      19                 :            : #include <linux/console.h>
      20                 :            : #include <linux/vt_kern.h>
      21                 :            : #include <linux/input.h>
      22                 :            : #include <linux/module.h>
      23                 :            : #include <linux/platform_device.h>
      24                 :            : 
      25                 :            : #define MAX_CONFIG_LEN          40
      26                 :            : 
      27                 :            : static struct kgdb_io           kgdboc_io_ops;
      28                 :            : 
      29                 :            : /* -1 = init not run yet, 0 = unconfigured, 1 = configured. */
      30                 :            : static int configured           = -1;
      31                 :            : static DEFINE_MUTEX(config_mutex);
      32                 :            : 
      33                 :            : static char config[MAX_CONFIG_LEN];
      34                 :            : static struct kparam_string kps = {
      35                 :            :         .string                 = config,
      36                 :            :         .maxlen                 = MAX_CONFIG_LEN,
      37                 :            : };
      38                 :            : 
      39                 :            : static int kgdboc_use_kms;  /* 1 if we use kernel mode switching */
      40                 :            : static struct tty_driver        *kgdb_tty_driver;
      41                 :            : static int                      kgdb_tty_line;
      42                 :            : 
      43                 :            : static struct platform_device *kgdboc_pdev;
      44                 :            : 
      45                 :            : #ifdef CONFIG_KDB_KEYBOARD
      46                 :          0 : static int kgdboc_reset_connect(struct input_handler *handler,
      47                 :            :                                 struct input_dev *dev,
      48                 :            :                                 const struct input_device_id *id)
      49                 :            : {
      50                 :          0 :         input_reset_device(dev);
      51                 :            : 
      52                 :            :         /* Return an error - we do not want to bind, just to reset */
      53                 :          0 :         return -ENODEV;
      54                 :            : }
      55                 :            : 
      56                 :          0 : static void kgdboc_reset_disconnect(struct input_handle *handle)
      57                 :            : {
      58                 :            :         /* We do not expect anyone to actually bind to us */
      59                 :          0 :         BUG();
      60                 :            : }
      61                 :            : 
      62                 :            : static const struct input_device_id kgdboc_reset_ids[] = {
      63                 :            :         {
      64                 :            :                 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
      65                 :            :                 .evbit = { BIT_MASK(EV_KEY) },
      66                 :            :         },
      67                 :            :         { }
      68                 :            : };
      69                 :            : 
      70                 :            : static struct input_handler kgdboc_reset_handler = {
      71                 :            :         .connect        = kgdboc_reset_connect,
      72                 :            :         .disconnect     = kgdboc_reset_disconnect,
      73                 :            :         .name           = "kgdboc_reset",
      74                 :            :         .id_table       = kgdboc_reset_ids,
      75                 :            : };
      76                 :            : 
      77                 :            : static DEFINE_MUTEX(kgdboc_reset_mutex);
      78                 :            : 
      79                 :          0 : static void kgdboc_restore_input_helper(struct work_struct *dummy)
      80                 :            : {
      81                 :            :         /*
      82                 :            :          * We need to take a mutex to prevent several instances of
      83                 :            :          * this work running on different CPUs so they don't try
      84                 :            :          * to register again already registered handler.
      85                 :            :          */
      86                 :          0 :         mutex_lock(&kgdboc_reset_mutex);
      87                 :            : 
      88                 :          0 :         if (input_register_handler(&kgdboc_reset_handler) == 0)
      89                 :          0 :                 input_unregister_handler(&kgdboc_reset_handler);
      90                 :            : 
      91                 :          0 :         mutex_unlock(&kgdboc_reset_mutex);
      92                 :          0 : }
      93                 :            : 
      94                 :            : static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper);
      95                 :            : 
      96                 :          0 : static void kgdboc_restore_input(void)
      97                 :            : {
      98                 :          0 :         if (likely(system_state == SYSTEM_RUNNING))
      99                 :            :                 schedule_work(&kgdboc_restore_input_work);
     100                 :          0 : }
     101                 :            : 
     102                 :          0 : static int kgdboc_register_kbd(char **cptr)
     103                 :            : {
     104                 :          0 :         if (strncmp(*cptr, "kbd", 3) == 0 ||
     105                 :          0 :                 strncmp(*cptr, "kdb", 3) == 0) {
     106                 :          0 :                 if (kdb_poll_idx < KDB_POLL_FUNC_MAX) {
     107                 :          0 :                         kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char;
     108                 :          0 :                         kdb_poll_idx++;
     109                 :          0 :                         if (cptr[0][3] == ',')
     110                 :          0 :                                 *cptr += 4;
     111                 :            :                         else
     112                 :            :                                 return 1;
     113                 :            :                 }
     114                 :            :         }
     115                 :            :         return 0;
     116                 :            : }
     117                 :            : 
     118                 :          3 : static void kgdboc_unregister_kbd(void)
     119                 :            : {
     120                 :            :         int i;
     121                 :            : 
     122                 :          3 :         for (i = 0; i < kdb_poll_idx; i++) {
     123                 :          3 :                 if (kdb_poll_funcs[i] == kdb_get_kbd_char) {
     124                 :          0 :                         kdb_poll_idx--;
     125                 :          0 :                         kdb_poll_funcs[i] = kdb_poll_funcs[kdb_poll_idx];
     126                 :          0 :                         kdb_poll_funcs[kdb_poll_idx] = NULL;
     127                 :          0 :                         i--;
     128                 :            :                 }
     129                 :            :         }
     130                 :          3 :         flush_work(&kgdboc_restore_input_work);
     131                 :          3 : }
     132                 :            : #else /* ! CONFIG_KDB_KEYBOARD */
     133                 :            : #define kgdboc_register_kbd(x) 0
     134                 :            : #define kgdboc_unregister_kbd()
     135                 :            : #define kgdboc_restore_input()
     136                 :            : #endif /* ! CONFIG_KDB_KEYBOARD */
     137                 :            : 
     138                 :          0 : static void cleanup_kgdboc(void)
     139                 :            : {
     140                 :          0 :         if (configured != 1)
     141                 :            :                 return;
     142                 :            : 
     143                 :            :         if (kgdb_unregister_nmi_console())
     144                 :            :                 return;
     145                 :          0 :         kgdboc_unregister_kbd();
     146                 :          0 :         kgdb_unregister_io_module(&kgdboc_io_ops);
     147                 :            : }
     148                 :            : 
     149                 :          3 : static int configure_kgdboc(void)
     150                 :            : {
     151                 :            :         struct tty_driver *p;
     152                 :          3 :         int tty_line = 0;
     153                 :            :         int err = -ENODEV;
     154                 :          3 :         char *cptr = config;
     155                 :            :         struct console *cons;
     156                 :            : 
     157                 :          3 :         if (!strlen(config) || isspace(config[0])) {
     158                 :            :                 err = 0;
     159                 :            :                 goto noconfig;
     160                 :            :         }
     161                 :            : 
     162                 :          0 :         kgdboc_io_ops.is_console = 0;
     163                 :          0 :         kgdb_tty_driver = NULL;
     164                 :            : 
     165                 :          0 :         kgdboc_use_kms = 0;
     166                 :          0 :         if (strncmp(cptr, "kms,", 4) == 0) {
     167                 :          0 :                 cptr += 4;
     168                 :          0 :                 kgdboc_use_kms = 1;
     169                 :            :         }
     170                 :            : 
     171                 :          0 :         if (kgdboc_register_kbd(&cptr))
     172                 :            :                 goto do_register;
     173                 :            : 
     174                 :          0 :         p = tty_find_polling_driver(cptr, &tty_line);
     175                 :          0 :         if (!p)
     176                 :            :                 goto noconfig;
     177                 :            : 
     178                 :          0 :         cons = console_drivers;
     179                 :          0 :         while (cons) {
     180                 :            :                 int idx;
     181                 :          0 :                 if (cons->device && cons->device(cons, &idx) == p &&
     182                 :          0 :                     idx == tty_line) {
     183                 :          0 :                         kgdboc_io_ops.is_console = 1;
     184                 :          0 :                         break;
     185                 :            :                 }
     186                 :          0 :                 cons = cons->next;
     187                 :            :         }
     188                 :            : 
     189                 :          0 :         kgdb_tty_driver = p;
     190                 :          0 :         kgdb_tty_line = tty_line;
     191                 :            : 
     192                 :            : do_register:
     193                 :          0 :         err = kgdb_register_io_module(&kgdboc_io_ops);
     194                 :          0 :         if (err)
     195                 :            :                 goto noconfig;
     196                 :            : 
     197                 :            :         err = kgdb_register_nmi_console();
     198                 :            :         if (err)
     199                 :            :                 goto nmi_con_failed;
     200                 :            : 
     201                 :          0 :         configured = 1;
     202                 :            : 
     203                 :          0 :         return 0;
     204                 :            : 
     205                 :            : nmi_con_failed:
     206                 :            :         kgdb_unregister_io_module(&kgdboc_io_ops);
     207                 :            : noconfig:
     208                 :          3 :         kgdboc_unregister_kbd();
     209                 :          3 :         configured = 0;
     210                 :            : 
     211                 :          3 :         return err;
     212                 :            : }
     213                 :            : 
     214                 :          3 : static int kgdboc_probe(struct platform_device *pdev)
     215                 :            : {
     216                 :            :         int ret = 0;
     217                 :            : 
     218                 :          3 :         mutex_lock(&config_mutex);
     219                 :          3 :         if (configured != 1) {
     220                 :          3 :                 ret = configure_kgdboc();
     221                 :            : 
     222                 :            :                 /* Convert "no device" to "defer" so we'll keep trying */
     223                 :          3 :                 if (ret == -ENODEV)
     224                 :            :                         ret = -EPROBE_DEFER;
     225                 :            :         }
     226                 :          3 :         mutex_unlock(&config_mutex);
     227                 :            : 
     228                 :          3 :         return ret;
     229                 :            : }
     230                 :            : 
     231                 :            : static struct platform_driver kgdboc_platform_driver = {
     232                 :            :         .probe = kgdboc_probe,
     233                 :            :         .driver = {
     234                 :            :                 .name = "kgdboc",
     235                 :            :                 .suppress_bind_attrs = true,
     236                 :            :         },
     237                 :            : };
     238                 :            : 
     239                 :          3 : static int __init init_kgdboc(void)
     240                 :            : {
     241                 :            :         int ret;
     242                 :            : 
     243                 :            :         /*
     244                 :            :          * kgdboc is a little bit of an odd "platform_driver".  It can be
     245                 :            :          * up and running long before the platform_driver object is
     246                 :            :          * created and thus doesn't actually store anything in it.  There's
     247                 :            :          * only one instance of kgdb so anything is stored as global state.
     248                 :            :          * The platform_driver is only created so that we can leverage the
     249                 :            :          * kernel's mechanisms (like -EPROBE_DEFER) to call us when our
     250                 :            :          * underlying tty is ready.  Here we init our platform driver and
     251                 :            :          * then create the single kgdboc instance.
     252                 :            :          */
     253                 :          3 :         ret = platform_driver_register(&kgdboc_platform_driver);
     254                 :          3 :         if (ret)
     255                 :            :                 return ret;
     256                 :            : 
     257                 :          3 :         kgdboc_pdev = platform_device_alloc("kgdboc", PLATFORM_DEVID_NONE);
     258                 :          3 :         if (!kgdboc_pdev) {
     259                 :            :                 ret = -ENOMEM;
     260                 :            :                 goto err_did_register;
     261                 :            :         }
     262                 :            : 
     263                 :          3 :         ret = platform_device_add(kgdboc_pdev);
     264                 :          3 :         if (!ret)
     265                 :            :                 return 0;
     266                 :            : 
     267                 :          0 :         platform_device_put(kgdboc_pdev);
     268                 :            : 
     269                 :            : err_did_register:
     270                 :          0 :         platform_driver_unregister(&kgdboc_platform_driver);
     271                 :          0 :         return ret;
     272                 :            : }
     273                 :            : 
     274                 :          0 : static void exit_kgdboc(void)
     275                 :            : {
     276                 :          0 :         mutex_lock(&config_mutex);
     277                 :          0 :         cleanup_kgdboc();
     278                 :          0 :         mutex_unlock(&config_mutex);
     279                 :            : 
     280                 :          0 :         platform_device_unregister(kgdboc_pdev);
     281                 :          0 :         platform_driver_unregister(&kgdboc_platform_driver);
     282                 :          0 : }
     283                 :            : 
     284                 :          0 : static int kgdboc_get_char(void)
     285                 :            : {
     286                 :          0 :         if (!kgdb_tty_driver)
     287                 :            :                 return -1;
     288                 :          0 :         return kgdb_tty_driver->ops->poll_get_char(kgdb_tty_driver,
     289                 :            :                                                 kgdb_tty_line);
     290                 :            : }
     291                 :            : 
     292                 :          0 : static void kgdboc_put_char(u8 chr)
     293                 :            : {
     294                 :          0 :         if (!kgdb_tty_driver)
     295                 :          0 :                 return;
     296                 :          0 :         kgdb_tty_driver->ops->poll_put_char(kgdb_tty_driver,
     297                 :            :                                         kgdb_tty_line, chr);
     298                 :            : }
     299                 :            : 
     300                 :          0 : static int param_set_kgdboc_var(const char *kmessage,
     301                 :            :                                 const struct kernel_param *kp)
     302                 :            : {
     303                 :          0 :         size_t len = strlen(kmessage);
     304                 :            :         int ret = 0;
     305                 :            : 
     306                 :          0 :         if (len >= MAX_CONFIG_LEN) {
     307                 :          0 :                 pr_err("config string too long\n");
     308                 :          0 :                 return -ENOSPC;
     309                 :            :         }
     310                 :            : 
     311                 :          0 :         if (kgdb_connected) {
     312                 :          0 :                 pr_err("Cannot reconfigure while KGDB is connected.\n");
     313                 :          0 :                 return -EBUSY;
     314                 :            :         }
     315                 :            : 
     316                 :          0 :         mutex_lock(&config_mutex);
     317                 :            : 
     318                 :          0 :         strcpy(config, kmessage);
     319                 :            :         /* Chop out \n char as a result of echo */
     320                 :          0 :         if (len && config[len - 1] == '\n')
     321                 :          0 :                 config[len - 1] = '\0';
     322                 :            : 
     323                 :          0 :         if (configured == 1)
     324                 :          0 :                 cleanup_kgdboc();
     325                 :            : 
     326                 :            :         /*
     327                 :            :          * Configure with the new params as long as init already ran.
     328                 :            :          * Note that we can get called before init if someone loads us
     329                 :            :          * with "modprobe kgdboc kgdboc=..." or if they happen to use the
     330                 :            :          * the odd syntax of "kgdboc.kgdboc=..." on the kernel command.
     331                 :            :          */
     332                 :          0 :         if (configured >= 0)
     333                 :          0 :                 ret = configure_kgdboc();
     334                 :            : 
     335                 :            :         /*
     336                 :            :          * If we couldn't configure then clear out the config.  Note that
     337                 :            :          * specifying an invalid config on the kernel command line vs.
     338                 :            :          * through sysfs have slightly different behaviors.  If we fail
     339                 :            :          * to configure what was specified on the kernel command line
     340                 :            :          * we'll leave it in the 'config' and return -EPROBE_DEFER from
     341                 :            :          * our probe.  When specified through sysfs userspace is
     342                 :            :          * responsible for loading the tty driver before setting up.
     343                 :            :          */
     344                 :          0 :         if (ret)
     345                 :          0 :                 config[0] = '\0';
     346                 :            : 
     347                 :          0 :         mutex_unlock(&config_mutex);
     348                 :            : 
     349                 :          0 :         return ret;
     350                 :            : }
     351                 :            : 
     352                 :            : static int dbg_restore_graphics;
     353                 :            : 
     354                 :          0 : static void kgdboc_pre_exp_handler(void)
     355                 :            : {
     356                 :          0 :         if (!dbg_restore_graphics && kgdboc_use_kms) {
     357                 :          0 :                 dbg_restore_graphics = 1;
     358                 :          0 :                 con_debug_enter(vc_cons[fg_console].d);
     359                 :            :         }
     360                 :            :         /* Increment the module count when the debugger is active */
     361                 :          0 :         if (!kgdb_connected)
     362                 :          0 :                 try_module_get(THIS_MODULE);
     363                 :            : 
     364                 :            :         atomic_inc(&ignore_console_lock_warning);
     365                 :          0 : }
     366                 :            : 
     367                 :          0 : static void kgdboc_post_exp_handler(void)
     368                 :            : {
     369                 :            :         atomic_dec(&ignore_console_lock_warning);
     370                 :            : 
     371                 :            :         /* decrement the module count when the debugger detaches */
     372                 :          0 :         if (!kgdb_connected)
     373                 :          0 :                 module_put(THIS_MODULE);
     374                 :          0 :         if (kgdboc_use_kms && dbg_restore_graphics) {
     375                 :          0 :                 dbg_restore_graphics = 0;
     376                 :          0 :                 con_debug_leave();
     377                 :            :         }
     378                 :          0 :         kgdboc_restore_input();
     379                 :          0 : }
     380                 :            : 
     381                 :            : static struct kgdb_io kgdboc_io_ops = {
     382                 :            :         .name                   = "kgdboc",
     383                 :            :         .read_char              = kgdboc_get_char,
     384                 :            :         .write_char             = kgdboc_put_char,
     385                 :            :         .pre_exception          = kgdboc_pre_exp_handler,
     386                 :            :         .post_exception         = kgdboc_post_exp_handler,
     387                 :            : };
     388                 :            : 
     389                 :            : #ifdef CONFIG_KGDB_SERIAL_CONSOLE
     390                 :          0 : static int kgdboc_option_setup(char *opt)
     391                 :            : {
     392                 :          0 :         if (!opt) {
     393                 :          0 :                 pr_err("config string not provided\n");
     394                 :          0 :                 return -EINVAL;
     395                 :            :         }
     396                 :            : 
     397                 :          0 :         if (strlen(opt) >= MAX_CONFIG_LEN) {
     398                 :          0 :                 pr_err("config string too long\n");
     399                 :          0 :                 return -ENOSPC;
     400                 :            :         }
     401                 :          0 :         strcpy(config, opt);
     402                 :            : 
     403                 :          0 :         return 0;
     404                 :            : }
     405                 :            : 
     406                 :            : __setup("kgdboc=", kgdboc_option_setup);
     407                 :            : 
     408                 :            : 
     409                 :            : /* This is only available if kgdboc is a built in for early debugging */
     410                 :          0 : static int __init kgdboc_early_init(char *opt)
     411                 :            : {
     412                 :          0 :         kgdboc_option_setup(opt);
     413                 :          0 :         configure_kgdboc();
     414                 :          0 :         return 0;
     415                 :            : }
     416                 :            : 
     417                 :            : early_param("ekgdboc", kgdboc_early_init);
     418                 :            : #endif /* CONFIG_KGDB_SERIAL_CONSOLE */
     419                 :            : 
     420                 :            : module_init(init_kgdboc);
     421                 :            : module_exit(exit_kgdboc);
     422                 :            : module_param_call(kgdboc, param_set_kgdboc_var, param_get_string, &kps, 0644);
     423                 :            : MODULE_PARM_DESC(kgdboc, "<serial_device>[,baud]");
     424                 :            : MODULE_DESCRIPTION("KGDB Console TTY Driver");
     425                 :            : MODULE_LICENSE("GPL");
    

Generated by: LCOV version 1.14