Pull kgdb updates from Daniel Thompson: "Changes for kgdb/kdb this cycle are dominated by a change from Sumit that removes as small (256K) private heap from kdb. This is change I've hoped for ever since I discovered how few users of this heap remained in the kernel, so many thanks to Sumit for hunting these down. The other change is an incremental step towards SPDX headers" * tag 'kgdb-5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/danielt/linux: kernel: debug: Convert to SPDX identifier kdb: Rename members of struct kdbtab_t kdb: Simplify kdb_defcmd macro logic kdb: Get rid of redundant kdb_register_flags() kdb: Rename struct defcmd_set to struct kdb_macro kdb: Get rid of custom debug heap allocator
Unified · Split
| @@ -13,6 +13,8 @@ · 12 unmodified lines | |||
| 13 | * Copyright (C) 2009 Jason Wessel <jason.wessel@windriver.com> | 13 | * Copyright (C) 2009 Jason Wessel <jason.wessel@windriver.com> |
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #include <linux/list.h> | ||
| 17 | |||
| 16 | /* Shifted versions of the command enable bits are be used if the command | 18 | /* Shifted versions of the command enable bits are be used if the command |
| 17 | * has no arguments (see kdb_check_flags). This allows commands, such as | 19 | * has no arguments (see kdb_check_flags). This allows commands, such as |
| 18 | * go, to have different permissions depending upon whether it is called | 20 | * go, to have different permissions depending upon whether it is called |
| @@ -64,6 +66,17 @@ typedef enum { · 45 unmodified lines | |||
| 64 | 66 | ||
| 65 | typedef int (*kdb_func_t)(int, const char **); | 67 | typedef int (*kdb_func_t)(int, const char **); |
| 66 | 68 | ||
| 69 | /* The KDB shell command table */ | ||
| 70 | typedef struct _kdbtab { | ||
| 71 | char *name; /* Command name */ | ||
| 72 | kdb_func_t func; /* Function to execute command */ | ||
| 73 | char *usage; /* Usage String for this command */ | ||
| 74 | char *help; /* Help message for this command */ | ||
| 75 | short minlen; /* Minimum legal # cmd chars required */ | ||
| 76 | kdb_cmdflags_t flags; /* Command behaviour flags */ | ||
| 77 | struct list_head list_node; /* Command list */ | ||
| 78 | } kdbtab_t; | ||
| 79 | |||
| 67 | #ifdef CONFIG_KGDB_KDB | 80 | #ifdef CONFIG_KGDB_KDB |
| 68 | #include <linux/init.h> | 81 | #include <linux/init.h> |
| 69 | #include <linux/sched.h> | 82 | #include <linux/sched.h> |
| @@ -193,19 +206,13 @@ static inline const char *kdb_walk_kallsyms(loff_t *pos) · 123 unmodified lines | |||
| 193 | #endif /* ! CONFIG_KALLSYMS */ | 206 | #endif /* ! CONFIG_KALLSYMS */ |
| 194 | 207 | ||
| 195 | /* Dynamic kdb shell command registration */ | 208 | /* Dynamic kdb shell command registration */ |
| 196 | extern int kdb_register(char *, kdb_func_t, char *, char *, short); | 209 | extern int kdb_register(kdbtab_t *cmd); |
| 197 | extern int kdb_register_flags(char *, kdb_func_t, char *, char *, | 210 | extern void kdb_unregister(kdbtab_t *cmd); |
| 198 | short, kdb_cmdflags_t); | ||
| 199 | extern int kdb_unregister(char *); | ||
| 200 | #else /* ! CONFIG_KGDB_KDB */ | 211 | #else /* ! CONFIG_KGDB_KDB */ |
| 201 | static inline __printf(1, 2) int kdb_printf(const char *fmt, ...) { return 0; } | 212 | static inline __printf(1, 2) int kdb_printf(const char *fmt, ...) { return 0; } |
| 202 | static inline void kdb_init(int level) {} | 213 | static inline void kdb_init(int level) {} |
| 203 | static inline int kdb_register(char *cmd, kdb_func_t func, char *usage, | 214 | static inline int kdb_register(kdbtab_t *cmd) { return 0; } |
| 204 | char *help, short minlen) { return 0; } | 215 | static inline void kdb_unregister(kdbtab_t *cmd) {} |
| 205 | static inline int kdb_register_flags(char *cmd, kdb_func_t func, char *usage, | ||
| 206 | char *help, short minlen, | ||
| 207 | kdb_cmdflags_t flags) { return 0; } | ||
| 208 | static inline int kdb_unregister(char *cmd) { return 0; } | ||
| 209 | #endif /* CONFIG_KGDB_KDB */ | 216 | #endif /* CONFIG_KGDB_KDB */ |
| 210 | enum { | 217 | enum { |
| 211 | KDB_NOT_INITIALIZED, | 218 | KDB_NOT_INITIALIZED, |
| @@ -1,3 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 1 | /* | 2 | /* |
| 2 | * Kernel Debug Core | 3 | * Kernel Debug Core |
| 3 | * | 4 | * |
| @@ -22,10 +23,6 @@ · 18 unmodified lines | |||
| 22 | * | 23 | * |
| 23 | * Original KGDB stub: David Grothe <dave@gcom.com>, | 24 | * Original KGDB stub: David Grothe <dave@gcom.com>, |
| 24 | * Tigran Aivazian <tigran@sco.com> | 25 | * Tigran Aivazian <tigran@sco.com> |
| 25 | * | ||
| 26 | * This file is licensed under the terms of the GNU General Public License | ||
| 27 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 28 | * kind, whether express or implied. | ||
| 29 | */ | 26 | */ |
| 30 | 27 | ||
| 31 | #define pr_fmt(fmt) "KGDB: " fmt | 28 | #define pr_fmt(fmt) "KGDB: " fmt |
| @@ -1,3 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 1 | /* | 2 | /* |
| 2 | * Kernel Debug Core | 3 | * Kernel Debug Core |
| 3 | * | 4 | * |
| @@ -22,10 +23,6 @@ · 18 unmodified lines | |||
| 22 | * | 23 | * |
| 23 | * Original KGDB stub: David Grothe <dave@gcom.com>, | 24 | * Original KGDB stub: David Grothe <dave@gcom.com>, |
| 24 | * Tigran Aivazian <tigran@sco.com> | 25 | * Tigran Aivazian <tigran@sco.com> |
| 25 | * | ||
| 26 | * This file is licensed under the terms of the GNU General Public License | ||
| 27 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 28 | * kind, whether express or implied. | ||
| 29 | */ | 26 | */ |
| 30 | 27 | ||
| 31 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
| @@ -523,51 +523,51 @@ static int kdb_ss(int argc, const char **argv) · 522 unmodified lines | |||
| 523 | } | 523 | } |
| 524 | 524 | ||
| 525 | static kdbtab_t bptab[] = { | 525 | static kdbtab_t bptab[] = { |
| 526 | { .cmd_name = "bp", | 526 | { .name = "bp", |
| 527 | .cmd_func = kdb_bp, | 527 | .func = kdb_bp, |
| 528 | .cmd_usage = "[<vaddr>]", | 528 | .usage = "[<vaddr>]", |
| 529 | .cmd_help = "Set/Display breakpoints", | 529 | .help = "Set/Display breakpoints", |
| 530 | .cmd_flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS, | 530 | .flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS, |
| 531 | }, | 531 | }, |
| 532 | { .cmd_name = "bl", | 532 | { .name = "bl", |
| 533 | .cmd_func = kdb_bp, | 533 | .func = kdb_bp, |
| 534 | .cmd_usage = "[<vaddr>]", | 534 | .usage = "[<vaddr>]", |
| 535 | .cmd_help = "Display breakpoints", | 535 | .help = "Display breakpoints", |
| 536 | .cmd_flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS, | 536 | .flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS, |
| 537 | }, | 537 | }, |
| 538 | { .cmd_name = "bc", | 538 | { .name = "bc", |
| 539 | .cmd_func = kdb_bc, | 539 | .func = kdb_bc, |
| 540 | .cmd_usage = "<bpnum>", | 540 | .usage = "<bpnum>", |
| 541 | .cmd_help = "Clear Breakpoint", | 541 | .help = "Clear Breakpoint", |
| 542 | .cmd_flags = KDB_ENABLE_FLOW_CTRL, | 542 | .flags = KDB_ENABLE_FLOW_CTRL, |
| 543 | }, | 543 | }, |
| 544 | { .cmd_name = "be", | 544 | { .name = "be", |
| 545 | .cmd_func = kdb_bc, | 545 | .func = kdb_bc, |
| 546 | .cmd_usage = "<bpnum>", | 546 | .usage = "<bpnum>", |
| 547 | .cmd_help = "Enable Breakpoint", | 547 | .help = "Enable Breakpoint", |
| 548 | .cmd_flags = KDB_ENABLE_FLOW_CTRL, | 548 | .flags = KDB_ENABLE_FLOW_CTRL, |
| 549 | }, | 549 | }, |
| 550 | { .cmd_name = "bd", | 550 | { .name = "bd", |
| 551 | .cmd_func = kdb_bc, | 551 | .func = kdb_bc, |
| 552 | .cmd_usage = "<bpnum>", | 552 | .usage = "<bpnum>", |
| 553 | .cmd_help = "Disable Breakpoint", | 553 | .help = "Disable Breakpoint", |
| 554 | .cmd_flags = KDB_ENABLE_FLOW_CTRL, | 554 | .flags = KDB_ENABLE_FLOW_CTRL, |
| 555 | }, | 555 | }, |
| 556 | { .cmd_name = "ss", | 556 | { .name = "ss", |
| 557 | .cmd_func = kdb_ss, | 557 | .func = kdb_ss, |
| 558 | .cmd_usage = "", | 558 | .usage = "", |
| 559 | .cmd_help = "Single Step", | 559 | .help = "Single Step", |
| 560 | .cmd_minlen = 1, | 560 | .minlen = 1, |
| 561 | .cmd_flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS, | 561 | .flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS, |
| 562 | }, | 562 | }, |
| 563 | }; | 563 | }; |
| 564 | 564 | ||
| 565 | static kdbtab_t bphcmd = { | 565 | static kdbtab_t bphcmd = { |
| 566 | .cmd_name = "bph", | 566 | .name = "bph", |
| 567 | .cmd_func = kdb_bp, | 567 | .func = kdb_bp, |
| 568 | .cmd_usage = "[<vaddr>]", | 568 | .usage = "[<vaddr>]", |
| 569 | .cmd_help = "[datar [length]|dataw [length]] Set hw brk", | 569 | .help = "[datar [length]|dataw [length]] Set hw brk", |
| 570 | .cmd_flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS, | 570 | .flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS, |
| 571 | }; | 571 | }; |
| 572 | 572 | ||
| 573 | /* Initialize the breakpoint table and register breakpoint commands. */ | 573 | /* Initialize the breakpoint table and register breakpoint commands. */ |
| @@ -140,7 +140,6 @@ int kdb_stub(struct kgdb_state *ks) · 139 unmodified lines | |||
| 140 | */ | 140 | */ |
| 141 | kdb_common_deinit_state(); | 141 | kdb_common_deinit_state(); |
| 142 | KDB_STATE_CLEAR(PAGER); | 142 | KDB_STATE_CLEAR(PAGER); |
| 143 | kdbnearsym_cleanup(); | ||
| 144 | if (error == KDB_CMD_KGDB) { | 143 | if (error == KDB_CMD_KGDB) { |
| 145 | if (KDB_STATE(DOING_KGDB)) | 144 | if (KDB_STATE(DOING_KGDB)) |
| 146 | KDB_STATE_CLEAR(DOING_KGDB); | 145 | KDB_STATE_CLEAR(DOING_KGDB); |
| @@ -33,7 +33,6 @@ · 32 unmodified lines | |||
| 33 | #include <linux/kallsyms.h> | 33 | #include <linux/kallsyms.h> |
| 34 | #include <linux/kgdb.h> | 34 | #include <linux/kgdb.h> |
| 35 | #include <linux/kdb.h> | 35 | #include <linux/kdb.h> |
| 36 | #include <linux/list.h> | ||
| 37 | #include <linux/notifier.h> | 36 | #include <linux/notifier.h> |
| 38 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
| 39 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
| @@ -654,16 +653,17 @@ static void kdb_cmderror(int diag) · 614 unmodified lines | |||
| 654 | * Returns: | 653 | * Returns: |
| 655 | * zero for success, a kdb diagnostic if error | 654 | * zero for success, a kdb diagnostic if error |
| 656 | */ | 655 | */ |
| 657 | struct defcmd_set { | 656 | struct kdb_macro { |
| 658 | int count; | 657 | kdbtab_t cmd; /* Macro command */ |
| 659 | bool usable; | 658 | struct list_head statements; /* Associated statement list */ |
| 660 | char *name; | ||
| 661 | char *usage; | ||
| 662 | char *help; | ||
| 663 | char **command; | ||
| 664 | }; | 659 | }; |
| 665 | static struct defcmd_set *defcmd_set; | 660 | |
| 666 | static int defcmd_set_count; | 661 | struct kdb_macro_statement { |
| 662 | char *statement; /* Statement text */ | ||
| 663 | struct list_head list_node; /* Statement list node */ | ||
| 664 | }; | ||
| 665 | |||
| 666 | static struct kdb_macro *kdb_macro; | ||
| 667 | static bool defcmd_in_progress; | 667 | static bool defcmd_in_progress; |
| 668 | 668 | ||
| 669 | /* Forward references */ | 669 | /* Forward references */ |
| @@ -671,53 +671,55 @@ static int kdb_exec_defcmd(int argc, const char **argv); · 1 unmodified line | |||
| 671 | 671 | ||
| 672 | static int kdb_defcmd2(const char *cmdstr, const char *argv0) | 672 | static int kdb_defcmd2(const char *cmdstr, const char *argv0) |
| 673 | { | 673 | { |
| 674 | struct defcmd_set *s = defcmd_set + defcmd_set_count - 1; | 674 | struct kdb_macro_statement *kms; |
| 675 | char **save_command = s->command; | 675 | |
| 676 | if (!kdb_macro) | ||
| 677 | return KDB_NOTIMP; | ||
| 678 | |||
| 676 | if (strcmp(argv0, "endefcmd") == 0) { | 679 | if (strcmp(argv0, "endefcmd") == 0) { |
| 677 | defcmd_in_progress = false; | 680 | defcmd_in_progress = false; |
| 678 | if (!s->count) | 681 | if (!list_empty(&kdb_macro->statements)) |
| 679 | s->usable = false; | 682 | kdb_register(&kdb_macro->cmd); |
| 680 | if (s->usable) | ||
| 681 | /* macros are always safe because when executed each | ||
| 682 | * internal command re-enters kdb_parse() and is | ||
| 683 | * safety checked individually. | ||
| 684 | */ | ||
| 685 | kdb_register_flags(s->name, kdb_exec_defcmd, s->usage, | ||
| 686 | s->help, 0, | ||
| 687 | KDB_ENABLE_ALWAYS_SAFE); | ||
| 688 | return 0; | 683 | return 0; |
| 689 | } | 684 | } |
| 690 | if (!s->usable) | 685 | |
| 691 | return KDB_NOTIMP; | 686 | kms = kmalloc(sizeof(*kms), GFP_KDB); |
| 692 | s->command = kcalloc(s->count + 1, sizeof(*(s->command)), GFP_KDB); | 687 | if (!kms) { |
| 693 | if (!s->command) { | 688 | kdb_printf("Could not allocate new kdb macro command: %s\n", |
| 694 | kdb_printf("Could not allocate new kdb_defcmd table for %s\n", | ||
| 695 | cmdstr); | 689 | cmdstr); |
| 696 | s->usable = false; | ||
| 697 | return KDB_NOTIMP; | 690 | return KDB_NOTIMP; |
| 698 | } | 691 | } |
| 699 | memcpy(s->command, save_command, s->count * sizeof(*(s->command))); | 692 | |
| 700 | s->command[s->count++] = kdb_strdup(cmdstr, GFP_KDB); | 693 | kms->statement = kdb_strdup(cmdstr, GFP_KDB); |
| 701 | kfree(save_command); | 694 | list_add_tail(&kms->list_node, &kdb_macro->statements); |
| 695 | |||
| 702 | return 0; | 696 | return 0; |
| 703 | } | 697 | } |
| 704 | 698 | ||
| 705 | static int kdb_defcmd(int argc, const char **argv) | 699 | static int kdb_defcmd(int argc, const char **argv) |
| 706 | { | 700 | { |
| 707 | struct defcmd_set *save_defcmd_set = defcmd_set, *s; | 701 | kdbtab_t *mp; |
| 702 | |||
| 708 | if (defcmd_in_progress) { | 703 | if (defcmd_in_progress) { |
| 709 | kdb_printf("kdb: nested defcmd detected, assuming missing " | 704 | kdb_printf("kdb: nested defcmd detected, assuming missing " |
| 710 | "endefcmd\n"); | 705 | "endefcmd\n"); |
| 711 | kdb_defcmd2("endefcmd", "endefcmd"); | 706 | kdb_defcmd2("endefcmd", "endefcmd"); |
| 712 | } | 707 | } |
| 713 | if (argc == 0) { | 708 | if (argc == 0) { |
| 714 | int i; | 709 | kdbtab_t *kp; |
| 715 | for (s = defcmd_set; s < defcmd_set + defcmd_set_count; ++s) { | 710 | struct kdb_macro *kmp; |
| 716 | kdb_printf("defcmd %s \"%s\" \"%s\"\n", s->name, | 711 | struct kdb_macro_statement *kms; |
| 717 | s->usage, s->help); | 712 | |
| 718 | for (i = 0; i < s->count; ++i) | 713 | list_for_each_entry(kp, &kdb_cmds_head, list_node) { |
| 719 | kdb_printf("%s", s->command[i]); | 714 | if (kp->func == kdb_exec_defcmd) { |
| 720 | kdb_printf("endefcmd\n"); | 715 | kdb_printf("defcmd %s \"%s\" \"%s\"\n", |
| 716 | kp->name, kp->usage, kp->help); | ||
| 717 | kmp = container_of(kp, struct kdb_macro, cmd); | ||
| 718 | list_for_each_entry(kms, &kmp->statements, | ||
| 719 | list_node) | ||
| 720 | kdb_printf("%s", kms->statement); | ||
| 721 | kdb_printf("endefcmd\n"); | ||
| 722 | } | ||
| 721 | } | 723 | } |
| 722 | return 0; | 724 | return 0; |
| 723 | } | 725 | } |
| @@ -727,45 +729,43 @@ static int kdb_defcmd(int argc, const char **argv) · 3 unmodified lines | |||
| 727 | kdb_printf("Command only available during kdb_init()\n"); | 729 | kdb_printf("Command only available during kdb_init()\n"); |
| 728 | return KDB_NOTIMP; | 730 | return KDB_NOTIMP; |
| 729 | } | 731 | } |
| 730 | defcmd_set = kmalloc_array(defcmd_set_count + 1, sizeof(*defcmd_set), | 732 | kdb_macro = kzalloc(sizeof(*kdb_macro), GFP_KDB); |
| 731 | GFP_KDB); | 733 | if (!kdb_macro) |
| 732 | if (!defcmd_set) | ||
| 733 | goto fail_defcmd; | 734 | goto fail_defcmd; |
| 734 | memcpy(defcmd_set, save_defcmd_set, | 735 | |
| 735 | defcmd_set_count * sizeof(*defcmd_set)); | 736 | mp = &kdb_macro->cmd; |
| 736 | s = defcmd_set + defcmd_set_count; | 737 | mp->func = kdb_exec_defcmd; |
| 737 | memset(s, 0, sizeof(*s)); | 738 | mp->minlen = 0; |
| 738 | s->usable = true; | 739 | mp->flags = KDB_ENABLE_ALWAYS_SAFE; |
| 739 | s->name = kdb_strdup(argv[1], GFP_KDB); | 740 | mp->name = kdb_strdup(argv[1], GFP_KDB); |
| 740 | if (!s->name) | 741 | if (!mp->name) |
| 741 | goto fail_name; | 742 | goto fail_name; |
| 742 | s->usage = kdb_strdup(argv[2], GFP_KDB); | 743 | mp->usage = kdb_strdup(argv[2], GFP_KDB); |
| 743 | if (!s->usage) | 744 | if (!mp->usage) |
| 744 | goto fail_usage; | 745 | goto fail_usage; |
| 745 | s->help = kdb_strdup(argv[3], GFP_KDB); | 746 | mp->help = kdb_strdup(argv[3], GFP_KDB); |
| 746 | if (!s->help) | 747 | if (!mp->help) |
| 747 | goto fail_help; | 748 | goto fail_help; |
| 748 | if (s->usage[0] == '"') { | 749 | if (mp->usage[0] == '"') { |
| 749 | strcpy(s->usage, argv[2]+1); | 750 | strcpy(mp->usage, argv[2]+1); |
| 750 | s->usage[strlen(s->usage)-1] = '\0'; | 751 | mp->usage[strlen(mp->usage)-1] = '\0'; |
| 751 | } | 752 | } |
| 752 | if (s->help[0] == '"') { | 753 | if (mp->help[0] == '"') { |
| 753 | strcpy(s->help, argv[3]+1); | 754 | strcpy(mp->help, argv[3]+1); |
| 754 | s->help[strlen(s->help)-1] = '\0'; | 755 | mp->help[strlen(mp->help)-1] = '\0'; |
| 755 | } | 756 | } |
| 756 | ++defcmd_set_count; | 757 | |
| 758 | INIT_LIST_HEAD(&kdb_macro->statements); | ||
| 757 | defcmd_in_progress = true; | 759 | defcmd_in_progress = true; |
| 758 | kfree(save_defcmd_set); | ||
| 759 | return 0; | 760 | return 0; |
| 760 | fail_help: | 761 | fail_help: |
| 761 | kfree(s->usage); | 762 | kfree(mp->usage); |
| 762 | fail_usage: | 763 | fail_usage: |
| 763 | kfree(s->name); | 764 | kfree(mp->name); |
| 764 | fail_name: | 765 | fail_name: |
| 765 | kfree(defcmd_set); | 766 | kfree(kdb_macro); |
| 766 | fail_defcmd: | 767 | fail_defcmd: |
| 767 | kdb_printf("Could not allocate new defcmd_set entry for %s\n", argv[1]); | 768 | kdb_printf("Could not allocate new kdb_macro entry for %s\n", argv[1]); |
| 768 | defcmd_set = save_defcmd_set; | ||
| 769 | return KDB_NOTIMP; | 769 | return KDB_NOTIMP; |
| 770 | } | 770 | } |
| 771 | 771 | ||
| @@ -780,25 +780,31 @@ fail_defcmd: · 8 unmodified lines | |||
| 780 | */ | 780 | */ |
| 781 | static int kdb_exec_defcmd(int argc, const char **argv) | 781 | static int kdb_exec_defcmd(int argc, const char **argv) |
| 782 | { | 782 | { |
| 783 | int i, ret; | 783 | int ret; |
| 784 | struct defcmd_set *s; | 784 | kdbtab_t *kp; |
| 785 | struct kdb_macro *kmp; | ||
| 786 | struct kdb_macro_statement *kms; | ||
| 787 | |||
| 785 | if (argc != 0) | 788 | if (argc != 0) |
| 786 | return KDB_ARGCOUNT; | 789 | return KDB_ARGCOUNT; |
| 787 | for (s = defcmd_set, i = 0; i < defcmd_set_count; ++i, ++s) { | 790 | |
| 788 | if (strcmp(s->name, argv[0]) == 0) | 791 | list_for_each_entry(kp, &kdb_cmds_head, list_node) { |
| 792 | if (strcmp(kp->name, argv[0]) == 0) | ||
| 789 | break; | 793 | break; |
| 790 | } | 794 | } |
| 791 | if (i == defcmd_set_count) { | 795 | if (list_entry_is_head(kp, &kdb_cmds_head, list_node)) { |
| 792 | kdb_printf("kdb_exec_defcmd: could not find commands for %s\n", | 796 | kdb_printf("kdb_exec_defcmd: could not find commands for %s\n", |
| 793 | argv[0]); | 797 | argv[0]); |
| 794 | return KDB_NOTIMP; | 798 | return KDB_NOTIMP; |
| 795 | } | 799 | } |
| 796 | for (i = 0; i < s->count; ++i) { | 800 | kmp = container_of(kp, struct kdb_macro, cmd); |
| 797 | /* Recursive use of kdb_parse, do not use argv after | 801 | list_for_each_entry(kms, &kmp->statements, list_node) { |
| 798 | * this point */ | 802 | /* |
| 803 | * Recursive use of kdb_parse, do not use argv after this point. | ||
| 804 | */ | ||
| 799 | argv = NULL; | 805 | argv = NULL; |
| 800 | kdb_printf("[%s]kdb> %s\n", s->name, s->command[i]); | 806 | kdb_printf("[%s]kdb> %s\n", kmp->cmd.name, kms->statement); |
| 801 | ret = kdb_parse(s->command[i]); | 807 | ret = kdb_parse(kms->statement); |
| 802 | if (ret) | 808 | if (ret) |
| 803 | return ret; | 809 | return ret; |
| 804 | } | 810 | } |
| @@ -1009,11 +1015,11 @@ int kdb_parse(const char *cmdstr) · 204 unmodified lines | |||
| 1009 | * If this command is allowed to be abbreviated, | 1015 | * If this command is allowed to be abbreviated, |
| 1010 | * check to see if this is it. | 1016 | * check to see if this is it. |
| 1011 | */ | 1017 | */ |
| 1012 | if (tp->cmd_minlen && (strlen(argv[0]) <= tp->cmd_minlen) && | 1018 | if (tp->minlen && (strlen(argv[0]) <= tp->minlen) && |
| 1013 | (strncmp(argv[0], tp->cmd_name, tp->cmd_minlen) == 0)) | 1019 | (strncmp(argv[0], tp->name, tp->minlen) == 0)) |
| 1014 | break; | 1020 | break; |
| 1015 | 1021 | ||
| 1016 | if (strcmp(argv[0], tp->cmd_name) == 0) | 1022 | if (strcmp(argv[0], tp->name) == 0) |
| 1017 | break; | 1023 | break; |
| 1018 | } | 1024 | } |
| 1019 | 1025 | ||
| @@ -1024,8 +1030,7 @@ int kdb_parse(const char *cmdstr) · 4 unmodified lines | |||
| 1024 | */ | 1030 | */ |
| 1025 | if (list_entry_is_head(tp, &kdb_cmds_head, list_node)) { | 1031 | if (list_entry_is_head(tp, &kdb_cmds_head, list_node)) { |
| 1026 | list_for_each_entry(tp, &kdb_cmds_head, list_node) { | 1032 | list_for_each_entry(tp, &kdb_cmds_head, list_node) { |
| 1027 | if (strncmp(argv[0], tp->cmd_name, | 1033 | if (strncmp(argv[0], tp->name, strlen(tp->name)) == 0) |
| 1028 | strlen(tp->cmd_name)) == 0) | ||
| 1029 | break; | 1034 | break; |
| 1030 | } | 1035 | } |
| 1031 | } | 1036 | } |
| @@ -1033,19 +1038,19 @@ int kdb_parse(const char *cmdstr) · 1 unmodified line | |||
| 1033 | if (!list_entry_is_head(tp, &kdb_cmds_head, list_node)) { | 1038 | if (!list_entry_is_head(tp, &kdb_cmds_head, list_node)) { |
| 1034 | int result; | 1039 | int result; |
| 1035 | 1040 | ||
| 1036 | if (!kdb_check_flags(tp->cmd_flags, kdb_cmd_enabled, argc <= 1)) | 1041 | if (!kdb_check_flags(tp->flags, kdb_cmd_enabled, argc <= 1)) |
| 1037 | return KDB_NOPERM; | 1042 | return KDB_NOPERM; |
| 1038 | 1043 | ||
| 1039 | KDB_STATE_SET(CMD); | 1044 | KDB_STATE_SET(CMD); |
| 1040 | result = (*tp->cmd_func)(argc-1, (const char **)argv); | 1045 | result = (*tp->func)(argc-1, (const char **)argv); |
| 1041 | if (result && ignore_errors && result > KDB_CMD_GO) | 1046 | if (result && ignore_errors && result > KDB_CMD_GO) |
| 1042 | result = 0; | 1047 | result = 0; |
| 1043 | KDB_STATE_CLEAR(CMD); | 1048 | KDB_STATE_CLEAR(CMD); |
| 1044 | 1049 | ||
| 1045 | if (tp->cmd_flags & KDB_REPEAT_WITH_ARGS) | 1050 | if (tp->flags & KDB_REPEAT_WITH_ARGS) |
| 1046 | return result; | 1051 | return result; |
| 1047 | 1052 | ||
| 1048 | argc = tp->cmd_flags & KDB_REPEAT_NO_ARGS ? 1 : 0; | 1053 | argc = tp->flags & KDB_REPEAT_NO_ARGS ? 1 : 0; |
| 1049 | if (argv[argc]) | 1054 | if (argv[argc]) |
| 1050 | *(argv[argc]) = '\0'; | 1055 | *(argv[argc]) = '\0'; |
| 1051 | return result; | 1056 | return result; |
| @@ -2412,12 +2417,12 @@ static int kdb_help(int argc, const char **argv) · 1360 unmodified lines | |||
| 2412 | char *space = ""; | 2417 | char *space = ""; |
| 2413 | if (KDB_FLAG(CMD_INTERRUPT)) | 2418 | if (KDB_FLAG(CMD_INTERRUPT)) |
| 2414 | return 0; | 2419 | return 0; |
| 2415 | if (!kdb_check_flags(kt->cmd_flags, kdb_cmd_enabled, true)) | 2420 | if (!kdb_check_flags(kt->flags, kdb_cmd_enabled, true)) |
| 2416 | continue; | 2421 | continue; |
| 2417 | if (strlen(kt->cmd_usage) > 20) | 2422 | if (strlen(kt->usage) > 20) |
| 2418 | space = "\n "; | 2423 | space = "\n "; |
| 2419 | kdb_printf("%-15.15s %-20s%s%s\n", kt->cmd_name, | 2424 | kdb_printf("%-15.15s %-20s%s%s\n", kt->name, |
| 2420 | kt->cmd_usage, space, kt->cmd_help); | 2425 | kt->usage, space, kt->help); |
| 2421 | } | 2426 | } |
| 2422 | return 0; | 2427 | return 0; |
| 2423 | } | 2428 | } |
| @@ -2613,56 +2618,32 @@ static int kdb_grep_help(int argc, const char **argv) · 189 unmodified lines | |||
| 2613 | return 0; | 2618 | return 0; |
| 2614 | } | 2619 | } |
| 2615 | 2620 | ||
| 2616 | /* | 2621 | /** |
| 2617 | * kdb_register_flags - This function is used to register a kernel | 2622 | * kdb_register() - This function is used to register a kernel debugger |
| 2618 | * debugger command. | 2623 | * command. |
| 2619 | * Inputs: | 2624 | * @cmd: pointer to kdb command |
| 2620 | * cmd Command name | 2625 | * |
| 2621 | * func Function to execute the command | 2626 | * Note that it's the job of the caller to keep the memory for the cmd |
| 2622 | * usage A simple usage string showing arguments | 2627 | * allocated until unregister is called. |
| 2623 | * help A simple help string describing command | ||
| 2624 | * repeat Does the command auto repeat on enter? | ||
| 2625 | * Returns: | ||
| 2626 | * zero for success, one if a duplicate command. | ||
| 2627 | */ | 2628 | */ |
| 2628 | int kdb_register_flags(char *cmd, | 2629 | int kdb_register(kdbtab_t *cmd) |
| 2629 | kdb_func_t func, | ||
| 2630 | char *usage, | ||
| 2631 | char *help, | ||
| 2632 | short minlen, | ||
| 2633 | kdb_cmdflags_t flags) | ||
| 2634 | { | 2630 | { |
| 2635 | kdbtab_t *kp; | 2631 | kdbtab_t *kp; |
| 2636 | 2632 | ||
| 2637 | list_for_each_entry(kp, &kdb_cmds_head, list_node) { | 2633 | list_for_each_entry(kp, &kdb_cmds_head, list_node) { |
| 2638 | if (strcmp(kp->cmd_name, cmd) == 0) { | 2634 | if (strcmp(kp->name, cmd->name) == 0) { |
| 2639 | kdb_printf("Duplicate kdb command registered: " | 2635 | kdb_printf("Duplicate kdb cmd: %s, func %p help %s\n", |
| 2640 | "%s, func %px help %s\n", cmd, func, help); | 2636 | cmd->name, cmd->func, cmd->help); |
| 2641 | return 1; | 2637 | return 1; |
| 2642 | } | 2638 | } |
| 2643 | } | 2639 | } |
| 2644 | 2640 | ||
| 2645 | kp = kmalloc(sizeof(*kp), GFP_KDB); | 2641 | list_add_tail(&cmd->list_node, &kdb_cmds_head); |
| 2646 | if (!kp) { | ||
| 2647 | kdb_printf("Could not allocate new kdb_command table\n"); | ||
| 2648 | return 1; | ||
| 2649 | } | ||
| 2650 | |||
| 2651 | kp->cmd_name = cmd; | ||
| 2652 | kp->cmd_func = func; | ||
| 2653 | kp->cmd_usage = usage; | ||
| 2654 | kp->cmd_help = help; | ||
| 2655 | kp->cmd_minlen = minlen; | ||
| 2656 | kp->cmd_flags = flags; | ||
| 2657 | kp->is_dynamic = true; | ||
| 2658 | |||
| 2659 | list_add_tail(&kp->list_node, &kdb_cmds_head); | ||
| 2660 | |||
| 2661 | return 0; | 2642 | return 0; |
| 2662 | } | 2643 | } |
| 2663 | EXPORT_SYMBOL_GPL(kdb_register_flags); | 2644 | EXPORT_SYMBOL_GPL(kdb_register); |
| 2664 | 2645 | ||
| 2665 | /* | 2646 | /** |
| 2666 | * kdb_register_table() - This function is used to register a kdb command | 2647 | * kdb_register_table() - This function is used to register a kdb command |
| 2667 | * table. | 2648 | * table. |
| 2668 | * @kp: pointer to kdb command table | 2649 | * @kp: pointer to kdb command table |
| @@ -2676,266 +2657,231 @@ void kdb_register_table(kdbtab_t *kp, size_t len) · 7 unmodified lines | |||
| 2676 | } | 2657 | } |
| 2677 | } | 2658 | } |
| 2678 | 2659 | ||
| 2679 | /* | 2660 | /** |
| 2680 | * kdb_register - Compatibility register function for commands that do | 2661 | * kdb_unregister() - This function is used to unregister a kernel debugger |
| 2681 | * not need to specify a repeat state. Equivalent to | 2662 | * command. It is generally called when a module which |
| 2682 | * kdb_register_flags with flags set to 0. | 2663 | * implements kdb command is unloaded. |
| 2683 | * Inputs: | 2664 | * @cmd: pointer to kdb command |
| 2684 | * cmd Command name | ||
| 2685 | * func Function to execute the command | ||
| 2686 | * usage A simple usage string showing arguments | ||
| 2687 | * help A simple help string describing command | ||
| 2688 | * Returns: | ||
| 2689 | * zero for success, one if a duplicate command. | ||
| 2690 | */ | 2665 | */ |
| 2691 | int kdb_register(char *cmd, | 2666 | void kdb_unregister(kdbtab_t *cmd) |
| 2692 | kdb_func_t func, | ||
| 2693 | char *usage, | ||
| 2694 | char *help, | ||
| 2695 | short minlen) | ||
| 2696 | { | 2667 | { |
| 2697 | return kdb_register_flags(cmd, func, usage, help, minlen, 0); | 2668 | list_del(&cmd->list_node); |
| 2698 | } | ||
| 2699 | EXPORT_SYMBOL_GPL(kdb_register); | ||
| 2700 | |||
| 2701 | /* | ||
| 2702 | * kdb_unregister - This function is used to unregister a kernel | ||
| 2703 | * debugger command. It is generally called when a module which | ||
| 2704 | * implements kdb commands is unloaded. | ||
| 2705 | * Inputs: | ||
| 2706 | * cmd Command name | ||
| 2707 | * Returns: | ||
| 2708 | * zero for success, one command not registered. | ||
| 2709 | */ | ||
| 2710 | int kdb_unregister(char *cmd) | ||
| 2711 | { | ||
| 2712 | kdbtab_t *kp; | ||
| 2713 | |||
| 2714 | /* | ||
| 2715 | * find the command. | ||
| 2716 | */ | ||
| 2717 | list_for_each_entry(kp, &kdb_cmds_head, list_node) { | ||
| 2718 | if (strcmp(kp->cmd_name, cmd) == 0) { | ||
| 2719 | list_del(&kp->list_node); | ||
| 2720 | if (kp->is_dynamic) | ||
| 2721 | kfree(kp); | ||
| 2722 | return 0; | ||
| 2723 | } | ||
| 2724 | } | ||
| 2725 | |||
| 2726 | /* Couldn't find it. */ | ||
| 2727 | return 1; | ||
| 2728 | } | 2669 | } |
| 2729 | EXPORT_SYMBOL_GPL(kdb_unregister); | 2670 | EXPORT_SYMBOL_GPL(kdb_unregister); |
| 2730 | 2671 | ||
| 2731 | static kdbtab_t maintab[] = { | 2672 | static kdbtab_t maintab[] = { |
| 2732 | { .cmd_name = "md", | 2673 | { .name = "md", |
| 2733 | .cmd_func = kdb_md, | 2674 | .func = kdb_md, |
| 2734 | .cmd_usage = "<vaddr>", | 2675 | .usage = "<vaddr>", |
| 2735 | .cmd_help = "Display Memory Contents, also mdWcN, e.g. md8c1", | 2676 | .help = "Display Memory Contents, also mdWcN, e.g. md8c1", |
| 2736 | .cmd_minlen = 1, | 2677 | .minlen = 1, |
| 2737 | .cmd_flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, | 2678 | .flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, |
| 2738 | }, | 2679 | }, |
| 2739 | { .cmd_name = "mdr", | 2680 | { .name = "mdr", |
| 2740 | .cmd_func = kdb_md, | 2681 | .func = kdb_md, |
| 2741 | .cmd_usage = "<vaddr> <bytes>", | 2682 | .usage = "<vaddr> <bytes>", |
| 2742 | .cmd_help = "Display Raw Memory", | 2683 | .help = "Display Raw Memory", |
| 2743 | .cmd_flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, | 2684 | .flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, |
| 2744 | }, | 2685 | }, |
| 2745 | { .cmd_name = "mdp", | 2686 | { .name = "mdp", |
| 2746 | .cmd_func = kdb_md, | 2687 | .func = kdb_md, |
| 2747 | .cmd_usage = "<paddr> <bytes>", | 2688 | .usage = "<paddr> <bytes>", |
| 2748 | .cmd_help = "Display Physical Memory", | 2689 | .help = "Display Physical Memory", |
| 2749 | .cmd_flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, | 2690 | .flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, |
| 2750 | }, | 2691 | }, |
| 2751 | { .cmd_name = "mds", | 2692 | { .name = "mds", |
| 2752 | .cmd_func = kdb_md, | 2693 | .func = kdb_md, |
| 2753 | .cmd_usage = "<vaddr>", | 2694 | .usage = "<vaddr>", |
| 2754 | .cmd_help = "Display Memory Symbolically", | 2695 | .help = "Display Memory Symbolically", |
| 2755 | .cmd_flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, | 2696 | .flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, |
| 2756 | }, | 2697 | }, |
| 2757 | { .cmd_name = "mm", | 2698 | { .name = "mm", |
| 2758 | .cmd_func = kdb_mm, | 2699 | .func = kdb_mm, |
| 2759 | .cmd_usage = "<vaddr> <contents>", | 2700 | .usage = "<vaddr> <contents>", |
| 2760 | .cmd_help = "Modify Memory Contents", | 2701 | .help = "Modify Memory Contents", |
| 2761 | .cmd_flags = KDB_ENABLE_MEM_WRITE | KDB_REPEAT_NO_ARGS, | 2702 | .flags = KDB_ENABLE_MEM_WRITE | KDB_REPEAT_NO_ARGS, |
| 2762 | }, | 2703 | }, |
| 2763 | { .cmd_name = "go", | 2704 | { .name = "go", |
| 2764 | .cmd_func = kdb_go, | 2705 | .func = kdb_go, |
| 2765 | .cmd_usage = "[<vaddr>]", | 2706 | .usage = "[<vaddr>]", |
| 2766 | .cmd_help = "Continue Execution", | 2707 | .help = "Continue Execution", |
| 2767 | .cmd_minlen = 1, | 2708 | .minlen = 1, |
| 2768 | .cmd_flags = KDB_ENABLE_REG_WRITE | | 2709 | .flags = KDB_ENABLE_REG_WRITE | |
| 2769 | KDB_ENABLE_ALWAYS_SAFE_NO_ARGS, | 2710 | KDB_ENABLE_ALWAYS_SAFE_NO_ARGS, |
| 2770 | }, | 2711 | }, |
| 2771 | { .cmd_name = "rd", | 2712 | { .name = "rd", |
| 2772 | .cmd_func = kdb_rd, | 2713 | .func = kdb_rd, |
| 2773 | .cmd_usage = "", | 2714 | .usage = "", |
| 2774 | .cmd_help = "Display Registers", | 2715 | .help = "Display Registers", |
| 2775 | .cmd_flags = KDB_ENABLE_REG_READ, | 2716 | .flags = KDB_ENABLE_REG_READ, |
| 2776 | }, | 2717 | }, |
| 2777 | { .cmd_name = "rm", | 2718 | { .name = "rm", |
| 2778 | .cmd_func = kdb_rm, | 2719 | .func = kdb_rm, |
| 2779 | .cmd_usage = "<reg> <contents>", | 2720 | .usage = "<reg> <contents>", |
| 2780 | .cmd_help = "Modify Registers", | 2721 | .help = "Modify Registers", |
| 2781 | .cmd_flags = KDB_ENABLE_REG_WRITE, | 2722 | .flags = KDB_ENABLE_REG_WRITE, |
| 2782 | }, | 2723 | }, |
| 2783 | { .cmd_name = "ef", | 2724 | { .name = "ef", |
| 2784 | .cmd_func = kdb_ef, | 2725 | .func = kdb_ef, |
| 2785 | .cmd_usage = "<vaddr>", | 2726 | .usage = "<vaddr>", |
| 2786 | .cmd_help = "Display exception frame", | 2727 | .help = "Display exception frame", |
| 2787 | .cmd_flags = KDB_ENABLE_MEM_READ, | 2728 | .flags = KDB_ENABLE_MEM_READ, |
| 2788 | }, | 2729 | }, |
| 2789 | { .cmd_name = "bt", | 2730 | { .name = "bt", |
| 2790 | .cmd_func = kdb_bt, | 2731 | .func = kdb_bt, |
| 2791 | .cmd_usage = "[<vaddr>]", | 2732 | .usage = "[<vaddr>]", |
| 2792 | .cmd_help = "Stack traceback", | 2733 | .help = "Stack traceback", |
| 2793 | .cmd_minlen = 1, | 2734 | .minlen = 1, |
| 2794 | .cmd_flags = KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS, | 2735 | .flags = KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS, |
| 2795 | }, | 2736 | }, |
| 2796 | { .cmd_name = "btp", | 2737 | { .name = "btp", |
| 2797 | .cmd_func = kdb_bt, | 2738 | .func = kdb_bt, |
| 2798 | .cmd_usage = "<pid>", | 2739 | .usage = "<pid>", |
| 2799 | .cmd_help = "Display stack for process <pid>", | 2740 | .help = "Display stack for process <pid>", |
| 2800 | .cmd_flags = KDB_ENABLE_INSPECT, | 2741 | .flags = KDB_ENABLE_INSPECT, |
| 2801 | }, | 2742 | }, |
| 2802 | { .cmd_name = "bta", | 2743 | { .name = "bta", |
| 2803 | .cmd_func = kdb_bt, | 2744 | .func = kdb_bt, |
| 2804 | .cmd_usage = "[D|R|S|T|C|Z|E|U|I|M|A]", | 2745 | .usage = "[D|R|S|T|C|Z|E|U|I|M|A]", |
| 2805 | .cmd_help = "Backtrace all processes matching state flag", | 2746 | .help = "Backtrace all processes matching state flag", |
| 2806 | .cmd_flags = KDB_ENABLE_INSPECT, | 2747 | .flags = KDB_ENABLE_INSPECT, |
| 2807 | }, | 2748 | }, |
| 2808 | { .cmd_name = "btc", | 2749 | { .name = "btc", |
| 2809 | .cmd_func = kdb_bt, | 2750 | .func = kdb_bt, |
| 2810 | .cmd_usage = "", | 2751 | .usage = "", |
| 2811 | .cmd_help = "Backtrace current process on each cpu", | 2752 | .help = "Backtrace current process on each cpu", |
| 2812 | .cmd_flags = KDB_ENABLE_INSPECT, | 2753 | .flags = KDB_ENABLE_INSPECT, |
| 2813 | }, | 2754 | }, |
| 2814 | { .cmd_name = "btt", | 2755 | { .name = "btt", |
| 2815 | .cmd_func = kdb_bt, | 2756 | .func = kdb_bt, |
| 2816 | .cmd_usage = "<vaddr>", | 2757 | .usage = "<vaddr>", |
| 2817 | .cmd_help = "Backtrace process given its struct task address", | 2758 | .help = "Backtrace process given its struct task address", |
| 2818 | .cmd_flags = KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS, | 2759 | .flags = KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS, |
| 2819 | }, | 2760 | }, |
| 2820 | { .cmd_name = "env", | 2761 | { .name = "env", |
| 2821 | .cmd_func = kdb_env, | 2762 | .func = kdb_env, |
| 2822 | .cmd_usage = "", | 2763 | .usage = "", |
| 2823 | .cmd_help = "Show environment variables", | 2764 | .help = "Show environment variables", |
| 2824 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2765 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2825 | }, | 2766 | }, |
| 2826 | { .cmd_name = "set", | 2767 | { .name = "set", |
| 2827 | .cmd_func = kdb_set, | 2768 | .func = kdb_set, |
| 2828 | .cmd_usage = "", | 2769 | .usage = "", |
| 2829 | .cmd_help = "Set environment variables", | 2770 | .help = "Set environment variables", |
| 2830 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2771 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2831 | }, | 2772 | }, |
| 2832 | { .cmd_name = "help", | 2773 | { .name = "help", |
| 2833 | .cmd_func = kdb_help, | 2774 | .func = kdb_help, |
| 2834 | .cmd_usage = "", | 2775 | .usage = "", |
| 2835 | .cmd_help = "Display Help Message", | 2776 | .help = "Display Help Message", |
| 2836 | .cmd_minlen = 1, | 2777 | .minlen = 1, |
| 2837 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2778 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2838 | }, | 2779 | }, |
| 2839 | { .cmd_name = "?", | 2780 | { .name = "?", |
| 2840 | .cmd_func = kdb_help, | 2781 | .func = kdb_help, |
| 2841 | .cmd_usage = "", | 2782 | .usage = "", |
| 2842 | .cmd_help = "Display Help Message", | 2783 | .help = "Display Help Message", |
| 2843 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2784 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2844 | }, | 2785 | }, |
| 2845 | { .cmd_name = "cpu", | 2786 | { .name = "cpu", |
| 2846 | .cmd_func = kdb_cpu, | 2787 | .func = kdb_cpu, |
| 2847 | .cmd_usage = "<cpunum>", | 2788 | .usage = "<cpunum>", |
| 2848 | .cmd_help = "Switch to new cpu", | 2789 | .help = "Switch to new cpu", |
| 2849 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE_NO_ARGS, | 2790 | .flags = KDB_ENABLE_ALWAYS_SAFE_NO_ARGS, |
| 2850 | }, | 2791 | }, |
| 2851 | { .cmd_name = "kgdb", | 2792 | { .name = "kgdb", |
| 2852 | .cmd_func = kdb_kgdb, | 2793 | .func = kdb_kgdb, |
| 2853 | .cmd_usage = "", | 2794 | .usage = "", |
| 2854 | .cmd_help = "Enter kgdb mode", | 2795 | .help = "Enter kgdb mode", |
| 2855 | .cmd_flags = 0, | 2796 | .flags = 0, |
| 2856 | }, | 2797 | }, |
| 2857 | { .cmd_name = "ps", | 2798 | { .name = "ps", |
| 2858 | .cmd_func = kdb_ps, | 2799 | .func = kdb_ps, |
| 2859 | .cmd_usage = "[<flags>|A]", | 2800 | .usage = "[<flags>|A]", |
| 2860 | .cmd_help = "Display active task list", | 2801 | .help = "Display active task list", |
| 2861 | .cmd_flags = KDB_ENABLE_INSPECT, | 2802 | .flags = KDB_ENABLE_INSPECT, |
| 2862 | }, | 2803 | }, |
| 2863 | { .cmd_name = "pid", | 2804 | { .name = "pid", |
| 2864 | .cmd_func = kdb_pid, | 2805 | .func = kdb_pid, |
| 2865 | .cmd_usage = "<pidnum>", | 2806 | .usage = "<pidnum>", |
| 2866 | .cmd_help = "Switch to another task", | 2807 | .help = "Switch to another task", |
| 2867 | .cmd_flags = KDB_ENABLE_INSPECT, | 2808 | .flags = KDB_ENABLE_INSPECT, |
| 2868 | }, | 2809 | }, |
| 2869 | { .cmd_name = "reboot", | 2810 | { .name = "reboot", |
| 2870 | .cmd_func = kdb_reboot, | 2811 | .func = kdb_reboot, |
| 2871 | .cmd_usage = "", | 2812 | .usage = "", |
| 2872 | .cmd_help = "Reboot the machine immediately", | 2813 | .help = "Reboot the machine immediately", |
| 2873 | .cmd_flags = KDB_ENABLE_REBOOT, | 2814 | .flags = KDB_ENABLE_REBOOT, |
| 2874 | }, | 2815 | }, |
| 2875 | #if defined(CONFIG_MODULES) | 2816 | #if defined(CONFIG_MODULES) |
| 2876 | { .cmd_name = "lsmod", | 2817 | { .name = "lsmod", |
| 2877 | .cmd_func = kdb_lsmod, | 2818 | .func = kdb_lsmod, |
| 2878 | .cmd_usage = "", | 2819 | .usage = "", |
| 2879 | .cmd_help = "List loaded kernel modules", | 2820 | .help = "List loaded kernel modules", |
| 2880 | .cmd_flags = KDB_ENABLE_INSPECT, | 2821 | .flags = KDB_ENABLE_INSPECT, |
| 2881 | }, | 2822 | }, |
| 2882 | #endif | 2823 | #endif |
| 2883 | #if defined(CONFIG_MAGIC_SYSRQ) | 2824 | #if defined(CONFIG_MAGIC_SYSRQ) |
| 2884 | { .cmd_name = "sr", | 2825 | { .name = "sr", |
| 2885 | .cmd_func = kdb_sr, | 2826 | .func = kdb_sr, |
| 2886 | .cmd_usage = "<key>", | 2827 | .usage = "<key>", |
| 2887 | .cmd_help = "Magic SysRq key", | 2828 | .help = "Magic SysRq key", |
| 2888 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2829 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2889 | }, | 2830 | }, |
| 2890 | #endif | 2831 | #endif |
| 2891 | #if defined(CONFIG_PRINTK) | 2832 | #if defined(CONFIG_PRINTK) |
| 2892 | { .cmd_name = "dmesg", | 2833 | { .name = "dmesg", |
| 2893 | .cmd_func = kdb_dmesg, | 2834 | .func = kdb_dmesg, |
| 2894 | .cmd_usage = "[lines]", | 2835 | .usage = "[lines]", |
| 2895 | .cmd_help = "Display syslog buffer", | 2836 | .help = "Display syslog buffer", |
| 2896 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2837 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2897 | }, | 2838 | }, |
| 2898 | #endif | 2839 | #endif |
| 2899 | { .cmd_name = "defcmd", | 2840 | { .name = "defcmd", |
| 2900 | .cmd_func = kdb_defcmd, | 2841 | .func = kdb_defcmd, |
| 2901 | .cmd_usage = "name \"usage\" \"help\"", | 2842 | .usage = "name \"usage\" \"help\"", |
| 2902 | .cmd_help = "Define a set of commands, down to endefcmd", | 2843 | .help = "Define a set of commands, down to endefcmd", |
| 2903 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2844 | /* |
| 2845 | * Macros are always safe because when executed each | ||
| 2846 | * internal command re-enters kdb_parse() and is safety | ||
| 2847 | * checked individually. | ||
| 2848 | */ | ||
| 2849 | .flags = KDB_ENABLE_ALWAYS_SAFE, | ||
| 2904 | }, | 2850 | }, |
| 2905 | { .cmd_name = "kill", | 2851 | { .name = "kill", |
| 2906 | .cmd_func = kdb_kill, | 2852 | .func = kdb_kill, |
| 2907 | .cmd_usage = "<-signal> <pid>", | 2853 | .usage = "<-signal> <pid>", |
| 2908 | .cmd_help = "Send a signal to a process", | 2854 | .help = "Send a signal to a process", |
| 2909 | .cmd_flags = KDB_ENABLE_SIGNAL, | 2855 | .flags = KDB_ENABLE_SIGNAL, |
| 2910 | }, | 2856 | }, |
| 2911 | { .cmd_name = "summary", | 2857 | { .name = "summary", |
| 2912 | .cmd_func = kdb_summary, | 2858 | .func = kdb_summary, |
| 2913 | .cmd_usage = "", | 2859 | .usage = "", |
| 2914 | .cmd_help = "Summarize the system", | 2860 | .help = "Summarize the system", |
| 2915 | .cmd_minlen = 4, | 2861 | .minlen = 4, |
| 2916 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2862 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2917 | }, | 2863 | }, |
| 2918 | { .cmd_name = "per_cpu", | 2864 | { .name = "per_cpu", |
| 2919 | .cmd_func = kdb_per_cpu, | 2865 | .func = kdb_per_cpu, |
| 2920 | .cmd_usage = "<sym> [<bytes>] [<cpu>]", | 2866 | .usage = "<sym> [<bytes>] [<cpu>]", |
| 2921 | .cmd_help = "Display per_cpu variables", | 2867 | .help = "Display per_cpu variables", |
| 2922 | .cmd_minlen = 3, | 2868 | .minlen = 3, |
| 2923 | .cmd_flags = KDB_ENABLE_MEM_READ, | 2869 | .flags = KDB_ENABLE_MEM_READ, |
| 2924 | }, | 2870 | }, |
| 2925 | { .cmd_name = "grephelp", | 2871 | { .name = "grephelp", |
| 2926 | .cmd_func = kdb_grep_help, | 2872 | .func = kdb_grep_help, |
| 2927 | .cmd_usage = "", | 2873 | .usage = "", |
| 2928 | .cmd_help = "Display help on | grep", | 2874 | .help = "Display help on | grep", |
| 2929 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2875 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2930 | }, | 2876 | }, |
| 2931 | }; | 2877 | }; |
| 2932 | 2878 | ||
| 2933 | static kdbtab_t nmicmd = { | 2879 | static kdbtab_t nmicmd = { |
| 2934 | .cmd_name = "disable_nmi", | 2880 | .name = "disable_nmi", |
| 2935 | .cmd_func = kdb_disable_nmi, | 2881 | .func = kdb_disable_nmi, |
| 2936 | .cmd_usage = "", | 2882 | .usage = "", |
| 2937 | .cmd_help = "Disable NMI entry to KDB", | 2883 | .help = "Disable NMI entry to KDB", |
| 2938 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2884 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2939 | }; | 2885 | }; |
| 2940 | 2886 | ||
| 2941 | /* Initialize the kdb command table. */ | 2887 | /* Initialize the kdb command table. */ |
| @@ -109,7 +109,6 @@ extern int kdbgetaddrarg(int, const char **, int*, unsigned long *, · 108 unmodified lines | |||
| 109 | long *, char **); | 109 | long *, char **); |
| 110 | extern int kdbgetsymval(const char *, kdb_symtab_t *); | 110 | extern int kdbgetsymval(const char *, kdb_symtab_t *); |
| 111 | extern int kdbnearsym(unsigned long, kdb_symtab_t *); | 111 | extern int kdbnearsym(unsigned long, kdb_symtab_t *); |
| 112 | extern void kdbnearsym_cleanup(void); | ||
| 113 | extern char *kdb_strdup(const char *str, gfp_t type); | 112 | extern char *kdb_strdup(const char *str, gfp_t type); |
| 114 | extern void kdb_symbol_print(unsigned long, const kdb_symtab_t *, unsigned int); | 113 | extern void kdb_symbol_print(unsigned long, const kdb_symtab_t *, unsigned int); |
| 115 | 114 | ||
| @@ -165,19 +164,6 @@ typedef struct _kdb_bp { · 49 unmodified lines | |||
| 165 | #ifdef CONFIG_KGDB_KDB | 164 | #ifdef CONFIG_KGDB_KDB |
| 166 | extern kdb_bp_t kdb_breakpoints[/* KDB_MAXBPT */]; | 165 | extern kdb_bp_t kdb_breakpoints[/* KDB_MAXBPT */]; |
| 167 | 166 | ||
| 168 | /* The KDB shell command table */ | ||
| 169 | typedef struct _kdbtab { | ||
| 170 | char *cmd_name; /* Command name */ | ||
| 171 | kdb_func_t cmd_func; /* Function to execute command */ | ||
| 172 | char *cmd_usage; /* Usage String for this command */ | ||
| 173 | char *cmd_help; /* Help message for this command */ | ||
| 174 | short cmd_minlen; /* Minimum legal # command | ||
| 175 | * chars required */ | ||
| 176 | kdb_cmdflags_t cmd_flags; /* Command behaviour flags */ | ||
| 177 | struct list_head list_node; /* Command list */ | ||
| 178 | bool is_dynamic; /* Command table allocation type */ | ||
| 179 | } kdbtab_t; | ||
| 180 | |||
| 181 | extern void kdb_register_table(kdbtab_t *kp, size_t len); | 167 | extern void kdb_register_table(kdbtab_t *kp, size_t len); |
| 182 | extern int kdb_bt(int, const char **); /* KDB display back trace */ | 168 | extern int kdb_bt(int, const char **); /* KDB display back trace */ |
| 183 | 169 | ||
| @@ -233,10 +219,6 @@ extern struct task_struct *kdb_curr_task(int); · 49 unmodified lines | |||
| 233 | 219 | ||
| 234 | #define GFP_KDB (in_dbg_master() ? GFP_ATOMIC : GFP_KERNEL) | 220 | #define GFP_KDB (in_dbg_master() ? GFP_ATOMIC : GFP_KERNEL) |
| 235 | 221 | ||
| 236 | extern void *debug_kmalloc(size_t size, gfp_t flags); | ||
| 237 | extern void debug_kfree(void *); | ||
| 238 | extern void debug_kusage(void); | ||
| 239 | |||
| 240 | extern struct task_struct *kdb_current_task; | 222 | extern struct task_struct *kdb_current_task; |
| 241 | extern struct pt_regs *kdb_current_regs; | 223 | extern struct pt_regs *kdb_current_regs; |
| 242 | 224 | ||
| @@ -51,48 +51,48 @@ int kdbgetsymval(const char *symname, kdb_symtab_t *symtab) · 50 unmodified lines | |||
| 51 | } | 51 | } |
| 52 | EXPORT_SYMBOL(kdbgetsymval); | 52 | EXPORT_SYMBOL(kdbgetsymval); |
| 53 | 53 | ||
| 54 | static char *kdb_name_table[100]; /* arbitrary size */ | 54 | /** |
| 55 | 55 | * kdbnearsym() - Return the name of the symbol with the nearest address | |
| 56 | /* | 56 | * less than @addr. |
| 57 | * kdbnearsym - Return the name of the symbol with the nearest address | 57 | * @addr: Address to check for near symbol |
| 58 | * less than 'addr'. | 58 | * @symtab: Structure to receive results |
| 59 | * | 59 | * |
| 60 | * Parameters: | 60 | * WARNING: This function may return a pointer to a single statically |
| 61 | * addr Address to check for symbol near | 61 | * allocated buffer (namebuf). kdb's unusual calling context (single |
| 62 | * symtab Structure to receive results | 62 | * threaded, all other CPUs halted) provides us sufficient locking for |
| 63 | * Returns: | 63 | * this to be safe. The only constraint imposed by the static buffer is |
| 64 | * 0 No sections contain this address, symtab zero filled | 64 | * that the caller must consume any previous reply prior to another call |
| 65 | * 1 Address mapped to module/symbol/section, data in symtab | 65 | * to lookup a new symbol. |
| 66 | * Remarks: | 66 | * |
| 67 | * 2.6 kallsyms has a "feature" where it unpacks the name into a | 67 | * Note that, strictly speaking, some architectures may re-enter the kdb |
| 68 | * string. If that string is reused before the caller expects it | 68 | * trap if the system turns out to be very badly damaged and this breaks |
| 69 | * then the caller sees its string change without warning. To | 69 | * the single-threaded assumption above. In these circumstances successful |
| 70 | * avoid cluttering up the main kdb code with lots of kdb_strdup, | 70 | * continuation and exit from the inner trap is unlikely to work and any |
| 71 | * tests and kfree calls, kdbnearsym maintains an LRU list of the | 71 | * user attempting this receives a prominent warning before being allowed |
| 72 | * last few unique strings. The list is sized large enough to | 72 | * to progress. In these circumstances we remain memory safe because |
| 73 | * hold active strings, no kdb caller of kdbnearsym makes more | 73 | * namebuf[KSYM_NAME_LEN-1] will never change from '\0' although we do |
| 74 | * than ~20 later calls before using a saved value. | 74 | * tolerate the possibility of garbled symbol display from the outer kdb |
| 75 | * trap. | ||
| 76 | * | ||
| 77 | * Return: | ||
| 78 | * * 0 - No sections contain this address, symtab zero filled | ||
| 79 | * * 1 - Address mapped to module/symbol/section, data in symtab | ||
| 75 | */ | 80 | */ |
| 76 | int kdbnearsym(unsigned long addr, kdb_symtab_t *symtab) | 81 | int kdbnearsym(unsigned long addr, kdb_symtab_t *symtab) |
| 77 | { | 82 | { |
| 78 | int ret = 0; | 83 | int ret = 0; |
| 79 | unsigned long symbolsize = 0; | 84 | unsigned long symbolsize = 0; |
| 80 | unsigned long offset = 0; | 85 | unsigned long offset = 0; |
| 81 | #define knt1_size 128 /* must be >= kallsyms table size */ | 86 | static char namebuf[KSYM_NAME_LEN]; |
| 82 | char *knt1 = NULL; | ||
| 83 | 87 | ||
| 84 | kdb_dbg_printf(AR, "addr=0x%lx, symtab=%px\n", addr, symtab); | 88 | kdb_dbg_printf(AR, "addr=0x%lx, symtab=%px\n", addr, symtab); |
| 85 | memset(symtab, 0, sizeof(*symtab)); | 89 | memset(symtab, 0, sizeof(*symtab)); |
| 86 | 90 | ||
| 87 | if (addr < 4096) | 91 | if (addr < 4096) |
| 88 | goto out; | 92 | goto out; |
| 89 | knt1 = debug_kmalloc(knt1_size, GFP_ATOMIC); | 93 | |
| 90 | if (!knt1) { | ||
| 91 | kdb_func_printf("addr=0x%lx cannot kmalloc knt1\n", addr); | ||
| 92 | goto out; | ||
| 93 | } | ||
| 94 | symtab->sym_name = kallsyms_lookup(addr, &symbolsize , &offset, | 94 | symtab->sym_name = kallsyms_lookup(addr, &symbolsize , &offset, |
| 95 | (char **)(&symtab->mod_name), knt1); | 95 | (char **)(&symtab->mod_name), namebuf); |
| 96 | if (offset > 8*1024*1024) { | 96 | if (offset > 8*1024*1024) { |
| 97 | symtab->sym_name = NULL; | 97 | symtab->sym_name = NULL; |
| 98 | addr = offset = symbolsize = 0; | 98 | addr = offset = symbolsize = 0; |
| @@ -101,63 +101,14 @@ int kdbnearsym(unsigned long addr, kdb_symtab_t *symtab) · 2 unmodified lines | |||
| 101 | symtab->sym_end = symtab->sym_start + symbolsize; | 101 | symtab->sym_end = symtab->sym_start + symbolsize; |
| 102 | ret = symtab->sym_name != NULL && *(symtab->sym_name) != '\0'; | 102 | ret = symtab->sym_name != NULL && *(symtab->sym_name) != '\0'; |
| 103 | 103 | ||
| 104 | if (ret) { | ||
| 105 | int i; | ||
| 106 | /* Another 2.6 kallsyms "feature". Sometimes the sym_name is | ||
| 107 | * set but the buffer passed into kallsyms_lookup is not used, | ||
| 108 | * so it contains garbage. The caller has to work out which | ||
| 109 | * buffer needs to be saved. | ||
| 110 | * | ||
| 111 | * What was Rusty smoking when he wrote that code? | ||
| 112 | */ | ||
| 113 | if (symtab->sym_name != knt1) { | ||
| 114 | strncpy(knt1, symtab->sym_name, knt1_size); | ||
| 115 | knt1[knt1_size-1] = '\0'; | ||
| 116 | } | ||
| 117 | for (i = 0; i < ARRAY_SIZE(kdb_name_table); ++i) { | ||
| 118 | if (kdb_name_table[i] && | ||
| 119 | strcmp(kdb_name_table[i], knt1) == 0) | ||
| 120 | break; | ||
| 121 | } | ||
| 122 | if (i >= ARRAY_SIZE(kdb_name_table)) { | ||
| 123 | debug_kfree(kdb_name_table[0]); | ||
| 124 | memmove(kdb_name_table, kdb_name_table+1, | ||
| 125 | sizeof(kdb_name_table[0]) * | ||
| 126 | (ARRAY_SIZE(kdb_name_table)-1)); | ||
| 127 | } else { | ||
| 128 | debug_kfree(knt1); | ||
| 129 | knt1 = kdb_name_table[i]; | ||
| 130 | memmove(kdb_name_table+i, kdb_name_table+i+1, | ||
| 131 | sizeof(kdb_name_table[0]) * | ||
| 132 | (ARRAY_SIZE(kdb_name_table)-i-1)); | ||
| 133 | } | ||
| 134 | i = ARRAY_SIZE(kdb_name_table) - 1; | ||
| 135 | kdb_name_table[i] = knt1; | ||
| 136 | symtab->sym_name = kdb_name_table[i]; | ||
| 137 | knt1 = NULL; | ||
| 138 | } | ||
| 139 | |||
| 140 | if (symtab->mod_name == NULL) | 104 | if (symtab->mod_name == NULL) |
| 141 | symtab->mod_name = "kernel"; | 105 | symtab->mod_name = "kernel"; |
| 142 | kdb_dbg_printf(AR, "returns %d symtab->sym_start=0x%lx, symtab->mod_name=%px, symtab->sym_name=%px (%s)\n", | 106 | kdb_dbg_printf(AR, "returns %d symtab->sym_start=0x%lx, symtab->mod_name=%px, symtab->sym_name=%px (%s)\n", |
| 143 | ret, symtab->sym_start, symtab->mod_name, symtab->sym_name, symtab->sym_name); | 107 | ret, symtab->sym_start, symtab->mod_name, symtab->sym_name, symtab->sym_name); |
| 144 | |||
| 145 | out: | 108 | out: |
| 146 | debug_kfree(knt1); | ||
| 147 | return ret; | 109 | return ret; |
| 148 | } | 110 | } |
| 149 | 111 | ||
| 150 | void kdbnearsym_cleanup(void) | ||
| 151 | { | ||
| 152 | int i; | ||
| 153 | for (i = 0; i < ARRAY_SIZE(kdb_name_table); ++i) { | ||
| 154 | if (kdb_name_table[i]) { | ||
| 155 | debug_kfree(kdb_name_table[i]); | ||
| 156 | kdb_name_table[i] = NULL; | ||
| 157 | } | ||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | static char ks_namebuf[KSYM_NAME_LEN+1], ks_namebuf_prev[KSYM_NAME_LEN+1]; | 112 | static char ks_namebuf[KSYM_NAME_LEN+1], ks_namebuf_prev[KSYM_NAME_LEN+1]; |
| 162 | 113 | ||
| 163 | /* | 114 | /* |
| @@ -655,230 +606,6 @@ unsigned long kdb_task_state(const struct task_struct *p, unsigned long mask) · 491 unmodified lines | |||
| 655 | return (mask & kdb_task_state_string(state)) != 0; | 606 | return (mask & kdb_task_state_string(state)) != 0; |
| 656 | } | 607 | } |
| 657 | 608 | ||
| 658 | /* Last ditch allocator for debugging, so we can still debug even when | ||
| 659 | * the GFP_ATOMIC pool has been exhausted. The algorithms are tuned | ||
| 660 | * for space usage, not for speed. One smallish memory pool, the free | ||
| 661 | * chain is always in ascending address order to allow coalescing, | ||
| 662 | * allocations are done in brute force best fit. | ||
| 663 | */ | ||
| 664 | |||
| 665 | struct debug_alloc_header { | ||
| 666 | u32 next; /* offset of next header from start of pool */ | ||
| 667 | u32 size; | ||
| 668 | void *caller; | ||
| 669 | }; | ||
| 670 | |||
| 671 | /* The memory returned by this allocator must be aligned, which means | ||
| 672 | * so must the header size. Do not assume that sizeof(struct | ||
| 673 | * debug_alloc_header) is a multiple of the alignment, explicitly | ||
| 674 | * calculate the overhead of this header, including the alignment. | ||
| 675 | * The rest of this code must not use sizeof() on any header or | ||
| 676 | * pointer to a header. | ||
| 677 | */ | ||
| 678 | #define dah_align 8 | ||
| 679 | #define dah_overhead ALIGN(sizeof(struct debug_alloc_header), dah_align) | ||
| 680 | |||
| 681 | static u64 debug_alloc_pool_aligned[256*1024/dah_align]; /* 256K pool */ | ||
| 682 | static char *debug_alloc_pool = (char *)debug_alloc_pool_aligned; | ||
| 683 | static u32 dah_first, dah_first_call = 1, dah_used, dah_used_max; | ||
| 684 | |||
| 685 | /* Locking is awkward. The debug code is called from all contexts, | ||
| 686 | * including non maskable interrupts. A normal spinlock is not safe | ||
| 687 | * in NMI context. Try to get the debug allocator lock, if it cannot | ||
| 688 | * be obtained after a second then give up. If the lock could not be | ||
| 689 | * previously obtained on this cpu then only try once. | ||
| 690 | * | ||
| 691 | * sparse has no annotation for "this function _sometimes_ acquires a | ||
| 692 | * lock", so fudge the acquire/release notation. | ||
| 693 | */ | ||
| 694 | static DEFINE_SPINLOCK(dap_lock); | ||
| 695 | static int get_dap_lock(void) | ||
| 696 | __acquires(dap_lock) | ||
| 697 | { | ||
| 698 | static int dap_locked = -1; | ||
| 699 | int count; | ||
| 700 | if (dap_locked == smp_processor_id()) | ||
| 701 | count = 1; | ||
| 702 | else | ||
| 703 | count = 1000; | ||
| 704 | while (1) { | ||
| 705 | if (spin_trylock(&dap_lock)) { | ||
| 706 | dap_locked = -1; | ||
| 707 | return 1; | ||
| 708 | } | ||
| 709 | if (!count--) | ||
| 710 | break; | ||
| 711 | udelay(1000); | ||
| 712 | } | ||
| 713 | dap_locked = smp_processor_id(); | ||
| 714 | __acquire(dap_lock); | ||
| 715 | return 0; | ||
| 716 | } | ||
| 717 | |||
| 718 | void *debug_kmalloc(size_t size, gfp_t flags) | ||
| 719 | { | ||
| 720 | unsigned int rem, h_offset; | ||
| 721 | struct debug_alloc_header *best, *bestprev, *prev, *h; | ||
| 722 | void *p = NULL; | ||
| 723 | if (!get_dap_lock()) { | ||
| 724 | __release(dap_lock); /* we never actually got it */ | ||
| 725 | return NULL; | ||
| 726 | } | ||
| 727 | h = (struct debug_alloc_header *)(debug_alloc_pool + dah_first); | ||
| 728 | if (dah_first_call) { | ||
| 729 | h->size = sizeof(debug_alloc_pool_aligned) - dah_overhead; | ||
| 730 | dah_first_call = 0; | ||
| 731 | } | ||
| 732 | size = ALIGN(size, dah_align); | ||
| 733 | prev = best = bestprev = NULL; | ||
| 734 | while (1) { | ||
| 735 | if (h->size >= size && (!best || h->size < best->size)) { | ||
| 736 | best = h; | ||
| 737 | bestprev = prev; | ||
| 738 | if (h->size == size) | ||
| 739 | break; | ||
| 740 | } | ||
| 741 | if (!h->next) | ||
| 742 | break; | ||
| 743 | prev = h; | ||
| 744 | h = (struct debug_alloc_header *)(debug_alloc_pool + h->next); | ||
| 745 | } | ||
| 746 | if (!best) | ||
| 747 | goto out; | ||
| 748 | rem = best->size - size; | ||
| 749 | /* The pool must always contain at least one header */ | ||
| 750 | if (best->next == 0 && bestprev == NULL && rem < dah_overhead) | ||
| 751 | goto out; | ||
| 752 | if (rem >= dah_overhead) { | ||
| 753 | best->size = size; | ||
| 754 | h_offset = ((char *)best - debug_alloc_pool) + | ||
| 755 | dah_overhead + best->size; | ||
| 756 | h = (struct debug_alloc_header *)(debug_alloc_pool + h_offset); | ||
| 757 | h->size = rem - dah_overhead; | ||
| 758 | h->next = best->next; | ||
| 759 | } else | ||
| 760 | h_offset = best->next; | ||
| 761 | best->caller = __builtin_return_address(0); | ||
| 762 | dah_used += best->size; | ||
| 763 | dah_used_max = max(dah_used, dah_used_max); | ||
| 764 | if (bestprev) | ||
| 765 | bestprev->next = h_offset; | ||
| 766 | else | ||
| 767 | dah_first = h_offset; | ||
| 768 | p = (char *)best + dah_overhead; | ||
| 769 | memset(p, POISON_INUSE, best->size - 1); | ||
| 770 | *((char *)p + best->size - 1) = POISON_END; | ||
| 771 | out: | ||
| 772 | spin_unlock(&dap_lock); | ||
| 773 | return p; | ||
| 774 | } | ||
| 775 | |||
| 776 | void debug_kfree(void *p) | ||
| 777 | { | ||
| 778 | struct debug_alloc_header *h; | ||
| 779 | unsigned int h_offset; | ||
| 780 | if (!p) | ||
| 781 | return; | ||
| 782 | if ((char *)p < debug_alloc_pool || | ||
| 783 | (char *)p >= debug_alloc_pool + sizeof(debug_alloc_pool_aligned)) { | ||
| 784 | kfree(p); | ||
| 785 | return; | ||
| 786 | } | ||
| 787 | if (!get_dap_lock()) { | ||
| 788 | __release(dap_lock); /* we never actually got it */ | ||
| 789 | return; /* memory leak, cannot be helped */ | ||
| 790 | } | ||
| 791 | h = (struct debug_alloc_header *)((char *)p - dah_overhead); | ||
| 792 | memset(p, POISON_FREE, h->size - 1); | ||
| 793 | *((char *)p + h->size - 1) = POISON_END; | ||
| 794 | h->caller = NULL; | ||
| 795 | dah_used -= h->size; | ||
| 796 | h_offset = (char *)h - debug_alloc_pool; | ||
| 797 | if (h_offset < dah_first) { | ||
| 798 | h->next = dah_first; | ||
| 799 | dah_first = h_offset; | ||
| 800 | } else { | ||
| 801 | struct debug_alloc_header *prev; | ||
| 802 | unsigned int prev_offset; | ||
| 803 | prev = (struct debug_alloc_header *)(debug_alloc_pool + | ||
| 804 | dah_first); | ||
| 805 | while (1) { | ||
| 806 | if (!prev->next || prev->next > h_offset) | ||
| 807 | break; | ||
| 808 | prev = (struct debug_alloc_header *) | ||
| 809 | (debug_alloc_pool + prev->next); | ||
| 810 | } | ||
| 811 | prev_offset = (char *)prev - debug_alloc_pool; | ||
| 812 | if (prev_offset + dah_overhead + prev->size == h_offset) { | ||
| 813 | prev->size += dah_overhead + h->size; | ||
| 814 | memset(h, POISON_FREE, dah_overhead - 1); | ||
| 815 | *((char *)h + dah_overhead - 1) = POISON_END; | ||
| 816 | h = prev; | ||
| 817 | h_offset = prev_offset; | ||
| 818 | } else { | ||
| 819 | h->next = prev->next; | ||
| 820 | prev->next = h_offset; | ||
| 821 | } | ||
| 822 | } | ||
| 823 | if (h_offset + dah_overhead + h->size == h->next) { | ||
| 824 | struct debug_alloc_header *next; | ||
| 825 | next = (struct debug_alloc_header *) | ||
| 826 | (debug_alloc_pool + h->next); | ||
| 827 | h->size += dah_overhead + next->size; | ||
| 828 | h->next = next->next; | ||
| 829 | memset(next, POISON_FREE, dah_overhead - 1); | ||
| 830 | *((char *)next + dah_overhead - 1) = POISON_END; | ||
| 831 | } | ||
| 832 | spin_unlock(&dap_lock); | ||
| 833 | } | ||
| 834 | |||
| 835 | void debug_kusage(void) | ||
| 836 | { | ||
| 837 | struct debug_alloc_header *h_free, *h_used; | ||
| 838 | #ifdef CONFIG_IA64 | ||
| 839 | /* FIXME: using dah for ia64 unwind always results in a memory leak. | ||
| 840 | * Fix that memory leak first, then set debug_kusage_one_time = 1 for | ||
| 841 | * all architectures. | ||
| 842 | */ | ||
| 843 | static int debug_kusage_one_time; | ||
| 844 | #else | ||
| 845 | static int debug_kusage_one_time = 1; | ||
| 846 | #endif | ||
| 847 | if (!get_dap_lock()) { | ||
| 848 | __release(dap_lock); /* we never actually got it */ | ||
| 849 | return; | ||
| 850 | } | ||
| 851 | h_free = (struct debug_alloc_header *)(debug_alloc_pool + dah_first); | ||
| 852 | if (dah_first == 0 && | ||
| 853 | (h_free->size == sizeof(debug_alloc_pool_aligned) - dah_overhead || | ||
| 854 | dah_first_call)) | ||
| 855 | goto out; | ||
| 856 | if (!debug_kusage_one_time) | ||
| 857 | goto out; | ||
| 858 | debug_kusage_one_time = 0; | ||
| 859 | kdb_func_printf("debug_kmalloc memory leak dah_first %d\n", dah_first); | ||
| 860 | if (dah_first) { | ||
| 861 | h_used = (struct debug_alloc_header *)debug_alloc_pool; | ||
| 862 | kdb_func_printf("h_used %px size %d\n", h_used, h_used->size); | ||
| 863 | } | ||
| 864 | do { | ||
| 865 | h_used = (struct debug_alloc_header *) | ||
| 866 | ((char *)h_free + dah_overhead + h_free->size); | ||
| 867 | kdb_func_printf("h_used %px size %d caller %px\n", | ||
| 868 | h_used, h_used->size, h_used->caller); | ||
| 869 | h_free = (struct debug_alloc_header *) | ||
| 870 | (debug_alloc_pool + h_free->next); | ||
| 871 | } while (h_free->next); | ||
| 872 | h_used = (struct debug_alloc_header *) | ||
| 873 | ((char *)h_free + dah_overhead + h_free->size); | ||
| 874 | if ((char *)h_used - debug_alloc_pool != | ||
| 875 | sizeof(debug_alloc_pool_aligned)) | ||
| 876 | kdb_func_printf("h_used %px size %d caller %px\n", | ||
| 877 | h_used, h_used->size, h_used->caller); | ||
| 878 | out: | ||
| 879 | spin_unlock(&dap_lock); | ||
| 880 | } | ||
| 881 | |||
| 882 | /* Maintain a small stack of kdb_flags to allow recursion without disturbing | 609 | /* Maintain a small stack of kdb_flags to allow recursion without disturbing |
| 883 | * the global kdb state. | 610 | * the global kdb state. |
| 884 | */ | 611 | */ |
| @@ -147,11 +147,17 @@ static int kdb_ftdump(int argc, const char **argv) · 146 unmodified lines | |||
| 147 | return 0; | 147 | return 0; |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | static kdbtab_t ftdump_cmd = { | ||
| 151 | .name = "ftdump", | ||
| 152 | .func = kdb_ftdump, | ||
| 153 | .usage = "[skip_#entries] [cpu]", | ||
| 154 | .help = "Dump ftrace log; -skip dumps last #entries", | ||
| 155 | .flags = KDB_ENABLE_ALWAYS_SAFE, | ||
| 156 | }; | ||
| 157 | |||
| 150 | static __init int kdb_ftrace_register(void) | 158 | static __init int kdb_ftrace_register(void) |
| 151 | { | 159 | { |
| 152 | kdb_register_flags("ftdump", kdb_ftdump, "[skip_#entries] [cpu]", | 160 | kdb_register(&ftdump_cmd); |
| 153 | "Dump ftrace log; -skip dumps last #entries", 0, | ||
| 154 | KDB_ENABLE_ALWAYS_SAFE); | ||
| 155 | return 0; | 161 | return 0; |
| 156 | } | 162 | } |
| 157 | 163 | ||
| @@ -28,28 +28,26 @@ static int kdb_hello_cmd(int argc, const char **argv) · 27 unmodified lines | |||
| 28 | return 0; | 28 | return 0; |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | static kdbtab_t hello_cmd = { | ||
| 32 | .name = "hello", | ||
| 33 | .func = kdb_hello_cmd, | ||
| 34 | .usage = "[string]", | ||
| 35 | .help = "Say Hello World or Hello [string]", | ||
| 36 | }; | ||
| 31 | 37 | ||
| 32 | static int __init kdb_hello_cmd_init(void) | 38 | static int __init kdb_hello_cmd_init(void) |
| 33 | { | 39 | { |
| 34 | /* | 40 | /* |
| 35 | * Registration of a dynamically added kdb command is done with | 41 | * Registration of a dynamically added kdb command is done with |
| 36 | * kdb_register() with the arguments being: | 42 | * kdb_register(). |
| 37 | * 1: The name of the shell command | ||
| 38 | * 2: The function that processes the command | ||
| 39 | * 3: Description of the usage of any arguments | ||
| 40 | * 4: Descriptive text when you run help | ||
| 41 | * 5: Number of characters to complete the command | ||
| 42 | * 0 == type the whole command | ||
| 43 | * 1 == match both "g" and "go" for example | ||
| 44 | */ | 43 | */ |
| 45 | kdb_register("hello", kdb_hello_cmd, "[string]", | 44 | kdb_register(&hello_cmd); |
| 46 | "Say Hello World or Hello [string]", 0); | ||
| 47 | return 0; | 45 | return 0; |
| 48 | } | 46 | } |
| 49 | 47 | ||
| 50 | static void __exit kdb_hello_cmd_exit(void) | 48 | static void __exit kdb_hello_cmd_exit(void) |
| 51 | { | 49 | { |
| 52 | kdb_unregister("hello"); | 50 | kdb_unregister(&hello_cmd); |
| 53 | } | 51 | } |
| 54 | 52 | ||
| 55 | module_init(kdb_hello_cmd_init); | 53 | module_init(kdb_hello_cmd_init); |