diff options
Diffstat (limited to 'kernel/kgdb.c')
-rw-r--r-- | kernel/kgdb.c | 67 |
1 files changed, 47 insertions, 20 deletions
diff --git a/kernel/kgdb.c b/kernel/kgdb.c index 9147a3190c9d..761fdd2b3034 100644 --- a/kernel/kgdb.c +++ b/kernel/kgdb.c | |||
@@ -129,6 +129,7 @@ struct task_struct *kgdb_usethread; | |||
129 | struct task_struct *kgdb_contthread; | 129 | struct task_struct *kgdb_contthread; |
130 | 130 | ||
131 | int kgdb_single_step; | 131 | int kgdb_single_step; |
132 | pid_t kgdb_sstep_pid; | ||
132 | 133 | ||
133 | /* Our I/O buffers. */ | 134 | /* Our I/O buffers. */ |
134 | static char remcom_in_buffer[BUFMAX]; | 135 | static char remcom_in_buffer[BUFMAX]; |
@@ -541,12 +542,17 @@ static struct task_struct *getthread(struct pt_regs *regs, int tid) | |||
541 | */ | 542 | */ |
542 | if (tid == 0 || tid == -1) | 543 | if (tid == 0 || tid == -1) |
543 | tid = -atomic_read(&kgdb_active) - 2; | 544 | tid = -atomic_read(&kgdb_active) - 2; |
544 | if (tid < 0) { | 545 | if (tid < -1 && tid > -NR_CPUS - 2) { |
545 | if (kgdb_info[-tid - 2].task) | 546 | if (kgdb_info[-tid - 2].task) |
546 | return kgdb_info[-tid - 2].task; | 547 | return kgdb_info[-tid - 2].task; |
547 | else | 548 | else |
548 | return idle_task(-tid - 2); | 549 | return idle_task(-tid - 2); |
549 | } | 550 | } |
551 | if (tid <= 0) { | ||
552 | printk(KERN_ERR "KGDB: Internal thread select error\n"); | ||
553 | dump_stack(); | ||
554 | return NULL; | ||
555 | } | ||
550 | 556 | ||
551 | /* | 557 | /* |
552 | * find_task_by_pid_ns() does not take the tasklist lock anymore | 558 | * find_task_by_pid_ns() does not take the tasklist lock anymore |
@@ -577,6 +583,9 @@ static void kgdb_wait(struct pt_regs *regs) | |||
577 | smp_wmb(); | 583 | smp_wmb(); |
578 | atomic_set(&cpu_in_kgdb[cpu], 1); | 584 | atomic_set(&cpu_in_kgdb[cpu], 1); |
579 | 585 | ||
586 | /* Disable any cpu specific hw breakpoints */ | ||
587 | kgdb_disable_hw_debug(regs); | ||
588 | |||
580 | /* Wait till primary CPU is done with debugging */ | 589 | /* Wait till primary CPU is done with debugging */ |
581 | while (atomic_read(&passive_cpu_wait[cpu])) | 590 | while (atomic_read(&passive_cpu_wait[cpu])) |
582 | cpu_relax(); | 591 | cpu_relax(); |
@@ -590,7 +599,7 @@ static void kgdb_wait(struct pt_regs *regs) | |||
590 | 599 | ||
591 | /* Signal the primary CPU that we are done: */ | 600 | /* Signal the primary CPU that we are done: */ |
592 | atomic_set(&cpu_in_kgdb[cpu], 0); | 601 | atomic_set(&cpu_in_kgdb[cpu], 0); |
593 | touch_softlockup_watchdog(); | 602 | touch_softlockup_watchdog_sync(); |
594 | clocksource_touch_watchdog(); | 603 | clocksource_touch_watchdog(); |
595 | local_irq_restore(flags); | 604 | local_irq_restore(flags); |
596 | } | 605 | } |
@@ -619,7 +628,8 @@ static void kgdb_flush_swbreak_addr(unsigned long addr) | |||
619 | static int kgdb_activate_sw_breakpoints(void) | 628 | static int kgdb_activate_sw_breakpoints(void) |
620 | { | 629 | { |
621 | unsigned long addr; | 630 | unsigned long addr; |
622 | int error = 0; | 631 | int error; |
632 | int ret = 0; | ||
623 | int i; | 633 | int i; |
624 | 634 | ||
625 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { | 635 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { |
@@ -629,13 +639,16 @@ static int kgdb_activate_sw_breakpoints(void) | |||
629 | addr = kgdb_break[i].bpt_addr; | 639 | addr = kgdb_break[i].bpt_addr; |
630 | error = kgdb_arch_set_breakpoint(addr, | 640 | error = kgdb_arch_set_breakpoint(addr, |
631 | kgdb_break[i].saved_instr); | 641 | kgdb_break[i].saved_instr); |
632 | if (error) | 642 | if (error) { |
633 | return error; | 643 | ret = error; |
644 | printk(KERN_INFO "KGDB: BP install failed: %lx", addr); | ||
645 | continue; | ||
646 | } | ||
634 | 647 | ||
635 | kgdb_flush_swbreak_addr(addr); | 648 | kgdb_flush_swbreak_addr(addr); |
636 | kgdb_break[i].state = BP_ACTIVE; | 649 | kgdb_break[i].state = BP_ACTIVE; |
637 | } | 650 | } |
638 | return 0; | 651 | return ret; |
639 | } | 652 | } |
640 | 653 | ||
641 | static int kgdb_set_sw_break(unsigned long addr) | 654 | static int kgdb_set_sw_break(unsigned long addr) |
@@ -682,7 +695,8 @@ static int kgdb_set_sw_break(unsigned long addr) | |||
682 | static int kgdb_deactivate_sw_breakpoints(void) | 695 | static int kgdb_deactivate_sw_breakpoints(void) |
683 | { | 696 | { |
684 | unsigned long addr; | 697 | unsigned long addr; |
685 | int error = 0; | 698 | int error; |
699 | int ret = 0; | ||
686 | int i; | 700 | int i; |
687 | 701 | ||
688 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { | 702 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { |
@@ -691,13 +705,15 @@ static int kgdb_deactivate_sw_breakpoints(void) | |||
691 | addr = kgdb_break[i].bpt_addr; | 705 | addr = kgdb_break[i].bpt_addr; |
692 | error = kgdb_arch_remove_breakpoint(addr, | 706 | error = kgdb_arch_remove_breakpoint(addr, |
693 | kgdb_break[i].saved_instr); | 707 | kgdb_break[i].saved_instr); |
694 | if (error) | 708 | if (error) { |
695 | return error; | 709 | printk(KERN_INFO "KGDB: BP remove failed: %lx\n", addr); |
710 | ret = error; | ||
711 | } | ||
696 | 712 | ||
697 | kgdb_flush_swbreak_addr(addr); | 713 | kgdb_flush_swbreak_addr(addr); |
698 | kgdb_break[i].state = BP_SET; | 714 | kgdb_break[i].state = BP_SET; |
699 | } | 715 | } |
700 | return 0; | 716 | return ret; |
701 | } | 717 | } |
702 | 718 | ||
703 | static int kgdb_remove_sw_break(unsigned long addr) | 719 | static int kgdb_remove_sw_break(unsigned long addr) |
@@ -870,7 +886,7 @@ static void gdb_cmd_getregs(struct kgdb_state *ks) | |||
870 | 886 | ||
871 | /* | 887 | /* |
872 | * All threads that don't have debuggerinfo should be | 888 | * All threads that don't have debuggerinfo should be |
873 | * in __schedule() sleeping, since all other CPUs | 889 | * in schedule() sleeping, since all other CPUs |
874 | * are in kgdb_wait, and thus have debuggerinfo. | 890 | * are in kgdb_wait, and thus have debuggerinfo. |
875 | */ | 891 | */ |
876 | if (local_debuggerinfo) { | 892 | if (local_debuggerinfo) { |
@@ -1204,8 +1220,10 @@ static int gdb_cmd_exception_pass(struct kgdb_state *ks) | |||
1204 | return 1; | 1220 | return 1; |
1205 | 1221 | ||
1206 | } else { | 1222 | } else { |
1207 | error_packet(remcom_out_buffer, -EINVAL); | 1223 | kgdb_msg_write("KGDB only knows signal 9 (pass)" |
1208 | return 0; | 1224 | " and 15 (pass and disconnect)\n" |
1225 | "Executing a continue without signal passing\n", 0); | ||
1226 | remcom_in_buffer[0] = 'c'; | ||
1209 | } | 1227 | } |
1210 | 1228 | ||
1211 | /* Indicate fall through */ | 1229 | /* Indicate fall through */ |
@@ -1395,6 +1413,7 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs) | |||
1395 | struct kgdb_state kgdb_var; | 1413 | struct kgdb_state kgdb_var; |
1396 | struct kgdb_state *ks = &kgdb_var; | 1414 | struct kgdb_state *ks = &kgdb_var; |
1397 | unsigned long flags; | 1415 | unsigned long flags; |
1416 | int sstep_tries = 100; | ||
1398 | int error = 0; | 1417 | int error = 0; |
1399 | int i, cpu; | 1418 | int i, cpu; |
1400 | 1419 | ||
@@ -1425,15 +1444,16 @@ acquirelock: | |||
1425 | cpu_relax(); | 1444 | cpu_relax(); |
1426 | 1445 | ||
1427 | /* | 1446 | /* |
1428 | * Do not start the debugger connection on this CPU if the last | 1447 | * For single stepping, try to only enter on the processor |
1429 | * instance of the exception handler wanted to come into the | 1448 | * that was single stepping. To gaurd against a deadlock, the |
1430 | * debugger on a different CPU via a single step | 1449 | * kernel will only try for the value of sstep_tries before |
1450 | * giving up and continuing on. | ||
1431 | */ | 1451 | */ |
1432 | if (atomic_read(&kgdb_cpu_doing_single_step) != -1 && | 1452 | if (atomic_read(&kgdb_cpu_doing_single_step) != -1 && |
1433 | atomic_read(&kgdb_cpu_doing_single_step) != cpu) { | 1453 | (kgdb_info[cpu].task && |
1434 | 1454 | kgdb_info[cpu].task->pid != kgdb_sstep_pid) && --sstep_tries) { | |
1435 | atomic_set(&kgdb_active, -1); | 1455 | atomic_set(&kgdb_active, -1); |
1436 | touch_softlockup_watchdog(); | 1456 | touch_softlockup_watchdog_sync(); |
1437 | clocksource_touch_watchdog(); | 1457 | clocksource_touch_watchdog(); |
1438 | local_irq_restore(flags); | 1458 | local_irq_restore(flags); |
1439 | 1459 | ||
@@ -1524,9 +1544,16 @@ acquirelock: | |||
1524 | } | 1544 | } |
1525 | 1545 | ||
1526 | kgdb_restore: | 1546 | kgdb_restore: |
1547 | if (atomic_read(&kgdb_cpu_doing_single_step) != -1) { | ||
1548 | int sstep_cpu = atomic_read(&kgdb_cpu_doing_single_step); | ||
1549 | if (kgdb_info[sstep_cpu].task) | ||
1550 | kgdb_sstep_pid = kgdb_info[sstep_cpu].task->pid; | ||
1551 | else | ||
1552 | kgdb_sstep_pid = 0; | ||
1553 | } | ||
1527 | /* Free kgdb_active */ | 1554 | /* Free kgdb_active */ |
1528 | atomic_set(&kgdb_active, -1); | 1555 | atomic_set(&kgdb_active, -1); |
1529 | touch_softlockup_watchdog(); | 1556 | touch_softlockup_watchdog_sync(); |
1530 | clocksource_touch_watchdog(); | 1557 | clocksource_touch_watchdog(); |
1531 | local_irq_restore(flags); | 1558 | local_irq_restore(flags); |
1532 | 1559 | ||