aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Wessel <jason.wessel@windriver.com>2008-03-20 14:43:44 -0400
committerIngo Molnar <mingo@elte.hu>2008-04-17 14:05:43 -0400
commit974460c5bfd9f6c38aa3dda189a63f9fc351035f (patch)
treefbfe9c79956e5fb31ff3da72b628d72d31d5f453
parente3e2aaf7dc0d82a055e084cfd48b9257c0c66b68 (diff)
kgdb: allow static kgdbts boot configuration
This patch adds in the ability to compile the kgdb internal test string into the kernel so as to run the tests at boot without changing the kernel boot arguments. This patch also changes all the error paths to invoke WARN_ON(1) which will emit the line number of the file and dump the kernel stack when an error occurs. You can disable the tests in a kernel that is built this way using "kgdbts=" Signed-off-by: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--drivers/misc/kgdbts.c41
-rw-r--r--lib/Kconfig.kgdb18
2 files changed, 42 insertions, 17 deletions
diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c
index cbc4822b5847..6d6286c4eeac 100644
--- a/drivers/misc/kgdbts.c
+++ b/drivers/misc/kgdbts.c
@@ -112,6 +112,10 @@
112 printk(KERN_INFO a); \ 112 printk(KERN_INFO a); \
113 touch_nmi_watchdog(); \ 113 touch_nmi_watchdog(); \
114 } while (0) 114 } while (0)
115#define eprintk(a...) do { \
116 printk(KERN_ERR a); \
117 WARN_ON(1); \
118 } while (0)
115#define MAX_CONFIG_LEN 40 119#define MAX_CONFIG_LEN 40
116 120
117static const char hexchars[] = "0123456789abcdef"; 121static const char hexchars[] = "0123456789abcdef";
@@ -145,7 +149,11 @@ static struct pt_regs kgdbts_regs;
145/* -1 = init not run yet, 0 = unconfigured, 1 = configured. */ 149/* -1 = init not run yet, 0 = unconfigured, 1 = configured. */
146static int configured = -1; 150static int configured = -1;
147 151
152#ifdef CONFIG_KGDB_TESTS_BOOT_STRING
153static char config[MAX_CONFIG_LEN] = CONFIG_KGDB_TESTS_BOOT_STRING;
154#else
148static char config[MAX_CONFIG_LEN]; 155static char config[MAX_CONFIG_LEN];
156#endif
149static struct kparam_string kps = { 157static struct kparam_string kps = {
150 .string = config, 158 .string = config,
151 .maxlen = MAX_CONFIG_LEN, 159 .maxlen = MAX_CONFIG_LEN,
@@ -289,7 +297,7 @@ static int check_and_rewind_pc(char *put_str, char *arg)
289#endif 297#endif
290 if (strcmp(arg, "silent") && 298 if (strcmp(arg, "silent") &&
291 instruction_pointer(&kgdbts_regs) + offset != addr) { 299 instruction_pointer(&kgdbts_regs) + offset != addr) {
292 printk(KERN_ERR "kgdbts: BP mismatch %lx expected %lx\n", 300 eprintk("kgdbts: BP mismatch %lx expected %lx\n",
293 instruction_pointer(&kgdbts_regs) + offset, addr); 301 instruction_pointer(&kgdbts_regs) + offset, addr);
294 return 1; 302 return 1;
295 } 303 }
@@ -313,7 +321,7 @@ static int check_single_step(char *put_str, char *arg)
313 v2printk("Singlestep stopped at IP: %lx\n", 321 v2printk("Singlestep stopped at IP: %lx\n",
314 instruction_pointer(&kgdbts_regs)); 322 instruction_pointer(&kgdbts_regs));
315 if (instruction_pointer(&kgdbts_regs) == addr) { 323 if (instruction_pointer(&kgdbts_regs) == addr) {
316 printk(KERN_ERR "kgdbts: SingleStep failed at %lx\n", 324 eprintk("kgdbts: SingleStep failed at %lx\n",
317 instruction_pointer(&kgdbts_regs)); 325 instruction_pointer(&kgdbts_regs));
318 return 1; 326 return 1;
319 } 327 }
@@ -378,7 +386,7 @@ static void emul_sstep_get(char *arg)
378 break_helper("z0", 0, sstep_addr); 386 break_helper("z0", 0, sstep_addr);
379 break; 387 break;
380 default: 388 default:
381 printk(KERN_ERR "kgdbts: ERROR failed sstep get emulation\n"); 389 eprintk("kgdbts: ERROR failed sstep get emulation\n");
382 } 390 }
383 sstep_state++; 391 sstep_state++;
384} 392}
@@ -404,26 +412,26 @@ static int emul_sstep_put(char *put_str, char *arg)
404 break; 412 break;
405 case 2: 413 case 2:
406 if (strncmp(put_str, "$OK", 3)) { 414 if (strncmp(put_str, "$OK", 3)) {
407 printk(KERN_ERR "kgdbts: failed sstep break set\n"); 415 eprintk("kgdbts: failed sstep break set\n");
408 return 1; 416 return 1;
409 } 417 }
410 break; 418 break;
411 case 3: 419 case 3:
412 if (strncmp(put_str, "$T0", 3)) { 420 if (strncmp(put_str, "$T0", 3)) {
413 printk(KERN_ERR "kgdbts: failed continue sstep\n"); 421 eprintk("kgdbts: failed continue sstep\n");
414 return 1; 422 return 1;
415 } 423 }
416 break; 424 break;
417 case 4: 425 case 4:
418 if (strncmp(put_str, "$OK", 3)) { 426 if (strncmp(put_str, "$OK", 3)) {
419 printk(KERN_ERR "kgdbts: failed sstep break unset\n"); 427 eprintk("kgdbts: failed sstep break unset\n");
420 return 1; 428 return 1;
421 } 429 }
422 /* Single step is complete so continue on! */ 430 /* Single step is complete so continue on! */
423 sstep_state = 0; 431 sstep_state = 0;
424 return 0; 432 return 0;
425 default: 433 default:
426 printk(KERN_ERR "kgdbts: ERROR failed sstep put emulation\n"); 434 eprintk("kgdbts: ERROR failed sstep put emulation\n");
427 } 435 }
428 436
429 /* Continue on the same test line until emulation is complete */ 437 /* Continue on the same test line until emulation is complete */
@@ -668,8 +676,7 @@ static int run_simple_test(int is_get_char, int chr)
668 } 676 }
669 677
670 if (get_buf[get_buf_cnt] == '\0') { 678 if (get_buf[get_buf_cnt] == '\0') {
671 printk(KERN_ERR 679 eprintk("kgdbts: ERROR GET: EOB on '%s' at %i\n",
672 "kgdbts: ERROR GET: end of buffer on '%s' at %i\n",
673 ts.name, ts.idx); 680 ts.name, ts.idx);
674 get_buf_cnt = 0; 681 get_buf_cnt = 0;
675 fill_get_buf("D"); 682 fill_get_buf("D");
@@ -684,13 +691,13 @@ static int run_simple_test(int is_get_char, int chr)
684 */ 691 */
685 if (ts.tst[ts.idx].get[0] == '\0' && 692 if (ts.tst[ts.idx].get[0] == '\0' &&
686 ts.tst[ts.idx].put[0] == '\0') { 693 ts.tst[ts.idx].put[0] == '\0') {
687 printk(KERN_ERR "kgdbts: ERROR: beyond end of test on" 694 eprintk("kgdbts: ERROR: beyond end of test on"
688 " '%s' line %i\n", ts.name, ts.idx); 695 " '%s' line %i\n", ts.name, ts.idx);
689 return 0; 696 return 0;
690 } 697 }
691 698
692 if (put_buf_cnt >= BUFMAX) { 699 if (put_buf_cnt >= BUFMAX) {
693 printk(KERN_ERR "kgdbts: ERROR: put buffer overflow on" 700 eprintk("kgdbts: ERROR: put buffer overflow on"
694 " '%s' line %i\n", ts.name, ts.idx); 701 " '%s' line %i\n", ts.name, ts.idx);
695 put_buf_cnt = 0; 702 put_buf_cnt = 0;
696 return 0; 703 return 0;
@@ -708,7 +715,7 @@ static int run_simple_test(int is_get_char, int chr)
708 v2printk("put%i: %s\n", ts.idx, put_buf); 715 v2printk("put%i: %s\n", ts.idx, put_buf);
709 /* Trigger check here */ 716 /* Trigger check here */
710 if (ts.validate_put && ts.validate_put(put_buf)) { 717 if (ts.validate_put && ts.validate_put(put_buf)) {
711 printk(KERN_ERR "kgdbts: ERROR PUT: end of test " 718 eprintk("kgdbts: ERROR PUT: end of test "
712 "buffer on '%s' line %i expected %s got %s\n", 719 "buffer on '%s' line %i expected %s got %s\n",
713 ts.name, ts.idx, ts.tst[ts.idx].put, put_buf); 720 ts.name, ts.idx, ts.tst[ts.idx].put, put_buf);
714 } 721 }
@@ -772,7 +779,7 @@ static void run_breakpoint_test(int is_hw_breakpoint)
772 if (test_complete) 779 if (test_complete)
773 return; 780 return;
774 781
775 printk(KERN_ERR "kgdbts: ERROR %s test failed\n", ts.name); 782 eprintk("kgdbts: ERROR %s test failed\n", ts.name);
776} 783}
777 784
778static void run_hw_break_test(int is_write_test) 785static void run_hw_break_test(int is_write_test)
@@ -791,7 +798,7 @@ static void run_hw_break_test(int is_write_test)
791 hw_break_val_access(); 798 hw_break_val_access();
792 if (is_write_test) { 799 if (is_write_test) {
793 if (test_complete == 2) 800 if (test_complete == 2)
794 printk(KERN_ERR "kgdbts: ERROR %s broke on access\n", 801 eprintk("kgdbts: ERROR %s broke on access\n",
795 ts.name); 802 ts.name);
796 hw_break_val_write(); 803 hw_break_val_write();
797 } 804 }
@@ -800,7 +807,7 @@ static void run_hw_break_test(int is_write_test)
800 if (test_complete == 1) 807 if (test_complete == 1)
801 return; 808 return;
802 809
803 printk(KERN_ERR "kgdbts: ERROR %s test failed\n", ts.name); 810 eprintk("kgdbts: ERROR %s test failed\n", ts.name);
804} 811}
805 812
806static void run_nmi_sleep_test(int nmi_sleep) 813static void run_nmi_sleep_test(int nmi_sleep)
@@ -817,12 +824,12 @@ static void run_nmi_sleep_test(int nmi_sleep)
817 touch_nmi_watchdog(); 824 touch_nmi_watchdog();
818 local_irq_restore(flags); 825 local_irq_restore(flags);
819 if (test_complete != 2) 826 if (test_complete != 2)
820 printk(KERN_ERR "kgdbts: ERROR nmi_test did not hit nmi\n"); 827 eprintk("kgdbts: ERROR nmi_test did not hit nmi\n");
821 kgdb_breakpoint(); 828 kgdb_breakpoint();
822 if (test_complete == 1) 829 if (test_complete == 1)
823 return; 830 return;
824 831
825 printk(KERN_ERR "kgdbts: ERROR %s test failed\n", ts.name); 832 eprintk("kgdbts: ERROR %s test failed\n", ts.name);
826} 833}
827 834
828static void run_bad_read_test(void) 835static void run_bad_read_test(void)
diff --git a/lib/Kconfig.kgdb b/lib/Kconfig.kgdb
index aaabcddcda5a..f2e01ac5ab09 100644
--- a/lib/Kconfig.kgdb
+++ b/lib/Kconfig.kgdb
@@ -38,3 +38,21 @@ config KGDB_TESTS
38 See the drivers/misc/kgdbts.c for the details about 38 See the drivers/misc/kgdbts.c for the details about
39 the tests. The most basic of this I/O module is to boot 39 the tests. The most basic of this I/O module is to boot
40 a kernel boot arguments "kgdbwait kgdbts=V1F100" 40 a kernel boot arguments "kgdbwait kgdbts=V1F100"
41
42config KGDB_TESTS_ON_BOOT
43 bool "KGDB: Run tests on boot"
44 depends on KGDB_TESTS
45 default n
46 help
47 Run the kgdb tests on boot up automatically without the need
48 to pass in a kernel parameter
49
50config KGDB_TESTS_BOOT_STRING
51 string "KGDB: which internal kgdb tests to run"
52 depends on KGDB_TESTS_ON_BOOT
53 default "V1F100"
54 help
55 This is the command string to send the kgdb test suite on
56 boot. See the drivers/misc/kgdbts.c for detailed
57 information about other strings you could use beyond the
58 default of V1F100.