Skip to content

Commit

Permalink
kgdbts: Use HW breakpoints with CONFIG_DEBUG_RODATA
Browse files Browse the repository at this point in the history
Whenever CONFIG_DEBUG_RODATA is set in the kernel config many kernel
text sections become read-only, and the use of software breakpoints in
the kgdb tests will cause the kernel to fail to complete the start up.

Until such time that there is an official API for modifying read-only
text sections hardware breakpoints must be used to run the do_fork or
sys_open tests or the tests get skipped.

Also fix the duplicated include reported by:
Huang Weiyi <weiyi.huang@gmail.com>

Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
  • Loading branch information
Jason Wessel committed May 28, 2008
1 parent 827e609 commit b33cb81
Showing 1 changed file with 24 additions and 4 deletions.
28 changes: 24 additions & 4 deletions drivers/misc/kgdbts.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@
#include <linux/nmi.h>
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/delay.h>

#define v1printk(a...) do { \
if (verbose) \
Expand Down Expand Up @@ -130,6 +129,8 @@ static int repeat_test;
static int test_complete;
static int send_ack;
static int final_ack;
static int force_hwbrks;
static int hwbreaks_ok;
static int hw_break_val;
static int hw_break_val2;
#if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || defined(CONFIG_SPARC)
Expand Down Expand Up @@ -233,12 +234,12 @@ static void break_helper(char *bp_type, char *arg, unsigned long vaddr)

static void sw_break(char *arg)
{
break_helper("Z0", arg, 0);
break_helper(force_hwbrks ? "Z1" : "Z0", arg, 0);
}

static void sw_rem_break(char *arg)
{
break_helper("z0", arg, 0);
break_helper(force_hwbrks ? "z1" : "z0", arg, 0);
}

static void hw_break(char *arg)
Expand Down Expand Up @@ -780,6 +781,8 @@ static void run_breakpoint_test(int is_hw_breakpoint)
return;

eprintk("kgdbts: ERROR %s test failed\n", ts.name);
if (is_hw_breakpoint)
hwbreaks_ok = 0;
}

static void run_hw_break_test(int is_write_test)
Expand All @@ -797,9 +800,11 @@ static void run_hw_break_test(int is_write_test)
kgdb_breakpoint();
hw_break_val_access();
if (is_write_test) {
if (test_complete == 2)
if (test_complete == 2) {
eprintk("kgdbts: ERROR %s broke on access\n",
ts.name);
hwbreaks_ok = 0;
}
hw_break_val_write();
}
kgdb_breakpoint();
Expand All @@ -808,6 +813,7 @@ static void run_hw_break_test(int is_write_test)
return;

eprintk("kgdbts: ERROR %s test failed\n", ts.name);
hwbreaks_ok = 0;
}

static void run_nmi_sleep_test(int nmi_sleep)
Expand Down Expand Up @@ -911,6 +917,7 @@ static void kgdbts_run_tests(void)

/* All HW break point tests */
if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) {
hwbreaks_ok = 1;
v1printk("kgdbts:RUN hw breakpoint test\n");
run_breakpoint_test(1);
v1printk("kgdbts:RUN hw write breakpoint test\n");
Expand All @@ -924,6 +931,19 @@ static void kgdbts_run_tests(void)
run_nmi_sleep_test(nmi_sleep);
}

#ifdef CONFIG_DEBUG_RODATA
/* Until there is an api to write to read-only text segments, use
* HW breakpoints for the remainder of any tests, else print a
* failure message if hw breakpoints do not work.
*/
if (!(arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT && hwbreaks_ok)) {
eprintk("kgdbts: HW breakpoints do not work,"
"skipping remaining tests\n");
return;
}
force_hwbrks = 1;
#endif /* CONFIG_DEBUG_RODATA */

/* If the do_fork test is run it will be the last test that is
* executed because a kernel thread will be spawned at the very
* end to unregister the debug hooks.
Expand Down

0 comments on commit b33cb81

Please sign in to comment.