diff options
Diffstat (limited to 'kernel/kgdb.c')
-rw-r--r-- | kernel/kgdb.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/kernel/kgdb.c b/kernel/kgdb.c index 29357a9ccfb2..ca21fe98e8de 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]; |
@@ -1400,6 +1401,7 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs) | |||
1400 | struct kgdb_state kgdb_var; | 1401 | struct kgdb_state kgdb_var; |
1401 | struct kgdb_state *ks = &kgdb_var; | 1402 | struct kgdb_state *ks = &kgdb_var; |
1402 | unsigned long flags; | 1403 | unsigned long flags; |
1404 | int sstep_tries = 100; | ||
1403 | int error = 0; | 1405 | int error = 0; |
1404 | int i, cpu; | 1406 | int i, cpu; |
1405 | 1407 | ||
@@ -1430,13 +1432,14 @@ acquirelock: | |||
1430 | cpu_relax(); | 1432 | cpu_relax(); |
1431 | 1433 | ||
1432 | /* | 1434 | /* |
1433 | * Do not start the debugger connection on this CPU if the last | 1435 | * For single stepping, try to only enter on the processor |
1434 | * instance of the exception handler wanted to come into the | 1436 | * that was single stepping. To gaurd against a deadlock, the |
1435 | * debugger on a different CPU via a single step | 1437 | * kernel will only try for the value of sstep_tries before |
1438 | * giving up and continuing on. | ||
1436 | */ | 1439 | */ |
1437 | if (atomic_read(&kgdb_cpu_doing_single_step) != -1 && | 1440 | if (atomic_read(&kgdb_cpu_doing_single_step) != -1 && |
1438 | atomic_read(&kgdb_cpu_doing_single_step) != cpu) { | 1441 | (kgdb_info[cpu].task && |
1439 | 1442 | kgdb_info[cpu].task->pid != kgdb_sstep_pid) && --sstep_tries) { | |
1440 | atomic_set(&kgdb_active, -1); | 1443 | atomic_set(&kgdb_active, -1); |
1441 | touch_softlockup_watchdog(); | 1444 | touch_softlockup_watchdog(); |
1442 | clocksource_touch_watchdog(); | 1445 | clocksource_touch_watchdog(); |
@@ -1529,6 +1532,13 @@ acquirelock: | |||
1529 | } | 1532 | } |
1530 | 1533 | ||
1531 | kgdb_restore: | 1534 | kgdb_restore: |
1535 | if (atomic_read(&kgdb_cpu_doing_single_step) != -1) { | ||
1536 | int sstep_cpu = atomic_read(&kgdb_cpu_doing_single_step); | ||
1537 | if (kgdb_info[sstep_cpu].task) | ||
1538 | kgdb_sstep_pid = kgdb_info[sstep_cpu].task->pid; | ||
1539 | else | ||
1540 | kgdb_sstep_pid = 0; | ||
1541 | } | ||
1532 | /* Free kgdb_active */ | 1542 | /* Free kgdb_active */ |
1533 | atomic_set(&kgdb_active, -1); | 1543 | atomic_set(&kgdb_active, -1); |
1534 | touch_softlockup_watchdog(); | 1544 | touch_softlockup_watchdog(); |