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
587587 arch_kgdb_ops.disable_hw_break(regs);
588588
589589 acquirelock:
590+ rcu_read_lock();
590591 /*
591592 * Interrupts will be restored by the 'trap return' code, except when
592593 * single stepping.
@@ -646,6 +647,7 @@ return_normal: · 53 unmodified lines
646647 atomic_dec(&slaves_in_kgdb);
647648 dbg_touch_watchdogs();
648649 local_irq_restore(flags);
650+ rcu_read_unlock();
649651 return 0;
650652 }
651653 cpu_relax();
@@ -664,6 +666,7 @@ return_normal: · 12 unmodified lines
664666 raw_spin_unlock(&dbg_master_lock);
665667 dbg_touch_watchdogs();
666668 local_irq_restore(flags);
669+ rcu_read_unlock();
667670
668671 goto acquirelock;
669672 }
@@ -787,6 +790,7 @@ kgdb_restore: · 117 unmodified lines
787790 raw_spin_unlock(&dbg_master_lock);
788791 dbg_touch_watchdogs();
789792 local_irq_restore(flags);
793+ rcu_read_unlock();
790794
791795 return kgdb_info[cpu].ret_state;
792796 }
kernel/debug/kdb/kdb_io.c+43−29
@@ -542,6 +542,44 @@ static int kdb_search_string(char *searched, char *searchfor) · 541 unmodified lines
542542 return 0;
543543 }
544544
545+static 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+
545583 int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap)
546584 {
547585 int diag;
@@ -553,7 +591,6 @@ int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap) · 5 unmodified lines
553591 int this_cpu, old_cpu;
554592 char *cp, *cp2, *cphold = NULL, replaced_byte = ' ';
555593 char *moreprompt = "more> ";
556− struct console *c;
557594 unsigned long uninitialized_var(flags);
558595
559596 /* Serialize kdb_printf if multiple cpus try to write at once.
@@ -687,22 +724,11 @@ kdb_printit: · 127 unmodified lines
687724 */
688725 retlen = strlen(kdb_buffer);
689726 cp = (char *) printk_skip_headers(kdb_buffer);
690− if (!dbg_kdb_mode && kgdb_connected) {
727+ if (!dbg_kdb_mode && kgdb_connected)
691728 gdbstub_msg_write(cp, retlen - (cp - kdb_buffer));
692− } else {
693− if (dbg_io_ops && !dbg_io_ops->is_console) {
694− len = retlen - (cp - kdb_buffer);
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− }
729+ else
730+ kdb_msg_write(cp, retlen - (cp - kdb_buffer));
731+
706732 if (logging) {
707733 saved_loglevel = console_loglevel;
708734 console_loglevel = CONSOLE_LOGLEVEL_SILENT;
@@ -751,19 +777,7 @@ kdb_printit: · 42 unmodified lines
751777 moreprompt = "more> ";
752778
753779 kdb_input_flush();
754−
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− }
780+ kdb_msg_write(moreprompt, strlen(moreprompt));
767781
768782 if (logging)
769783 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