aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mn10300
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2011-03-18 12:54:29 -0400
committerDavid Howells <dhowells@redhat.com>2011-03-18 12:54:29 -0400
commit9ee21723ccc30070f47c411826d4ed013cd050c2 (patch)
tree5f460e51e72ef93f4103c39032f1aec298a638db /arch/mn10300
parentddb7d1e975d224885397c002512ded987be3c3bc (diff)
MN10300: gdbstub: Restrict single-stepping to non-preemptable non-SMP configs
Restrict single-stepping through the kernel using gdbstub to non-preemptable non-SMP configs as gdbstub has to do software single-stepping by means of temporary breakpoints. Hardware single-stepping is unavailable as Panasonic have not sufficiently documented the interface to it. Software single-stepping through preemptable or SMP kernels runs into problems as it makes it much more likely that the wrong thread will hit the temporary breakpoints. It seems impractical to work around the problem for the most part. It could be possible to make a UP preemptable kernel switch temporary breakpoints in and out in switch_to(). Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'arch/mn10300')
-rw-r--r--arch/mn10300/Kconfig.debug8
-rw-r--r--arch/mn10300/kernel/gdb-stub.c12
2 files changed, 18 insertions, 2 deletions
diff --git a/arch/mn10300/Kconfig.debug b/arch/mn10300/Kconfig.debug
index ce83c74b3fd7..a1b8620f65ae 100644
--- a/arch/mn10300/Kconfig.debug
+++ b/arch/mn10300/Kconfig.debug
@@ -54,6 +54,14 @@ config GDBSTUB_IMMEDIATE
54 possible, leaving the program counter at the beginning of 54 possible, leaving the program counter at the beginning of
55 start_kernel() in init/main.c. 55 start_kernel() in init/main.c.
56 56
57config GDBSTUB_ALLOW_SINGLE_STEP
58 bool "Allow software single-stepping in GDB stub"
59 depends on GDBSTUB && !SMP && !PREEMPT
60 help
61 Allow GDB stub to perform software single-stepping through the
62 kernel. This doesn't work very well on SMP or preemptible kernels as
63 it uses temporary breakpoints to emulate single-stepping.
64
57config GDB_CONSOLE 65config GDB_CONSOLE
58 bool "Console output to GDB" 66 bool "Console output to GDB"
59 depends on GDBSTUB 67 depends on GDBSTUB
diff --git a/arch/mn10300/kernel/gdb-stub.c b/arch/mn10300/kernel/gdb-stub.c
index b169d99d9f20..a9c1e916687f 100644
--- a/arch/mn10300/kernel/gdb-stub.c
+++ b/arch/mn10300/kernel/gdb-stub.c
@@ -405,6 +405,7 @@ static int hexToInt(char **ptr, int *intValue)
405 return (numChars); 405 return (numChars);
406} 406}
407 407
408#ifdef CONFIG_GDBSTUB_ALLOW_SINGLE_STEP
408/* 409/*
409 * We single-step by setting breakpoints. When an exception 410 * We single-step by setting breakpoints. When an exception
410 * is handled, we need to restore the instructions hoisted 411 * is handled, we need to restore the instructions hoisted
@@ -729,6 +730,7 @@ static int gdbstub_single_step(struct pt_regs *regs)
729 __gdbstub_restore_bp(); 730 __gdbstub_restore_bp();
730 return -EFAULT; 731 return -EFAULT;
731} 732}
733#endif /* CONFIG_GDBSTUB_ALLOW_SINGLE_STEP */
732 734
733#ifdef CONFIG_GDBSTUB_CONSOLE 735#ifdef CONFIG_GDBSTUB_CONSOLE
734 736
@@ -1208,11 +1210,13 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep)
1208 /* if we were single stepping, restore the opcodes hoisted for the 1210 /* if we were single stepping, restore the opcodes hoisted for the
1209 * breakpoint[s] */ 1211 * breakpoint[s] */
1210 broke = 0; 1212 broke = 0;
1213#ifdef CONFIG_GDBSTUB_ALLOW_SINGLE_STEP
1211 if ((step_bp[0].addr && step_bp[0].addr == (u8 *) regs->pc) || 1214 if ((step_bp[0].addr && step_bp[0].addr == (u8 *) regs->pc) ||
1212 (step_bp[1].addr && step_bp[1].addr == (u8 *) regs->pc)) 1215 (step_bp[1].addr && step_bp[1].addr == (u8 *) regs->pc))
1213 broke = 1; 1216 broke = 1;
1214 1217
1215 __gdbstub_restore_bp(); 1218 __gdbstub_restore_bp();
1219#endif
1216 1220
1217 if (gdbstub_rx_unget) { 1221 if (gdbstub_rx_unget) {
1218 sigval = SIGINT; 1222 sigval = SIGINT;
@@ -1548,17 +1552,21 @@ packet_waiting:
1548 * Step to next instruction 1552 * Step to next instruction
1549 */ 1553 */
1550 case 's': 1554 case 's':
1551 /* 1555 /* Using the T flag doesn't seem to perform single
1552 * using the T flag doesn't seem to perform single
1553 * stepping (it seems to wind up being caught by the 1556 * stepping (it seems to wind up being caught by the
1554 * JTAG unit), so we have to use breakpoints and 1557 * JTAG unit), so we have to use breakpoints and
1555 * continue instead. 1558 * continue instead.
1556 */ 1559 */
1560#ifdef CONFIG_GDBSTUB_ALLOW_SINGLE_STEP
1557 if (gdbstub_single_step(regs) < 0) 1561 if (gdbstub_single_step(regs) < 0)
1558 /* ignore any fault error for now */ 1562 /* ignore any fault error for now */
1559 gdbstub_printk("unable to set single-step" 1563 gdbstub_printk("unable to set single-step"
1560 " bp\n"); 1564 " bp\n");
1561 goto done; 1565 goto done;
1566#else
1567 gdbstub_strcpy(output_buffer, "E01");
1568 break;
1569#endif
1562 1570
1563 /* 1571 /*
1564 * Set baud rate (bBB) 1572 * Set baud rate (bBB)