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

Showing the changes to kernel (2 of 6 files). Show all

Unified · Split

2 files
  1. kernel/debug/debug_core.c +4 −0
  2. kernel/debug/kdb/kdb_io.c +43 −29
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);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t