0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0013
0014 #include <linux/kernel.h>
0015 #include <linux/ctype.h>
0016 #include <linux/kgdb.h>
0017 #include <linux/kdb.h>
0018 #include <linux/tty.h>
0019 #include <linux/console.h>
0020 #include <linux/vt_kern.h>
0021 #include <linux/input.h>
0022 #include <linux/module.h>
0023 #include <linux/platform_device.h>
0024 #include <linux/serial_core.h>
0025
0026 #define MAX_CONFIG_LEN 40
0027
0028 static struct kgdb_io kgdboc_io_ops;
0029
0030
0031 static int configured = -1;
0032 static DEFINE_MUTEX(config_mutex);
0033
0034 static char config[MAX_CONFIG_LEN];
0035 static struct kparam_string kps = {
0036 .string = config,
0037 .maxlen = MAX_CONFIG_LEN,
0038 };
0039
0040 static int kgdboc_use_kms;
0041 static struct tty_driver *kgdb_tty_driver;
0042 static int kgdb_tty_line;
0043
0044 static struct platform_device *kgdboc_pdev;
0045
0046 #if IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE)
0047 static struct kgdb_io kgdboc_earlycon_io_ops;
0048 static int (*earlycon_orig_exit)(struct console *con);
0049 #endif
0050
0051 #ifdef CONFIG_KDB_KEYBOARD
0052 static int kgdboc_reset_connect(struct input_handler *handler,
0053 struct input_dev *dev,
0054 const struct input_device_id *id)
0055 {
0056 input_reset_device(dev);
0057
0058
0059 return -ENODEV;
0060 }
0061
0062 static void kgdboc_reset_disconnect(struct input_handle *handle)
0063 {
0064
0065 BUG();
0066 }
0067
0068 static const struct input_device_id kgdboc_reset_ids[] = {
0069 {
0070 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
0071 .evbit = { BIT_MASK(EV_KEY) },
0072 },
0073 { }
0074 };
0075
0076 static struct input_handler kgdboc_reset_handler = {
0077 .connect = kgdboc_reset_connect,
0078 .disconnect = kgdboc_reset_disconnect,
0079 .name = "kgdboc_reset",
0080 .id_table = kgdboc_reset_ids,
0081 };
0082
0083 static DEFINE_MUTEX(kgdboc_reset_mutex);
0084
0085 static void kgdboc_restore_input_helper(struct work_struct *dummy)
0086 {
0087
0088
0089
0090
0091
0092 mutex_lock(&kgdboc_reset_mutex);
0093
0094 if (input_register_handler(&kgdboc_reset_handler) == 0)
0095 input_unregister_handler(&kgdboc_reset_handler);
0096
0097 mutex_unlock(&kgdboc_reset_mutex);
0098 }
0099
0100 static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper);
0101
0102 static void kgdboc_restore_input(void)
0103 {
0104 if (likely(system_state == SYSTEM_RUNNING))
0105 schedule_work(&kgdboc_restore_input_work);
0106 }
0107
0108 static int kgdboc_register_kbd(char **cptr)
0109 {
0110 if (strncmp(*cptr, "kbd", 3) == 0 ||
0111 strncmp(*cptr, "kdb", 3) == 0) {
0112 if (kdb_poll_idx < KDB_POLL_FUNC_MAX) {
0113 kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char;
0114 kdb_poll_idx++;
0115 if (cptr[0][3] == ',')
0116 *cptr += 4;
0117 else
0118 return 1;
0119 }
0120 }
0121 return 0;
0122 }
0123
0124 static void kgdboc_unregister_kbd(void)
0125 {
0126 int i;
0127
0128 for (i = 0; i < kdb_poll_idx; i++) {
0129 if (kdb_poll_funcs[i] == kdb_get_kbd_char) {
0130 kdb_poll_idx--;
0131 kdb_poll_funcs[i] = kdb_poll_funcs[kdb_poll_idx];
0132 kdb_poll_funcs[kdb_poll_idx] = NULL;
0133 i--;
0134 }
0135 }
0136 flush_work(&kgdboc_restore_input_work);
0137 }
0138 #else
0139 #define kgdboc_register_kbd(x) 0
0140 #define kgdboc_unregister_kbd()
0141 #define kgdboc_restore_input()
0142 #endif
0143
0144 #if IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE)
0145 static void cleanup_earlycon(void)
0146 {
0147 if (kgdboc_earlycon_io_ops.cons)
0148 kgdb_unregister_io_module(&kgdboc_earlycon_io_ops);
0149 }
0150 #else
0151 static inline void cleanup_earlycon(void) { }
0152 #endif
0153
0154 static void cleanup_kgdboc(void)
0155 {
0156 cleanup_earlycon();
0157
0158 if (configured != 1)
0159 return;
0160
0161 if (kgdb_unregister_nmi_console())
0162 return;
0163 kgdboc_unregister_kbd();
0164 kgdb_unregister_io_module(&kgdboc_io_ops);
0165 }
0166
0167 static int configure_kgdboc(void)
0168 {
0169 struct tty_driver *p;
0170 int tty_line = 0;
0171 int err = -ENODEV;
0172 char *cptr = config;
0173 struct console *cons;
0174
0175 if (!strlen(config) || isspace(config[0])) {
0176 err = 0;
0177 goto noconfig;
0178 }
0179
0180 kgdboc_io_ops.cons = NULL;
0181 kgdb_tty_driver = NULL;
0182
0183 kgdboc_use_kms = 0;
0184 if (strncmp(cptr, "kms,", 4) == 0) {
0185 cptr += 4;
0186 kgdboc_use_kms = 1;
0187 }
0188
0189 if (kgdboc_register_kbd(&cptr))
0190 goto do_register;
0191
0192 p = tty_find_polling_driver(cptr, &tty_line);
0193 if (!p)
0194 goto noconfig;
0195
0196 for_each_console(cons) {
0197 int idx;
0198 if (cons->device && cons->device(cons, &idx) == p &&
0199 idx == tty_line) {
0200 kgdboc_io_ops.cons = cons;
0201 break;
0202 }
0203 }
0204
0205 kgdb_tty_driver = p;
0206 kgdb_tty_line = tty_line;
0207
0208 do_register:
0209 err = kgdb_register_io_module(&kgdboc_io_ops);
0210 if (err)
0211 goto noconfig;
0212
0213 err = kgdb_register_nmi_console();
0214 if (err)
0215 goto nmi_con_failed;
0216
0217 configured = 1;
0218
0219 return 0;
0220
0221 nmi_con_failed:
0222 kgdb_unregister_io_module(&kgdboc_io_ops);
0223 noconfig:
0224 kgdboc_unregister_kbd();
0225 configured = 0;
0226
0227 return err;
0228 }
0229
0230 static int kgdboc_probe(struct platform_device *pdev)
0231 {
0232 int ret = 0;
0233
0234 mutex_lock(&config_mutex);
0235 if (configured != 1) {
0236 ret = configure_kgdboc();
0237
0238
0239 if (ret == -ENODEV)
0240 ret = -EPROBE_DEFER;
0241 }
0242 mutex_unlock(&config_mutex);
0243
0244 return ret;
0245 }
0246
0247 static struct platform_driver kgdboc_platform_driver = {
0248 .probe = kgdboc_probe,
0249 .driver = {
0250 .name = "kgdboc",
0251 .suppress_bind_attrs = true,
0252 },
0253 };
0254
0255 static int __init init_kgdboc(void)
0256 {
0257 int ret;
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269 ret = platform_driver_register(&kgdboc_platform_driver);
0270 if (ret)
0271 return ret;
0272
0273 kgdboc_pdev = platform_device_alloc("kgdboc", PLATFORM_DEVID_NONE);
0274 if (!kgdboc_pdev) {
0275 ret = -ENOMEM;
0276 goto err_did_register;
0277 }
0278
0279 ret = platform_device_add(kgdboc_pdev);
0280 if (!ret)
0281 return 0;
0282
0283 platform_device_put(kgdboc_pdev);
0284
0285 err_did_register:
0286 platform_driver_unregister(&kgdboc_platform_driver);
0287 return ret;
0288 }
0289
0290 static void exit_kgdboc(void)
0291 {
0292 mutex_lock(&config_mutex);
0293 cleanup_kgdboc();
0294 mutex_unlock(&config_mutex);
0295
0296 platform_device_unregister(kgdboc_pdev);
0297 platform_driver_unregister(&kgdboc_platform_driver);
0298 }
0299
0300 static int kgdboc_get_char(void)
0301 {
0302 if (!kgdb_tty_driver)
0303 return -1;
0304 return kgdb_tty_driver->ops->poll_get_char(kgdb_tty_driver,
0305 kgdb_tty_line);
0306 }
0307
0308 static void kgdboc_put_char(u8 chr)
0309 {
0310 if (!kgdb_tty_driver)
0311 return;
0312 kgdb_tty_driver->ops->poll_put_char(kgdb_tty_driver,
0313 kgdb_tty_line, chr);
0314 }
0315
0316 static int param_set_kgdboc_var(const char *kmessage,
0317 const struct kernel_param *kp)
0318 {
0319 size_t len = strlen(kmessage);
0320 int ret = 0;
0321
0322 if (len >= MAX_CONFIG_LEN) {
0323 pr_err("config string too long\n");
0324 return -ENOSPC;
0325 }
0326
0327 if (kgdb_connected) {
0328 pr_err("Cannot reconfigure while KGDB is connected.\n");
0329 return -EBUSY;
0330 }
0331
0332 mutex_lock(&config_mutex);
0333
0334 strcpy(config, kmessage);
0335
0336 if (len && config[len - 1] == '\n')
0337 config[len - 1] = '\0';
0338
0339 if (configured == 1)
0340 cleanup_kgdboc();
0341
0342
0343
0344
0345
0346
0347
0348 if (configured >= 0)
0349 ret = configure_kgdboc();
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360 if (ret)
0361 config[0] = '\0';
0362
0363 mutex_unlock(&config_mutex);
0364
0365 return ret;
0366 }
0367
0368 static int dbg_restore_graphics;
0369
0370 static void kgdboc_pre_exp_handler(void)
0371 {
0372 if (!dbg_restore_graphics && kgdboc_use_kms) {
0373 dbg_restore_graphics = 1;
0374 con_debug_enter(vc_cons[fg_console].d);
0375 }
0376
0377 if (!kgdb_connected)
0378 try_module_get(THIS_MODULE);
0379 }
0380
0381 static void kgdboc_post_exp_handler(void)
0382 {
0383
0384 if (!kgdb_connected)
0385 module_put(THIS_MODULE);
0386 if (kgdboc_use_kms && dbg_restore_graphics) {
0387 dbg_restore_graphics = 0;
0388 con_debug_leave();
0389 }
0390 kgdboc_restore_input();
0391 }
0392
0393 static struct kgdb_io kgdboc_io_ops = {
0394 .name = "kgdboc",
0395 .read_char = kgdboc_get_char,
0396 .write_char = kgdboc_put_char,
0397 .pre_exception = kgdboc_pre_exp_handler,
0398 .post_exception = kgdboc_post_exp_handler,
0399 };
0400
0401 #if IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE)
0402 static int kgdboc_option_setup(char *opt)
0403 {
0404 if (!opt) {
0405 pr_err("config string not provided\n");
0406 return 1;
0407 }
0408
0409 if (strlen(opt) >= MAX_CONFIG_LEN) {
0410 pr_err("config string too long\n");
0411 return 1;
0412 }
0413 strcpy(config, opt);
0414
0415 return 1;
0416 }
0417
0418 __setup("kgdboc=", kgdboc_option_setup);
0419
0420
0421
0422 static int __init kgdboc_early_init(char *opt)
0423 {
0424 kgdboc_option_setup(opt);
0425 configure_kgdboc();
0426 return 0;
0427 }
0428
0429 early_param("ekgdboc", kgdboc_early_init);
0430
0431 static int kgdboc_earlycon_get_char(void)
0432 {
0433 char c;
0434
0435 if (!kgdboc_earlycon_io_ops.cons->read(kgdboc_earlycon_io_ops.cons,
0436 &c, 1))
0437 return NO_POLL_CHAR;
0438
0439 return c;
0440 }
0441
0442 static void kgdboc_earlycon_put_char(u8 chr)
0443 {
0444 kgdboc_earlycon_io_ops.cons->write(kgdboc_earlycon_io_ops.cons, &chr,
0445 1);
0446 }
0447
0448 static void kgdboc_earlycon_pre_exp_handler(void)
0449 {
0450 struct console *con;
0451 static bool already_warned;
0452
0453 if (already_warned)
0454 return;
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464 for_each_console(con)
0465 if (con == kgdboc_earlycon_io_ops.cons)
0466 return;
0467
0468 already_warned = true;
0469 pr_warn("kgdboc_earlycon is still using bootconsole\n");
0470 }
0471
0472 static int kgdboc_earlycon_deferred_exit(struct console *con)
0473 {
0474
0475
0476
0477
0478
0479
0480
0481 con->exit = earlycon_orig_exit;
0482
0483 return 0;
0484 }
0485
0486 static void kgdboc_earlycon_deinit(void)
0487 {
0488 if (!kgdboc_earlycon_io_ops.cons)
0489 return;
0490
0491 if (kgdboc_earlycon_io_ops.cons->exit == kgdboc_earlycon_deferred_exit)
0492
0493
0494
0495
0496
0497 kgdboc_earlycon_io_ops.cons->exit = earlycon_orig_exit;
0498 else if (kgdboc_earlycon_io_ops.cons->exit)
0499
0500
0501
0502
0503
0504 kgdboc_earlycon_io_ops.cons->exit(kgdboc_earlycon_io_ops.cons);
0505
0506 kgdboc_earlycon_io_ops.cons = NULL;
0507 }
0508
0509 static struct kgdb_io kgdboc_earlycon_io_ops = {
0510 .name = "kgdboc_earlycon",
0511 .read_char = kgdboc_earlycon_get_char,
0512 .write_char = kgdboc_earlycon_put_char,
0513 .pre_exception = kgdboc_earlycon_pre_exp_handler,
0514 .deinit = kgdboc_earlycon_deinit,
0515 };
0516
0517 #define MAX_CONSOLE_NAME_LEN (sizeof((struct console *) 0)->name)
0518 static char kgdboc_earlycon_param[MAX_CONSOLE_NAME_LEN] __initdata;
0519 static bool kgdboc_earlycon_late_enable __initdata;
0520
0521 static int __init kgdboc_earlycon_init(char *opt)
0522 {
0523 struct console *con;
0524
0525 kdb_init(KDB_INIT_EARLY);
0526
0527
0528
0529
0530
0531 console_lock();
0532 for_each_console(con) {
0533 if (con->write && con->read &&
0534 (con->flags & (CON_BOOT | CON_ENABLED)) &&
0535 (!opt || !opt[0] || strcmp(con->name, opt) == 0))
0536 break;
0537 }
0538
0539 if (!con) {
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549 if (!kgdboc_earlycon_late_enable) {
0550 pr_info("No suitable earlycon yet, will try later\n");
0551 if (opt)
0552 strscpy(kgdboc_earlycon_param, opt,
0553 sizeof(kgdboc_earlycon_param));
0554 kgdboc_earlycon_late_enable = true;
0555 } else {
0556 pr_info("Couldn't find kgdb earlycon\n");
0557 }
0558 goto unlock;
0559 }
0560
0561 kgdboc_earlycon_io_ops.cons = con;
0562 pr_info("Going to register kgdb with earlycon '%s'\n", con->name);
0563 if (kgdb_register_io_module(&kgdboc_earlycon_io_ops) != 0) {
0564 kgdboc_earlycon_io_ops.cons = NULL;
0565 pr_info("Failed to register kgdb with earlycon\n");
0566 } else {
0567
0568 earlycon_orig_exit = con->exit;
0569 con->exit = kgdboc_earlycon_deferred_exit;
0570 }
0571
0572 unlock:
0573 console_unlock();
0574
0575
0576 return 0;
0577 }
0578
0579 early_param("kgdboc_earlycon", kgdboc_earlycon_init);
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589 static int __init kgdboc_earlycon_late_init(void)
0590 {
0591 if (kgdboc_earlycon_late_enable)
0592 kgdboc_earlycon_init(kgdboc_earlycon_param);
0593 return 0;
0594 }
0595 console_initcall(kgdboc_earlycon_late_init);
0596
0597 #endif
0598
0599 module_init(init_kgdboc);
0600 module_exit(exit_kgdboc);
0601 module_param_call(kgdboc, param_set_kgdboc_var, param_get_string, &kps, 0644);
0602 MODULE_PARM_DESC(kgdboc, "<serial_device>[,baud]");
0603 MODULE_DESCRIPTION("KGDB Console TTY Driver");
0604 MODULE_LICENSE("GPL");