diff options
Diffstat (limited to 'drivers/misc/kgdbts.c')
-rw-r--r-- | drivers/misc/kgdbts.c | 75 |
1 files changed, 43 insertions, 32 deletions
diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c index 30a1af857c7a..fa394104339c 100644 --- a/drivers/misc/kgdbts.c +++ b/drivers/misc/kgdbts.c | |||
@@ -47,6 +47,7 @@ | |||
47 | * to test the HW NMI watchdog | 47 | * to test the HW NMI watchdog |
48 | * F## = Break at do_fork for ## iterations | 48 | * F## = Break at do_fork for ## iterations |
49 | * S## = Break at sys_open for ## iterations | 49 | * S## = Break at sys_open for ## iterations |
50 | * I## = Run the single step test ## iterations | ||
50 | * | 51 | * |
51 | * NOTE: that the do_fork and sys_open tests are mutually exclusive. | 52 | * NOTE: that the do_fork and sys_open tests are mutually exclusive. |
52 | * | 53 | * |
@@ -375,7 +376,7 @@ static void emul_sstep_get(char *arg) | |||
375 | break; | 376 | break; |
376 | case 1: | 377 | case 1: |
377 | /* set breakpoint */ | 378 | /* set breakpoint */ |
378 | break_helper("Z0", 0, sstep_addr); | 379 | break_helper("Z0", NULL, sstep_addr); |
379 | break; | 380 | break; |
380 | case 2: | 381 | case 2: |
381 | /* Continue */ | 382 | /* Continue */ |
@@ -383,7 +384,7 @@ static void emul_sstep_get(char *arg) | |||
383 | break; | 384 | break; |
384 | case 3: | 385 | case 3: |
385 | /* Clear breakpoint */ | 386 | /* Clear breakpoint */ |
386 | break_helper("z0", 0, sstep_addr); | 387 | break_helper("z0", NULL, sstep_addr); |
387 | break; | 388 | break; |
388 | default: | 389 | default: |
389 | eprintk("kgdbts: ERROR failed sstep get emulation\n"); | 390 | eprintk("kgdbts: ERROR failed sstep get emulation\n"); |
@@ -465,11 +466,11 @@ static struct test_struct sw_breakpoint_test[] = { | |||
465 | { "?", "S0*" }, /* Clear break points */ | 466 | { "?", "S0*" }, /* Clear break points */ |
466 | { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ | 467 | { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ |
467 | { "c", "T0*", }, /* Continue */ | 468 | { "c", "T0*", }, /* Continue */ |
468 | { "g", "kgdbts_break_test", 0, check_and_rewind_pc }, | 469 | { "g", "kgdbts_break_test", NULL, check_and_rewind_pc }, |
469 | { "write", "OK", write_regs }, | 470 | { "write", "OK", write_regs }, |
470 | { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */ | 471 | { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */ |
471 | { "D", "OK" }, /* Detach */ | 472 | { "D", "OK" }, /* Detach */ |
472 | { "D", "OK", 0, got_break }, /* If the test worked we made it here */ | 473 | { "D", "OK", NULL, got_break }, /* On success we made it here */ |
473 | { "", "" }, | 474 | { "", "" }, |
474 | }; | 475 | }; |
475 | 476 | ||
@@ -499,14 +500,14 @@ static struct test_struct singlestep_break_test[] = { | |||
499 | { "?", "S0*" }, /* Clear break points */ | 500 | { "?", "S0*" }, /* Clear break points */ |
500 | { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ | 501 | { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ |
501 | { "c", "T0*", }, /* Continue */ | 502 | { "c", "T0*", }, /* Continue */ |
502 | { "g", "kgdbts_break_test", 0, check_and_rewind_pc }, | 503 | { "g", "kgdbts_break_test", NULL, check_and_rewind_pc }, |
503 | { "write", "OK", write_regs }, /* Write registers */ | 504 | { "write", "OK", write_regs }, /* Write registers */ |
504 | { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */ | 505 | { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */ |
505 | { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ | 506 | { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ |
506 | { "g", "kgdbts_break_test", 0, check_single_step }, | 507 | { "g", "kgdbts_break_test", NULL, check_single_step }, |
507 | { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ | 508 | { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ |
508 | { "c", "T0*", }, /* Continue */ | 509 | { "c", "T0*", }, /* Continue */ |
509 | { "g", "kgdbts_break_test", 0, check_and_rewind_pc }, | 510 | { "g", "kgdbts_break_test", NULL, check_and_rewind_pc }, |
510 | { "write", "OK", write_regs }, /* Write registers */ | 511 | { "write", "OK", write_regs }, /* Write registers */ |
511 | { "D", "OK" }, /* Remove all breakpoints and continues */ | 512 | { "D", "OK" }, /* Remove all breakpoints and continues */ |
512 | { "", "" }, | 513 | { "", "" }, |
@@ -520,14 +521,14 @@ static struct test_struct do_fork_test[] = { | |||
520 | { "?", "S0*" }, /* Clear break points */ | 521 | { "?", "S0*" }, /* Clear break points */ |
521 | { "do_fork", "OK", sw_break, }, /* set sw breakpoint */ | 522 | { "do_fork", "OK", sw_break, }, /* set sw breakpoint */ |
522 | { "c", "T0*", }, /* Continue */ | 523 | { "c", "T0*", }, /* Continue */ |
523 | { "g", "do_fork", 0, check_and_rewind_pc }, /* check location */ | 524 | { "g", "do_fork", NULL, check_and_rewind_pc }, /* check location */ |
524 | { "write", "OK", write_regs }, /* Write registers */ | 525 | { "write", "OK", write_regs }, /* Write registers */ |
525 | { "do_fork", "OK", sw_rem_break }, /*remove breakpoint */ | 526 | { "do_fork", "OK", sw_rem_break }, /*remove breakpoint */ |
526 | { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ | 527 | { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ |
527 | { "g", "do_fork", 0, check_single_step }, | 528 | { "g", "do_fork", NULL, check_single_step }, |
528 | { "do_fork", "OK", sw_break, }, /* set sw breakpoint */ | 529 | { "do_fork", "OK", sw_break, }, /* set sw breakpoint */ |
529 | { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */ | 530 | { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */ |
530 | { "D", "OK", 0, final_ack_set }, /* detach and unregister I/O */ | 531 | { "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */ |
531 | { "", "" }, | 532 | { "", "" }, |
532 | }; | 533 | }; |
533 | 534 | ||
@@ -538,14 +539,14 @@ static struct test_struct sys_open_test[] = { | |||
538 | { "?", "S0*" }, /* Clear break points */ | 539 | { "?", "S0*" }, /* Clear break points */ |
539 | { "sys_open", "OK", sw_break, }, /* set sw breakpoint */ | 540 | { "sys_open", "OK", sw_break, }, /* set sw breakpoint */ |
540 | { "c", "T0*", }, /* Continue */ | 541 | { "c", "T0*", }, /* Continue */ |
541 | { "g", "sys_open", 0, check_and_rewind_pc }, /* check location */ | 542 | { "g", "sys_open", NULL, check_and_rewind_pc }, /* check location */ |
542 | { "write", "OK", write_regs }, /* Write registers */ | 543 | { "write", "OK", write_regs }, /* Write registers */ |
543 | { "sys_open", "OK", sw_rem_break }, /*remove breakpoint */ | 544 | { "sys_open", "OK", sw_rem_break }, /*remove breakpoint */ |
544 | { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ | 545 | { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ |
545 | { "g", "sys_open", 0, check_single_step }, | 546 | { "g", "sys_open", NULL, check_single_step }, |
546 | { "sys_open", "OK", sw_break, }, /* set sw breakpoint */ | 547 | { "sys_open", "OK", sw_break, }, /* set sw breakpoint */ |
547 | { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */ | 548 | { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */ |
548 | { "D", "OK", 0, final_ack_set }, /* detach and unregister I/O */ | 549 | { "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */ |
549 | { "", "" }, | 550 | { "", "" }, |
550 | }; | 551 | }; |
551 | 552 | ||
@@ -556,11 +557,11 @@ static struct test_struct hw_breakpoint_test[] = { | |||
556 | { "?", "S0*" }, /* Clear break points */ | 557 | { "?", "S0*" }, /* Clear break points */ |
557 | { "kgdbts_break_test", "OK", hw_break, }, /* set hw breakpoint */ | 558 | { "kgdbts_break_test", "OK", hw_break, }, /* set hw breakpoint */ |
558 | { "c", "T0*", }, /* Continue */ | 559 | { "c", "T0*", }, /* Continue */ |
559 | { "g", "kgdbts_break_test", 0, check_and_rewind_pc }, | 560 | { "g", "kgdbts_break_test", NULL, check_and_rewind_pc }, |
560 | { "write", "OK", write_regs }, | 561 | { "write", "OK", write_regs }, |
561 | { "kgdbts_break_test", "OK", hw_rem_break }, /*remove breakpoint */ | 562 | { "kgdbts_break_test", "OK", hw_rem_break }, /*remove breakpoint */ |
562 | { "D", "OK" }, /* Detach */ | 563 | { "D", "OK" }, /* Detach */ |
563 | { "D", "OK", 0, got_break }, /* If the test worked we made it here */ | 564 | { "D", "OK", NULL, got_break }, /* On success we made it here */ |
564 | { "", "" }, | 565 | { "", "" }, |
565 | }; | 566 | }; |
566 | 567 | ||
@@ -570,12 +571,12 @@ static struct test_struct hw_breakpoint_test[] = { | |||
570 | static struct test_struct hw_write_break_test[] = { | 571 | static struct test_struct hw_write_break_test[] = { |
571 | { "?", "S0*" }, /* Clear break points */ | 572 | { "?", "S0*" }, /* Clear break points */ |
572 | { "hw_break_val", "OK", hw_write_break, }, /* set hw breakpoint */ | 573 | { "hw_break_val", "OK", hw_write_break, }, /* set hw breakpoint */ |
573 | { "c", "T0*", 0, got_break }, /* Continue */ | 574 | { "c", "T0*", NULL, got_break }, /* Continue */ |
574 | { "g", "silent", 0, check_and_rewind_pc }, | 575 | { "g", "silent", NULL, check_and_rewind_pc }, |
575 | { "write", "OK", write_regs }, | 576 | { "write", "OK", write_regs }, |
576 | { "hw_break_val", "OK", hw_rem_write_break }, /*remove breakpoint */ | 577 | { "hw_break_val", "OK", hw_rem_write_break }, /*remove breakpoint */ |
577 | { "D", "OK" }, /* Detach */ | 578 | { "D", "OK" }, /* Detach */ |
578 | { "D", "OK", 0, got_break }, /* If the test worked we made it here */ | 579 | { "D", "OK", NULL, got_break }, /* On success we made it here */ |
579 | { "", "" }, | 580 | { "", "" }, |
580 | }; | 581 | }; |
581 | 582 | ||
@@ -585,12 +586,12 @@ static struct test_struct hw_write_break_test[] = { | |||
585 | static struct test_struct hw_access_break_test[] = { | 586 | static struct test_struct hw_access_break_test[] = { |
586 | { "?", "S0*" }, /* Clear break points */ | 587 | { "?", "S0*" }, /* Clear break points */ |
587 | { "hw_break_val", "OK", hw_access_break, }, /* set hw breakpoint */ | 588 | { "hw_break_val", "OK", hw_access_break, }, /* set hw breakpoint */ |
588 | { "c", "T0*", 0, got_break }, /* Continue */ | 589 | { "c", "T0*", NULL, got_break }, /* Continue */ |
589 | { "g", "silent", 0, check_and_rewind_pc }, | 590 | { "g", "silent", NULL, check_and_rewind_pc }, |
590 | { "write", "OK", write_regs }, | 591 | { "write", "OK", write_regs }, |
591 | { "hw_break_val", "OK", hw_rem_access_break }, /*remove breakpoint */ | 592 | { "hw_break_val", "OK", hw_rem_access_break }, /*remove breakpoint */ |
592 | { "D", "OK" }, /* Detach */ | 593 | { "D", "OK" }, /* Detach */ |
593 | { "D", "OK", 0, got_break }, /* If the test worked we made it here */ | 594 | { "D", "OK", NULL, got_break }, /* On success we made it here */ |
594 | { "", "" }, | 595 | { "", "" }, |
595 | }; | 596 | }; |
596 | 597 | ||
@@ -599,9 +600,9 @@ static struct test_struct hw_access_break_test[] = { | |||
599 | */ | 600 | */ |
600 | static struct test_struct nmi_sleep_test[] = { | 601 | static struct test_struct nmi_sleep_test[] = { |
601 | { "?", "S0*" }, /* Clear break points */ | 602 | { "?", "S0*" }, /* Clear break points */ |
602 | { "c", "T0*", 0, got_break }, /* Continue */ | 603 | { "c", "T0*", NULL, got_break }, /* Continue */ |
603 | { "D", "OK" }, /* Detach */ | 604 | { "D", "OK" }, /* Detach */ |
604 | { "D", "OK", 0, got_break }, /* If the test worked we made it here */ | 605 | { "D", "OK", NULL, got_break }, /* On success we made it here */ |
605 | { "", "" }, | 606 | { "", "" }, |
606 | }; | 607 | }; |
607 | 608 | ||
@@ -874,18 +875,23 @@ static void kgdbts_run_tests(void) | |||
874 | { | 875 | { |
875 | char *ptr; | 876 | char *ptr; |
876 | int fork_test = 0; | 877 | int fork_test = 0; |
877 | int sys_open_test = 0; | 878 | int do_sys_open_test = 0; |
879 | int sstep_test = 1000; | ||
878 | int nmi_sleep = 0; | 880 | int nmi_sleep = 0; |
881 | int i; | ||
879 | 882 | ||
880 | ptr = strstr(config, "F"); | 883 | ptr = strstr(config, "F"); |
881 | if (ptr) | 884 | if (ptr) |
882 | fork_test = simple_strtol(ptr+1, NULL, 10); | 885 | fork_test = simple_strtol(ptr + 1, NULL, 10); |
883 | ptr = strstr(config, "S"); | 886 | ptr = strstr(config, "S"); |
884 | if (ptr) | 887 | if (ptr) |
885 | sys_open_test = simple_strtol(ptr+1, NULL, 10); | 888 | do_sys_open_test = simple_strtol(ptr + 1, NULL, 10); |
886 | ptr = strstr(config, "N"); | 889 | ptr = strstr(config, "N"); |
887 | if (ptr) | 890 | if (ptr) |
888 | nmi_sleep = simple_strtol(ptr+1, NULL, 10); | 891 | nmi_sleep = simple_strtol(ptr+1, NULL, 10); |
892 | ptr = strstr(config, "I"); | ||
893 | if (ptr) | ||
894 | sstep_test = simple_strtol(ptr+1, NULL, 10); | ||
889 | 895 | ||
890 | /* required internal KGDB tests */ | 896 | /* required internal KGDB tests */ |
891 | v1printk("kgdbts:RUN plant and detach test\n"); | 897 | v1printk("kgdbts:RUN plant and detach test\n"); |
@@ -894,8 +900,13 @@ static void kgdbts_run_tests(void) | |||
894 | run_breakpoint_test(0); | 900 | run_breakpoint_test(0); |
895 | v1printk("kgdbts:RUN bad memory access test\n"); | 901 | v1printk("kgdbts:RUN bad memory access test\n"); |
896 | run_bad_read_test(); | 902 | run_bad_read_test(); |
897 | v1printk("kgdbts:RUN singlestep breakpoint test\n"); | 903 | v1printk("kgdbts:RUN singlestep test %i iterations\n", sstep_test); |
898 | run_singlestep_break_test(); | 904 | for (i = 0; i < sstep_test; i++) { |
905 | run_singlestep_break_test(); | ||
906 | if (i % 100 == 0) | ||
907 | v1printk("kgdbts:RUN singlestep [%i/%i]\n", | ||
908 | i, sstep_test); | ||
909 | } | ||
899 | 910 | ||
900 | /* ===Optional tests=== */ | 911 | /* ===Optional tests=== */ |
901 | 912 | ||
@@ -922,7 +933,7 @@ static void kgdbts_run_tests(void) | |||
922 | repeat_test = fork_test; | 933 | repeat_test = fork_test; |
923 | printk(KERN_INFO "kgdbts:RUN do_fork for %i breakpoints\n", | 934 | printk(KERN_INFO "kgdbts:RUN do_fork for %i breakpoints\n", |
924 | repeat_test); | 935 | repeat_test); |
925 | kthread_run(kgdbts_unreg_thread, 0, "kgdbts_unreg"); | 936 | kthread_run(kgdbts_unreg_thread, NULL, "kgdbts_unreg"); |
926 | run_do_fork_test(); | 937 | run_do_fork_test(); |
927 | return; | 938 | return; |
928 | } | 939 | } |
@@ -931,11 +942,11 @@ static void kgdbts_run_tests(void) | |||
931 | * executed because a kernel thread will be spawned at the very | 942 | * executed because a kernel thread will be spawned at the very |
932 | * end to unregister the debug hooks. | 943 | * end to unregister the debug hooks. |
933 | */ | 944 | */ |
934 | if (sys_open_test) { | 945 | if (do_sys_open_test) { |
935 | repeat_test = sys_open_test; | 946 | repeat_test = do_sys_open_test; |
936 | printk(KERN_INFO "kgdbts:RUN sys_open for %i breakpoints\n", | 947 | printk(KERN_INFO "kgdbts:RUN sys_open for %i breakpoints\n", |
937 | repeat_test); | 948 | repeat_test); |
938 | kthread_run(kgdbts_unreg_thread, 0, "kgdbts_unreg"); | 949 | kthread_run(kgdbts_unreg_thread, NULL, "kgdbts_unreg"); |
939 | run_sys_open_test(); | 950 | run_sys_open_test(); |
940 | return; | 951 | return; |
941 | } | 952 | } |