aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/debug/debug_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/debug/debug_core.c')
-rw-r--r--kernel/debug/debug_core.c153
1 files changed, 72 insertions, 81 deletions
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index de407c78178d..cefd4a11f6d9 100644
--- a/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -47,6 +47,7 @@
47#include <linux/pid.h> 47#include <linux/pid.h>
48#include <linux/smp.h> 48#include <linux/smp.h>
49#include <linux/mm.h> 49#include <linux/mm.h>
50#include <linux/rcupdate.h>
50 51
51#include <asm/cacheflush.h> 52#include <asm/cacheflush.h>
52#include <asm/byteorder.h> 53#include <asm/byteorder.h>
@@ -109,13 +110,15 @@ static struct kgdb_bkpt kgdb_break[KGDB_MAX_BREAKPOINTS] = {
109 */ 110 */
110atomic_t kgdb_active = ATOMIC_INIT(-1); 111atomic_t kgdb_active = ATOMIC_INIT(-1);
111EXPORT_SYMBOL_GPL(kgdb_active); 112EXPORT_SYMBOL_GPL(kgdb_active);
113static DEFINE_RAW_SPINLOCK(dbg_master_lock);
114static DEFINE_RAW_SPINLOCK(dbg_slave_lock);
112 115
113/* 116/*
114 * We use NR_CPUs not PERCPU, in case kgdb is used to debug early 117 * We use NR_CPUs not PERCPU, in case kgdb is used to debug early
115 * bootup code (which might not have percpu set up yet): 118 * bootup code (which might not have percpu set up yet):
116 */ 119 */
117static atomic_t passive_cpu_wait[NR_CPUS]; 120static atomic_t masters_in_kgdb;
118static atomic_t cpu_in_kgdb[NR_CPUS]; 121static atomic_t slaves_in_kgdb;
119static atomic_t kgdb_break_tasklet_var; 122static atomic_t kgdb_break_tasklet_var;
120atomic_t kgdb_setting_breakpoint; 123atomic_t kgdb_setting_breakpoint;
121 124
@@ -206,18 +209,6 @@ int __weak kgdb_skipexception(int exception, struct pt_regs *regs)
206 return 0; 209 return 0;
207} 210}
208 211
209/**
210 * kgdb_disable_hw_debug - Disable hardware debugging while we in kgdb.
211 * @regs: Current &struct pt_regs.
212 *
213 * This function will be called if the particular architecture must
214 * disable hardware debugging while it is processing gdb packets or
215 * handling exception.
216 */
217void __weak kgdb_disable_hw_debug(struct pt_regs *regs)
218{
219}
220
221/* 212/*
222 * Some architectures need cache flushes when we set/clear a 213 * Some architectures need cache flushes when we set/clear a
223 * breakpoint: 214 * breakpoint:
@@ -457,26 +448,34 @@ static int kgdb_reenter_check(struct kgdb_state *ks)
457 return 1; 448 return 1;
458} 449}
459 450
460static void dbg_cpu_switch(int cpu, int next_cpu) 451static void dbg_touch_watchdogs(void)
461{ 452{
462 /* Mark the cpu we are switching away from as a slave when it 453 touch_softlockup_watchdog_sync();
463 * holds the kgdb_active token. This must be done so that the 454 clocksource_touch_watchdog();
464 * that all the cpus wait in for the debug core will not enter 455 rcu_cpu_stall_reset();
465 * again as the master. */
466 if (cpu == atomic_read(&kgdb_active)) {
467 kgdb_info[cpu].exception_state |= DCPU_IS_SLAVE;
468 kgdb_info[cpu].exception_state &= ~DCPU_WANT_MASTER;
469 }
470 kgdb_info[next_cpu].exception_state |= DCPU_NEXT_MASTER;
471} 456}
472 457
473static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs) 458static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs,
459 int exception_state)
474{ 460{
475 unsigned long flags; 461 unsigned long flags;
476 int sstep_tries = 100; 462 int sstep_tries = 100;
477 int error; 463 int error;
478 int i, cpu; 464 int cpu;
479 int trace_on = 0; 465 int trace_on = 0;
466 int online_cpus = num_online_cpus();
467
468 kgdb_info[ks->cpu].enter_kgdb++;
469 kgdb_info[ks->cpu].exception_state |= exception_state;
470
471 if (exception_state == DCPU_WANT_MASTER)
472 atomic_inc(&masters_in_kgdb);
473 else
474 atomic_inc(&slaves_in_kgdb);
475
476 if (arch_kgdb_ops.disable_hw_break)
477 arch_kgdb_ops.disable_hw_break(regs);
478
480acquirelock: 479acquirelock:
481 /* 480 /*
482 * Interrupts will be restored by the 'trap return' code, except when 481 * Interrupts will be restored by the 'trap return' code, except when
@@ -489,14 +488,15 @@ acquirelock:
489 kgdb_info[cpu].task = current; 488 kgdb_info[cpu].task = current;
490 kgdb_info[cpu].ret_state = 0; 489 kgdb_info[cpu].ret_state = 0;
491 kgdb_info[cpu].irq_depth = hardirq_count() >> HARDIRQ_SHIFT; 490 kgdb_info[cpu].irq_depth = hardirq_count() >> HARDIRQ_SHIFT;
492 /*
493 * Make sure the above info reaches the primary CPU before
494 * our cpu_in_kgdb[] flag setting does:
495 */
496 atomic_inc(&cpu_in_kgdb[cpu]);
497 491
498 if (exception_level == 1) 492 /* Make sure the above info reaches the primary CPU */
493 smp_mb();
494
495 if (exception_level == 1) {
496 if (raw_spin_trylock(&dbg_master_lock))
497 atomic_xchg(&kgdb_active, cpu);
499 goto cpu_master_loop; 498 goto cpu_master_loop;
499 }
500 500
501 /* 501 /*
502 * CPU will loop if it is a slave or request to become a kgdb 502 * CPU will loop if it is a slave or request to become a kgdb
@@ -508,10 +508,12 @@ cpu_loop:
508 kgdb_info[cpu].exception_state &= ~DCPU_NEXT_MASTER; 508 kgdb_info[cpu].exception_state &= ~DCPU_NEXT_MASTER;
509 goto cpu_master_loop; 509 goto cpu_master_loop;
510 } else if (kgdb_info[cpu].exception_state & DCPU_WANT_MASTER) { 510 } else if (kgdb_info[cpu].exception_state & DCPU_WANT_MASTER) {
511 if (atomic_cmpxchg(&kgdb_active, -1, cpu) == cpu) 511 if (raw_spin_trylock(&dbg_master_lock)) {
512 atomic_xchg(&kgdb_active, cpu);
512 break; 513 break;
514 }
513 } else if (kgdb_info[cpu].exception_state & DCPU_IS_SLAVE) { 515 } else if (kgdb_info[cpu].exception_state & DCPU_IS_SLAVE) {
514 if (!atomic_read(&passive_cpu_wait[cpu])) 516 if (!raw_spin_is_locked(&dbg_slave_lock))
515 goto return_normal; 517 goto return_normal;
516 } else { 518 } else {
517return_normal: 519return_normal:
@@ -522,9 +524,12 @@ return_normal:
522 arch_kgdb_ops.correct_hw_break(); 524 arch_kgdb_ops.correct_hw_break();
523 if (trace_on) 525 if (trace_on)
524 tracing_on(); 526 tracing_on();
525 atomic_dec(&cpu_in_kgdb[cpu]); 527 kgdb_info[cpu].exception_state &=
526 touch_softlockup_watchdog_sync(); 528 ~(DCPU_WANT_MASTER | DCPU_IS_SLAVE);
527 clocksource_touch_watchdog(); 529 kgdb_info[cpu].enter_kgdb--;
530 smp_mb__before_atomic_dec();
531 atomic_dec(&slaves_in_kgdb);
532 dbg_touch_watchdogs();
528 local_irq_restore(flags); 533 local_irq_restore(flags);
529 return 0; 534 return 0;
530 } 535 }
@@ -541,8 +546,8 @@ return_normal:
541 (kgdb_info[cpu].task && 546 (kgdb_info[cpu].task &&
542 kgdb_info[cpu].task->pid != kgdb_sstep_pid) && --sstep_tries) { 547 kgdb_info[cpu].task->pid != kgdb_sstep_pid) && --sstep_tries) {
543 atomic_set(&kgdb_active, -1); 548 atomic_set(&kgdb_active, -1);
544 touch_softlockup_watchdog_sync(); 549 raw_spin_unlock(&dbg_master_lock);
545 clocksource_touch_watchdog(); 550 dbg_touch_watchdogs();
546 local_irq_restore(flags); 551 local_irq_restore(flags);
547 552
548 goto acquirelock; 553 goto acquirelock;
@@ -563,16 +568,12 @@ return_normal:
563 if (dbg_io_ops->pre_exception) 568 if (dbg_io_ops->pre_exception)
564 dbg_io_ops->pre_exception(); 569 dbg_io_ops->pre_exception();
565 570
566 kgdb_disable_hw_debug(ks->linux_regs);
567
568 /* 571 /*
569 * Get the passive CPU lock which will hold all the non-primary 572 * Get the passive CPU lock which will hold all the non-primary
570 * CPU in a spin state while the debugger is active 573 * CPU in a spin state while the debugger is active
571 */ 574 */
572 if (!kgdb_single_step) { 575 if (!kgdb_single_step)
573 for (i = 0; i < NR_CPUS; i++) 576 raw_spin_lock(&dbg_slave_lock);
574 atomic_inc(&passive_cpu_wait[i]);
575 }
576 577
577#ifdef CONFIG_SMP 578#ifdef CONFIG_SMP
578 /* Signal the other CPUs to enter kgdb_wait() */ 579 /* Signal the other CPUs to enter kgdb_wait() */
@@ -583,10 +584,9 @@ return_normal:
583 /* 584 /*
584 * Wait for the other CPUs to be notified and be waiting for us: 585 * Wait for the other CPUs to be notified and be waiting for us:
585 */ 586 */
586 for_each_online_cpu(i) { 587 while (kgdb_do_roundup && (atomic_read(&masters_in_kgdb) +
587 while (kgdb_do_roundup && !atomic_read(&cpu_in_kgdb[i])) 588 atomic_read(&slaves_in_kgdb)) != online_cpus)
588 cpu_relax(); 589 cpu_relax();
589 }
590 590
591 /* 591 /*
592 * At this point the primary processor is completely 592 * At this point the primary processor is completely
@@ -615,7 +615,8 @@ cpu_master_loop:
615 if (error == DBG_PASS_EVENT) { 615 if (error == DBG_PASS_EVENT) {
616 dbg_kdb_mode = !dbg_kdb_mode; 616 dbg_kdb_mode = !dbg_kdb_mode;
617 } else if (error == DBG_SWITCH_CPU_EVENT) { 617 } else if (error == DBG_SWITCH_CPU_EVENT) {
618 dbg_cpu_switch(cpu, dbg_switch_cpu); 618 kgdb_info[dbg_switch_cpu].exception_state |=
619 DCPU_NEXT_MASTER;
619 goto cpu_loop; 620 goto cpu_loop;
620 } else { 621 } else {
621 kgdb_info[cpu].ret_state = error; 622 kgdb_info[cpu].ret_state = error;
@@ -627,24 +628,11 @@ cpu_master_loop:
627 if (dbg_io_ops->post_exception) 628 if (dbg_io_ops->post_exception)
628 dbg_io_ops->post_exception(); 629 dbg_io_ops->post_exception();
629 630
630 atomic_dec(&cpu_in_kgdb[ks->cpu]);
631
632 if (!kgdb_single_step) { 631 if (!kgdb_single_step) {
633 for (i = NR_CPUS-1; i >= 0; i--) 632 raw_spin_unlock(&dbg_slave_lock);
634 atomic_dec(&passive_cpu_wait[i]); 633 /* Wait till all the CPUs have quit from the debugger. */
635 /* 634 while (kgdb_do_roundup && atomic_read(&slaves_in_kgdb))
636 * Wait till all the CPUs have quit from the debugger, 635 cpu_relax();
637 * but allow a CPU that hit an exception and is
638 * waiting to become the master to remain in the debug
639 * core.
640 */
641 for_each_online_cpu(i) {
642 while (kgdb_do_roundup &&
643 atomic_read(&cpu_in_kgdb[i]) &&
644 !(kgdb_info[i].exception_state &
645 DCPU_WANT_MASTER))
646 cpu_relax();
647 }
648 } 636 }
649 637
650kgdb_restore: 638kgdb_restore:
@@ -655,12 +643,20 @@ kgdb_restore:
655 else 643 else
656 kgdb_sstep_pid = 0; 644 kgdb_sstep_pid = 0;
657 } 645 }
646 if (arch_kgdb_ops.correct_hw_break)
647 arch_kgdb_ops.correct_hw_break();
658 if (trace_on) 648 if (trace_on)
659 tracing_on(); 649 tracing_on();
650
651 kgdb_info[cpu].exception_state &=
652 ~(DCPU_WANT_MASTER | DCPU_IS_SLAVE);
653 kgdb_info[cpu].enter_kgdb--;
654 smp_mb__before_atomic_dec();
655 atomic_dec(&masters_in_kgdb);
660 /* Free kgdb_active */ 656 /* Free kgdb_active */
661 atomic_set(&kgdb_active, -1); 657 atomic_set(&kgdb_active, -1);
662 touch_softlockup_watchdog_sync(); 658 raw_spin_unlock(&dbg_master_lock);
663 clocksource_touch_watchdog(); 659 dbg_touch_watchdogs();
664 local_irq_restore(flags); 660 local_irq_restore(flags);
665 661
666 return kgdb_info[cpu].ret_state; 662 return kgdb_info[cpu].ret_state;
@@ -678,7 +674,6 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs)
678{ 674{
679 struct kgdb_state kgdb_var; 675 struct kgdb_state kgdb_var;
680 struct kgdb_state *ks = &kgdb_var; 676 struct kgdb_state *ks = &kgdb_var;
681 int ret;
682 677
683 ks->cpu = raw_smp_processor_id(); 678 ks->cpu = raw_smp_processor_id();
684 ks->ex_vector = evector; 679 ks->ex_vector = evector;
@@ -689,11 +684,10 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs)
689 684
690 if (kgdb_reenter_check(ks)) 685 if (kgdb_reenter_check(ks))
691 return 0; /* Ouch, double exception ! */ 686 return 0; /* Ouch, double exception ! */
692 kgdb_info[ks->cpu].exception_state |= DCPU_WANT_MASTER; 687 if (kgdb_info[ks->cpu].enter_kgdb != 0)
693 ret = kgdb_cpu_enter(ks, regs); 688 return 0;
694 kgdb_info[ks->cpu].exception_state &= ~(DCPU_WANT_MASTER | 689
695 DCPU_IS_SLAVE); 690 return kgdb_cpu_enter(ks, regs, DCPU_WANT_MASTER);
696 return ret;
697} 691}
698 692
699int kgdb_nmicallback(int cpu, void *regs) 693int kgdb_nmicallback(int cpu, void *regs)
@@ -706,12 +700,9 @@ int kgdb_nmicallback(int cpu, void *regs)
706 ks->cpu = cpu; 700 ks->cpu = cpu;
707 ks->linux_regs = regs; 701 ks->linux_regs = regs;
708 702
709 if (!atomic_read(&cpu_in_kgdb[cpu]) && 703 if (kgdb_info[ks->cpu].enter_kgdb == 0 &&
710 atomic_read(&kgdb_active) != -1 && 704 raw_spin_is_locked(&dbg_master_lock)) {
711 atomic_read(&kgdb_active) != cpu) { 705 kgdb_cpu_enter(ks, regs, DCPU_IS_SLAVE);
712 kgdb_info[cpu].exception_state |= DCPU_IS_SLAVE;
713 kgdb_cpu_enter(ks, regs);
714 kgdb_info[cpu].exception_state &= ~DCPU_IS_SLAVE;
715 return 0; 706 return 0;
716 } 707 }
717#endif 708#endif