diff options
-rw-r--r-- | drivers/misc/kgdbts.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c index 2763ae086531..e4ff50b95a5e 100644 --- a/drivers/misc/kgdbts.c +++ b/drivers/misc/kgdbts.c | |||
@@ -102,7 +102,6 @@ | |||
102 | #include <linux/nmi.h> | 102 | #include <linux/nmi.h> |
103 | #include <linux/delay.h> | 103 | #include <linux/delay.h> |
104 | #include <linux/kthread.h> | 104 | #include <linux/kthread.h> |
105 | #include <linux/delay.h> | ||
106 | 105 | ||
107 | #define v1printk(a...) do { \ | 106 | #define v1printk(a...) do { \ |
108 | if (verbose) \ | 107 | if (verbose) \ |
@@ -130,6 +129,8 @@ static int repeat_test; | |||
130 | static int test_complete; | 129 | static int test_complete; |
131 | static int send_ack; | 130 | static int send_ack; |
132 | static int final_ack; | 131 | static int final_ack; |
132 | static int force_hwbrks; | ||
133 | static int hwbreaks_ok; | ||
133 | static int hw_break_val; | 134 | static int hw_break_val; |
134 | static int hw_break_val2; | 135 | static int hw_break_val2; |
135 | #if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || defined(CONFIG_SPARC) | 136 | #if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || defined(CONFIG_SPARC) |
@@ -233,12 +234,12 @@ static void break_helper(char *bp_type, char *arg, unsigned long vaddr) | |||
233 | 234 | ||
234 | static void sw_break(char *arg) | 235 | static void sw_break(char *arg) |
235 | { | 236 | { |
236 | break_helper("Z0", arg, 0); | 237 | break_helper(force_hwbrks ? "Z1" : "Z0", arg, 0); |
237 | } | 238 | } |
238 | 239 | ||
239 | static void sw_rem_break(char *arg) | 240 | static void sw_rem_break(char *arg) |
240 | { | 241 | { |
241 | break_helper("z0", arg, 0); | 242 | break_helper(force_hwbrks ? "z1" : "z0", arg, 0); |
242 | } | 243 | } |
243 | 244 | ||
244 | static void hw_break(char *arg) | 245 | static void hw_break(char *arg) |
@@ -780,6 +781,8 @@ static void run_breakpoint_test(int is_hw_breakpoint) | |||
780 | return; | 781 | return; |
781 | 782 | ||
782 | eprintk("kgdbts: ERROR %s test failed\n", ts.name); | 783 | eprintk("kgdbts: ERROR %s test failed\n", ts.name); |
784 | if (is_hw_breakpoint) | ||
785 | hwbreaks_ok = 0; | ||
783 | } | 786 | } |
784 | 787 | ||
785 | static void run_hw_break_test(int is_write_test) | 788 | static void run_hw_break_test(int is_write_test) |
@@ -797,9 +800,11 @@ static void run_hw_break_test(int is_write_test) | |||
797 | kgdb_breakpoint(); | 800 | kgdb_breakpoint(); |
798 | hw_break_val_access(); | 801 | hw_break_val_access(); |
799 | if (is_write_test) { | 802 | if (is_write_test) { |
800 | if (test_complete == 2) | 803 | if (test_complete == 2) { |
801 | eprintk("kgdbts: ERROR %s broke on access\n", | 804 | eprintk("kgdbts: ERROR %s broke on access\n", |
802 | ts.name); | 805 | ts.name); |
806 | hwbreaks_ok = 0; | ||
807 | } | ||
803 | hw_break_val_write(); | 808 | hw_break_val_write(); |
804 | } | 809 | } |
805 | kgdb_breakpoint(); | 810 | kgdb_breakpoint(); |
@@ -808,6 +813,7 @@ static void run_hw_break_test(int is_write_test) | |||
808 | return; | 813 | return; |
809 | 814 | ||
810 | eprintk("kgdbts: ERROR %s test failed\n", ts.name); | 815 | eprintk("kgdbts: ERROR %s test failed\n", ts.name); |
816 | hwbreaks_ok = 0; | ||
811 | } | 817 | } |
812 | 818 | ||
813 | static void run_nmi_sleep_test(int nmi_sleep) | 819 | static void run_nmi_sleep_test(int nmi_sleep) |
@@ -911,6 +917,7 @@ static void kgdbts_run_tests(void) | |||
911 | 917 | ||
912 | /* All HW break point tests */ | 918 | /* All HW break point tests */ |
913 | if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) { | 919 | if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) { |
920 | hwbreaks_ok = 1; | ||
914 | v1printk("kgdbts:RUN hw breakpoint test\n"); | 921 | v1printk("kgdbts:RUN hw breakpoint test\n"); |
915 | run_breakpoint_test(1); | 922 | run_breakpoint_test(1); |
916 | v1printk("kgdbts:RUN hw write breakpoint test\n"); | 923 | v1printk("kgdbts:RUN hw write breakpoint test\n"); |
@@ -924,6 +931,19 @@ static void kgdbts_run_tests(void) | |||
924 | run_nmi_sleep_test(nmi_sleep); | 931 | run_nmi_sleep_test(nmi_sleep); |
925 | } | 932 | } |
926 | 933 | ||
934 | #ifdef CONFIG_DEBUG_RODATA | ||
935 | /* Until there is an api to write to read-only text segments, use | ||
936 | * HW breakpoints for the remainder of any tests, else print a | ||
937 | * failure message if hw breakpoints do not work. | ||
938 | */ | ||
939 | if (!(arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT && hwbreaks_ok)) { | ||
940 | eprintk("kgdbts: HW breakpoints do not work," | ||
941 | "skipping remaining tests\n"); | ||
942 | return; | ||
943 | } | ||
944 | force_hwbrks = 1; | ||
945 | #endif /* CONFIG_DEBUG_RODATA */ | ||
946 | |||
927 | /* If the do_fork test is run it will be the last test that is | 947 | /* If the do_fork test is run it will be the last test that is |
928 | * executed because a kernel thread will be spawned at the very | 948 | * executed because a kernel thread will be spawned at the very |
929 | * end to unregister the debug hooks. | 949 | * end to unregister the debug hooks. |