Commit 974460c5bfd9f6c38aa3dda189a63f9fc351035f
Committed by
Ingo Molnar
1 parent
e3e2aaf7dc
Exists in
master
and in
39 other branches
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>
Showing 2 changed files with 42 additions and 17 deletions Side-by-side Diff
drivers/misc/kgdbts.c
... | ... | @@ -112,6 +112,10 @@ |
112 | 112 | printk(KERN_INFO a); \ |
113 | 113 | touch_nmi_watchdog(); \ |
114 | 114 | } while (0) |
115 | +#define eprintk(a...) do { \ | |
116 | + printk(KERN_ERR a); \ | |
117 | + WARN_ON(1); \ | |
118 | + } while (0) | |
115 | 119 | #define MAX_CONFIG_LEN 40 |
116 | 120 | |
117 | 121 | static const char hexchars[] = "0123456789abcdef"; |
118 | 122 | |
... | ... | @@ -145,7 +149,11 @@ |
145 | 149 | /* -1 = init not run yet, 0 = unconfigured, 1 = configured. */ |
146 | 150 | static int configured = -1; |
147 | 151 | |
152 | +#ifdef CONFIG_KGDB_TESTS_BOOT_STRING | |
153 | +static char config[MAX_CONFIG_LEN] = CONFIG_KGDB_TESTS_BOOT_STRING; | |
154 | +#else | |
148 | 155 | static char config[MAX_CONFIG_LEN]; |
156 | +#endif | |
149 | 157 | static struct kparam_string kps = { |
150 | 158 | .string = config, |
151 | 159 | .maxlen = MAX_CONFIG_LEN, |
... | ... | @@ -289,7 +297,7 @@ |
289 | 297 | #endif |
290 | 298 | if (strcmp(arg, "silent") && |
291 | 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 | 301 | instruction_pointer(&kgdbts_regs) + offset, addr); |
294 | 302 | return 1; |
295 | 303 | } |
... | ... | @@ -313,7 +321,7 @@ |
313 | 321 | v2printk("Singlestep stopped at IP: %lx\n", |
314 | 322 | instruction_pointer(&kgdbts_regs)); |
315 | 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 | 325 | instruction_pointer(&kgdbts_regs)); |
318 | 326 | return 1; |
319 | 327 | } |
... | ... | @@ -378,7 +386,7 @@ |
378 | 386 | break_helper("z0", 0, sstep_addr); |
379 | 387 | break; |
380 | 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 | 391 | sstep_state++; |
384 | 392 | } |
385 | 393 | |
386 | 394 | |
387 | 395 | |
... | ... | @@ -404,26 +412,26 @@ |
404 | 412 | break; |
405 | 413 | case 2: |
406 | 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 | 416 | return 1; |
409 | 417 | } |
410 | 418 | break; |
411 | 419 | case 3: |
412 | 420 | if (strncmp(put_str, "$T0", 3)) { |
413 | - printk(KERN_ERR "kgdbts: failed continue sstep\n"); | |
421 | + eprintk("kgdbts: failed continue sstep\n"); | |
414 | 422 | return 1; |
415 | 423 | } |
416 | 424 | break; |
417 | 425 | case 4: |
418 | 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 | 428 | return 1; |
421 | 429 | } |
422 | 430 | /* Single step is complete so continue on! */ |
423 | 431 | sstep_state = 0; |
424 | 432 | return 0; |
425 | 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 | 437 | /* Continue on the same test line until emulation is complete */ |
... | ... | @@ -668,8 +676,7 @@ |
668 | 676 | } |
669 | 677 | |
670 | 678 | if (get_buf[get_buf_cnt] == '\0') { |
671 | - printk(KERN_ERR | |
672 | - "kgdbts: ERROR GET: end of buffer on '%s' at %i\n", | |
679 | + eprintk("kgdbts: ERROR GET: EOB on '%s' at %i\n", | |
673 | 680 | ts.name, ts.idx); |
674 | 681 | get_buf_cnt = 0; |
675 | 682 | fill_get_buf("D"); |
676 | 683 | |
... | ... | @@ -684,13 +691,13 @@ |
684 | 691 | */ |
685 | 692 | if (ts.tst[ts.idx].get[0] == '\0' && |
686 | 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 | 695 | " '%s' line %i\n", ts.name, ts.idx); |
689 | 696 | return 0; |
690 | 697 | } |
691 | 698 | |
692 | 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 | 701 | " '%s' line %i\n", ts.name, ts.idx); |
695 | 702 | put_buf_cnt = 0; |
696 | 703 | return 0; |
... | ... | @@ -708,7 +715,7 @@ |
708 | 715 | v2printk("put%i: %s\n", ts.idx, put_buf); |
709 | 716 | /* Trigger check here */ |
710 | 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 | 719 | "buffer on '%s' line %i expected %s got %s\n", |
713 | 720 | ts.name, ts.idx, ts.tst[ts.idx].put, put_buf); |
714 | 721 | } |
... | ... | @@ -772,7 +779,7 @@ |
772 | 779 | if (test_complete) |
773 | 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 | |
778 | 785 | static void run_hw_break_test(int is_write_test) |
... | ... | @@ -791,7 +798,7 @@ |
791 | 798 | hw_break_val_access(); |
792 | 799 | if (is_write_test) { |
793 | 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 | 802 | ts.name); |
796 | 803 | hw_break_val_write(); |
797 | 804 | } |
... | ... | @@ -800,7 +807,7 @@ |
800 | 807 | if (test_complete == 1) |
801 | 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 | |
806 | 813 | static void run_nmi_sleep_test(int nmi_sleep) |
807 | 814 | |
... | ... | @@ -817,12 +824,12 @@ |
817 | 824 | touch_nmi_watchdog(); |
818 | 825 | local_irq_restore(flags); |
819 | 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 | 828 | kgdb_breakpoint(); |
822 | 829 | if (test_complete == 1) |
823 | 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 | |
828 | 835 | static void run_bad_read_test(void) |
lib/Kconfig.kgdb
... | ... | @@ -38,4 +38,22 @@ |
38 | 38 | See the drivers/misc/kgdbts.c for the details about |
39 | 39 | the tests. The most basic of this I/O module is to boot |
40 | 40 | a kernel boot arguments "kgdbwait kgdbts=V1F100" |
41 | + | |
42 | +config 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 | + | |
50 | +config 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. |