History

Merge tag 'kgdb-5.8-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/danielt/linux

Pull kgdb fixes from Daniel Thompson: "The main change here is a fix for a number of unsafe interactions between kdb and the console system. The fixes are specific to kdb (pure kgdb debugging does not use the console system at all). On systems with an NMI then kdb, if it is enabled, must get messages to the user despite potentially running from some "difficult" calling contexts. These fixes avoid using the console system where we have been provided an alternative (safer) way to interact with the user and, if using the console system in unavoidable, use oops_in_progress for deadlock avoidance. These fixes also ensure kdb honours the console enable flag. Also included is a fix that wraps kgdb trap handling in an RCU read lock to avoids triggering diagnostic warnings. This is a wide lock scope but this is OK because kgdb is a stop-the-world debugger. When we stop the world we put all the CPUs into holding pens and this inhibits RCU update anyway" * tag 'kgdb-5.8-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/danielt/linux: kgdb: Avoid suspicious RCU usage warning kdb: Switch to use safer dbg_io_ops over console APIs kdb: Make kdb_printf() console handling more robust kdb: Check status of console prior to invoking handlers kdb: Re-factor kdb_printf() message write code

Linus Torvalds committed 6 years ago

Commit 6116dea2 parents 21d2f68 440ab9e6 files · +68 −50Browse files

Unified · Split

6 files
  1. drivers/tty/serial/kgdb_nmi.c +1 −1
  2. drivers/tty/serial/kgdboc.c +16 −16
  3. drivers/usb/early/ehci-dbgp.c +2 −1
  4. include/linux/kgdb.h +2 −3
  5. kernel/debug/debug_core.c +4 −0
  6. kernel/debug/kdb/kdb_io.c +43 −29
drivers/tty/serial/kgdb_nmi.c+1−1
@@ -50,7 +50,7 @@ static int kgdb_nmi_console_setup(struct console *co, char *options) · 49 unmodified lines
50 * I/O utilities that messages sent to the console will automatically50 * I/O utilities that messages sent to the console will automatically
51 * be displayed on the dbg_io.51 * be displayed on the dbg_io.
52 */52 */
53 dbg_io_ops->is_console = true;53 dbg_io_ops->cons = co;
54 54
55 return 0;55 return 0;
56}56}
drivers/tty/serial/kgdboc.c+16−16
@@ -45,7 +45,6 @@ static struct platform_device *kgdboc_pdev; · 44 unmodified lines
45 45
46#if IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE)46#if IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE)
47static struct kgdb_io kgdboc_earlycon_io_ops;47static struct kgdb_io kgdboc_earlycon_io_ops;
48static struct console *earlycon;
49static int (*earlycon_orig_exit)(struct console *con);48static int (*earlycon_orig_exit)(struct console *con);
50#endif /* IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE) */49#endif /* IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE) */
51 50
@@ -145,7 +144,7 @@ static void kgdboc_unregister_kbd(void) · 93 unmodified lines
145#if IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE)144#if IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE)
146static void cleanup_earlycon(void)145static void cleanup_earlycon(void)
147{146{
148 if (earlycon)147 if (kgdboc_earlycon_io_ops.cons)
149 kgdb_unregister_io_module(&kgdboc_earlycon_io_ops);148 kgdb_unregister_io_module(&kgdboc_earlycon_io_ops);
150}149}
151#else /* !IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE) */150#else /* !IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE) */
@@ -178,7 +177,7 @@ static int configure_kgdboc(void) · 26 unmodified lines
178 goto noconfig;177 goto noconfig;
179 }178 }
180 179
181 kgdboc_io_ops.is_console = 0;180 kgdboc_io_ops.cons = NULL;
182 kgdb_tty_driver = NULL;181 kgdb_tty_driver = NULL;
183 182
184 kgdboc_use_kms = 0;183 kgdboc_use_kms = 0;
@@ -198,7 +197,7 @@ static int configure_kgdboc(void) · 13 unmodified lines
198 int idx;197 int idx;
199 if (cons->device && cons->device(cons, &idx) == p &&198 if (cons->device && cons->device(cons, &idx) == p &&
200 idx == tty_line) {199 idx == tty_line) {
201 kgdboc_io_ops.is_console = 1;200 kgdboc_io_ops.cons = cons;
202 break;201 break;
203 }202 }
204 }203 }
@@ -433,7 +432,8 @@ static int kgdboc_earlycon_get_char(void) · 228 unmodified lines
433{432{
434 char c;433 char c;
435 434
436 if (!earlycon->read(earlycon, &c, 1))435 if (!kgdboc_earlycon_io_ops.cons->read(kgdboc_earlycon_io_ops.cons,
436 &c, 1))
437 return NO_POLL_CHAR;437 return NO_POLL_CHAR;
438 438
439 return c;439 return c;
@@ -441,7 +441,8 @@ static int kgdboc_earlycon_get_char(void) · 1 unmodified line
441 441
442static void kgdboc_earlycon_put_char(u8 chr)442static void kgdboc_earlycon_put_char(u8 chr)
443{443{
444 earlycon->write(earlycon, &chr, 1);444 kgdboc_earlycon_io_ops.cons->write(kgdboc_earlycon_io_ops.cons, &chr,
445 1);
445}446}
446 447
447static void kgdboc_earlycon_pre_exp_handler(void)448static void kgdboc_earlycon_pre_exp_handler(void)
@@ -461,7 +462,7 @@ static void kgdboc_earlycon_pre_exp_handler(void) · 13 unmodified lines
461 * boot if we detect this case.462 * boot if we detect this case.
462 */463 */
463 for_each_console(con)464 for_each_console(con)
464 if (con == earlycon)465 if (con == kgdboc_earlycon_io_ops.cons)
465 return;466 return;
466 467
467 already_warned = true;468 already_warned = true;
@@ -484,25 +485,25 @@ static int kgdboc_earlycon_deferred_exit(struct console *con) · 16 unmodified lines
484 485
485static void kgdboc_earlycon_deinit(void)486static void kgdboc_earlycon_deinit(void)
486{487{
487 if (!earlycon)488 if (!kgdboc_earlycon_io_ops.cons)
488 return;489 return;
489 490
490 if (earlycon->exit == kgdboc_earlycon_deferred_exit)491 if (kgdboc_earlycon_io_ops.cons->exit == kgdboc_earlycon_deferred_exit)
491 /*492 /*
492 * kgdboc_earlycon is exiting but original boot console exit493 * kgdboc_earlycon is exiting but original boot console exit
493 * was never called (AKA kgdboc_earlycon_deferred_exit()494 * was never called (AKA kgdboc_earlycon_deferred_exit()
494 * didn't ever run). Undo our trap.495 * didn't ever run). Undo our trap.
495 */496 */
496 earlycon->exit = earlycon_orig_exit;497 kgdboc_earlycon_io_ops.cons->exit = earlycon_orig_exit;
497 else if (earlycon->exit)498 else if (kgdboc_earlycon_io_ops.cons->exit)
498 /*499 /*
499 * We skipped calling the exit() routine so we could try to500 * We skipped calling the exit() routine so we could try to
500 * keep using the boot console even after it went away. We're501 * keep using the boot console even after it went away. We're
501 * finally done so call the function now.502 * finally done so call the function now.
502 */503 */
503 earlycon->exit(earlycon);504 kgdboc_earlycon_io_ops.cons->exit(kgdboc_earlycon_io_ops.cons);
504 505
505 earlycon = NULL;506 kgdboc_earlycon_io_ops.cons = NULL;
506}507}
507 508
508static struct kgdb_io kgdboc_earlycon_io_ops = {509static struct kgdb_io kgdboc_earlycon_io_ops = {
@@ -511,7 +512,6 @@ static struct kgdb_io kgdboc_earlycon_io_ops = { · 2 unmodified lines
511 .write_char = kgdboc_earlycon_put_char,512 .write_char = kgdboc_earlycon_put_char,
512 .pre_exception = kgdboc_earlycon_pre_exp_handler,513 .pre_exception = kgdboc_earlycon_pre_exp_handler,
513 .deinit = kgdboc_earlycon_deinit,514 .deinit = kgdboc_earlycon_deinit,
514 .is_console = true,
515};515};
516 516
517#define MAX_CONSOLE_NAME_LEN (sizeof((struct console *) 0)->name)517#define MAX_CONSOLE_NAME_LEN (sizeof((struct console *) 0)->name)
@@ -557,10 +557,10 @@ static int __init kgdboc_earlycon_init(char *opt) · 39 unmodified lines
557 goto unlock;557 goto unlock;
558 }558 }
559 559
560 earlycon = con;560 kgdboc_earlycon_io_ops.cons = con;
561 pr_info("Going to register kgdb with earlycon '%s'\n", con->name);561 pr_info("Going to register kgdb with earlycon '%s'\n", con->name);
562 if (kgdb_register_io_module(&kgdboc_earlycon_io_ops) != 0) {562 if (kgdb_register_io_module(&kgdboc_earlycon_io_ops) != 0) {
563 earlycon = NULL;563 kgdboc_earlycon_io_ops.cons = NULL;
564 pr_info("Failed to register kgdb with earlycon\n");564 pr_info("Failed to register kgdb with earlycon\n");
565 } else {565 } else {
566 /* Trap exit so we can keep earlycon longer if needed. */566 /* Trap exit so we can keep earlycon longer if needed. */
drivers/usb/early/ehci-dbgp.c+2−1
@@ -1058,7 +1058,8 @@ static int __init kgdbdbgp_parse_config(char *str) · 1057 unmodified lines
1058 kgdbdbgp_wait_time = simple_strtoul(ptr, &ptr, 10);1058 kgdbdbgp_wait_time = simple_strtoul(ptr, &ptr, 10);
1059 }1059 }
1060 kgdb_register_io_module(&kgdbdbgp_io_ops);1060 kgdb_register_io_module(&kgdbdbgp_io_ops);
1061 kgdbdbgp_io_ops.is_console = early_dbgp_console.index != -1;1061 if (early_dbgp_console.index != -1)
1062 kgdbdbgp_io_ops.cons = &early_dbgp_console;
1062 1063
1063 return 0;1064 return 0;
1064}1065}
include/linux/kgdb.h+2−3
@@ -276,8 +276,7 @@ struct kgdb_arch { · 275 unmodified lines
276 * the I/O driver.276 * the I/O driver.
277 * @post_exception: Pointer to a function that will do any cleanup work277 * @post_exception: Pointer to a function that will do any cleanup work
278 * for the I/O driver.278 * for the I/O driver.
279 * @is_console: 1 if the end device is a console 0 if the I/O device is279 * @cons: valid if the I/O device is a console; else NULL.
280 * not a console
281 */280 */
282struct kgdb_io {281struct kgdb_io {
283 const char *name;282 const char *name;
@@ -288,7 +287,7 @@ struct kgdb_io { · 4 unmodified lines
288 void (*deinit) (void);287 void (*deinit) (void);
289 void (*pre_exception) (void);288 void (*pre_exception) (void);
290 void (*post_exception) (void);289 void (*post_exception) (void);
291 int is_console;290 struct console *cons;
292};291};
293 292
294extern const struct kgdb_arch arch_kgdb_ops;293extern const struct kgdb_arch arch_kgdb_ops;
kernel/debug/debug_core.c+4−0
@@ -587,6 +587,7 @@ static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs, · 586 unmodified lines
587 arch_kgdb_ops.disable_hw_break(regs);587 arch_kgdb_ops.disable_hw_break(regs);
588 588
589acquirelock:589acquirelock:
590 rcu_read_lock();
590 /*591 /*
591 * Interrupts will be restored by the 'trap return' code, except when592 * Interrupts will be restored by the 'trap return' code, except when
592 * single stepping.593 * single stepping.
@@ -646,6 +647,7 @@ return_normal: · 53 unmodified lines
646 atomic_dec(&slaves_in_kgdb);647 atomic_dec(&slaves_in_kgdb);
647 dbg_touch_watchdogs();648 dbg_touch_watchdogs();
648 local_irq_restore(flags);649 local_irq_restore(flags);
650 rcu_read_unlock();
649 return 0;651 return 0;
650 }652 }
651 cpu_relax();653 cpu_relax();
@@ -664,6 +666,7 @@ return_normal: · 12 unmodified lines
664 raw_spin_unlock(&dbg_master_lock);666 raw_spin_unlock(&dbg_master_lock);
665 dbg_touch_watchdogs();667 dbg_touch_watchdogs();
666 local_irq_restore(flags);668 local_irq_restore(flags);
669 rcu_read_unlock();
667 670
668 goto acquirelock;671 goto acquirelock;
669 }672 }
@@ -787,6 +790,7 @@ kgdb_restore: · 117 unmodified lines
787 raw_spin_unlock(&dbg_master_lock);790 raw_spin_unlock(&dbg_master_lock);
788 dbg_touch_watchdogs();791 dbg_touch_watchdogs();
789 local_irq_restore(flags);792 local_irq_restore(flags);
793 rcu_read_unlock();
790 794
791 return kgdb_info[cpu].ret_state;795 return kgdb_info[cpu].ret_state;
792}796}
kernel/debug/kdb/kdb_io.c+43−29
@@ -542,6 +542,44 @@ static int kdb_search_string(char *searched, char *searchfor) · 541 unmodified lines
542 return 0;542 return 0;
543}543}
544 544
545static void kdb_msg_write(const char *msg, int msg_len)
546{
547 struct console *c;
548
549 if (msg_len == 0)
550 return;
551
552 if (dbg_io_ops) {
553 const char *cp = msg;
554 int len = msg_len;
555
556 while (len--) {
557 dbg_io_ops->write_char(*cp);
558 cp++;
559 }
560 }
561
562 for_each_console(c) {
563 if (!(c->flags & CON_ENABLED))
564 continue;
565 if (c == dbg_io_ops->cons)
566 continue;
567 /*
568 * Set oops_in_progress to encourage the console drivers to
569 * disregard their internal spin locks: in the current calling
570 * context the risk of deadlock is a bigger problem than risks
571 * due to re-entering the console driver. We operate directly on
572 * oops_in_progress rather than using bust_spinlocks() because
573 * the calls bust_spinlocks() makes on exit are not appropriate
574 * for this calling context.
575 */
576 ++oops_in_progress;
577 c->write(c, msg, msg_len);
578 --oops_in_progress;
579 touch_nmi_watchdog();
580 }
581}
582
545int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap)583int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap)
546{584{
547 int diag;585 int diag;
@@ -553,7 +591,6 @@ int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap) · 5 unmodified lines
553 int this_cpu, old_cpu;591 int this_cpu, old_cpu;
554 char *cp, *cp2, *cphold = NULL, replaced_byte = ' ';592 char *cp, *cp2, *cphold = NULL, replaced_byte = ' ';
555 char *moreprompt = "more> ";593 char *moreprompt = "more> ";
556 struct console *c;
557 unsigned long uninitialized_var(flags);594 unsigned long uninitialized_var(flags);
558 595
559 /* Serialize kdb_printf if multiple cpus try to write at once.596 /* Serialize kdb_printf if multiple cpus try to write at once.
@@ -687,22 +724,11 @@ kdb_printit: · 127 unmodified lines
687 */724 */
688 retlen = strlen(kdb_buffer);725 retlen = strlen(kdb_buffer);
689 cp = (char *) printk_skip_headers(kdb_buffer);726 cp = (char *) printk_skip_headers(kdb_buffer);
690 if (!dbg_kdb_mode && kgdb_connected) {727 if (!dbg_kdb_mode && kgdb_connected)
691 gdbstub_msg_write(cp, retlen - (cp - kdb_buffer));728 gdbstub_msg_write(cp, retlen - (cp - kdb_buffer));
692 } else {729 else
693 if (dbg_io_ops && !dbg_io_ops->is_console) {730 kdb_msg_write(cp, retlen - (cp - kdb_buffer));
694 len = retlen - (cp - kdb_buffer);731
695 cp2 = cp;
696 while (len--) {
697 dbg_io_ops->write_char(*cp2);
698 cp2++;
699 }
700 }
701 for_each_console(c) {
702 c->write(c, cp, retlen - (cp - kdb_buffer));
703 touch_nmi_watchdog();
704 }
705 }
706 if (logging) {732 if (logging) {
707 saved_loglevel = console_loglevel;733 saved_loglevel = console_loglevel;
708 console_loglevel = CONSOLE_LOGLEVEL_SILENT;734 console_loglevel = CONSOLE_LOGLEVEL_SILENT;
@@ -751,19 +777,7 @@ kdb_printit: · 42 unmodified lines
751 moreprompt = "more> ";777 moreprompt = "more> ";
752 778
753 kdb_input_flush();779 kdb_input_flush();
754 780 kdb_msg_write(moreprompt, strlen(moreprompt));
755 if (dbg_io_ops && !dbg_io_ops->is_console) {
756 len = strlen(moreprompt);
757 cp = moreprompt;
758 while (len--) {
759 dbg_io_ops->write_char(*cp);
760 cp++;
761 }
762 }
763 for_each_console(c) {
764 c->write(c, moreprompt, strlen(moreprompt));
765 touch_nmi_watchdog();
766 }
767 781
768 if (logging)782 if (logging)
769 printk("%s", moreprompt);783 printk("%s", moreprompt);