diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2009-03-31 15:05:31 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2009-03-30 22:35:31 -0400 |
commit | e610499e2656e61975affd0af56b26eb73964c84 (patch) | |
tree | e870def77ba17f717a8cf2766f0b4ac8c2ae89f3 /kernel | |
parent | 414fd31b2553aaf160ca9b9afe45aa0372b01b92 (diff) |
module: __module_address
Impact: New API, cleanup
ksplice wants to know the bounds of a module, not just the module text.
It makes sense to have __module_address. We then implement
is_module_address and __module_text_address in terms of this (and
change is_module_text_address() to bool while we're at it).
Also, add proper kerneldoc for them all.
Cc: Anders Kaseorg <andersk@mit.edu>
Cc: Jeff Arnold <jbarnold@mit.edu>
Cc: Tim Abbott <tabbott@mit.edu>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/module.c | 76 |
1 files changed, 58 insertions, 18 deletions
diff --git a/kernel/module.c b/kernel/module.c index 2f0fddf3c114..bd15a94f91c1 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -76,7 +76,7 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq); | |||
76 | 76 | ||
77 | static BLOCKING_NOTIFIER_HEAD(module_notify_list); | 77 | static BLOCKING_NOTIFIER_HEAD(module_notify_list); |
78 | 78 | ||
79 | /* Bounds of module allocation, for speeding __module_text_address */ | 79 | /* Bounds of module allocation, for speeding __module_address */ |
80 | static unsigned long module_addr_min = -1UL, module_addr_max = 0; | 80 | static unsigned long module_addr_min = -1UL, module_addr_max = 0; |
81 | 81 | ||
82 | int register_module_notifier(struct notifier_block * nb) | 82 | int register_module_notifier(struct notifier_block * nb) |
@@ -2745,29 +2745,31 @@ const struct exception_table_entry *search_module_extables(unsigned long addr) | |||
2745 | } | 2745 | } |
2746 | 2746 | ||
2747 | /* | 2747 | /* |
2748 | * Is this a valid module address? | 2748 | * is_module_address - is this address inside a module? |
2749 | * @addr: the address to check. | ||
2750 | * | ||
2751 | * See is_module_text_address() if you simply want to see if the address | ||
2752 | * is code (not data). | ||
2749 | */ | 2753 | */ |
2750 | int is_module_address(unsigned long addr) | 2754 | bool is_module_address(unsigned long addr) |
2751 | { | 2755 | { |
2752 | struct module *mod; | 2756 | bool ret; |
2753 | 2757 | ||
2754 | preempt_disable(); | 2758 | preempt_disable(); |
2755 | 2759 | ret = __module_address(addr) != NULL; | |
2756 | list_for_each_entry_rcu(mod, &modules, list) { | ||
2757 | if (within_module_core(addr, mod)) { | ||
2758 | preempt_enable(); | ||
2759 | return 1; | ||
2760 | } | ||
2761 | } | ||
2762 | |||
2763 | preempt_enable(); | 2760 | preempt_enable(); |
2764 | 2761 | ||
2765 | return 0; | 2762 | return ret; |
2766 | } | 2763 | } |
2767 | 2764 | ||
2768 | 2765 | /* | |
2769 | /* Is this a valid kernel address? */ | 2766 | * __module_address - get the module which contains an address. |
2770 | __notrace_funcgraph struct module *__module_text_address(unsigned long addr) | 2767 | * @addr: the address. |
2768 | * | ||
2769 | * Must be called with preempt disabled or module mutex held so that | ||
2770 | * module doesn't get freed during this. | ||
2771 | */ | ||
2772 | __notrace_funcgraph struct module *__module_address(unsigned long addr) | ||
2771 | { | 2773 | { |
2772 | struct module *mod; | 2774 | struct module *mod; |
2773 | 2775 | ||
@@ -2775,12 +2777,50 @@ __notrace_funcgraph struct module *__module_text_address(unsigned long addr) | |||
2775 | return NULL; | 2777 | return NULL; |
2776 | 2778 | ||
2777 | list_for_each_entry_rcu(mod, &modules, list) | 2779 | list_for_each_entry_rcu(mod, &modules, list) |
2778 | if (within(addr, mod->module_init, mod->init_text_size) | 2780 | if (within_module_core(addr, mod) |
2779 | || within(addr, mod->module_core, mod->core_text_size)) | 2781 | || within_module_init(addr, mod)) |
2780 | return mod; | 2782 | return mod; |
2781 | return NULL; | 2783 | return NULL; |
2782 | } | 2784 | } |
2783 | 2785 | ||
2786 | /* | ||
2787 | * is_module_text_address - is this address inside module code? | ||
2788 | * @addr: the address to check. | ||
2789 | * | ||
2790 | * See is_module_address() if you simply want to see if the address is | ||
2791 | * anywhere in a module. See kernel_text_address() for testing if an | ||
2792 | * address corresponds to kernel or module code. | ||
2793 | */ | ||
2794 | bool is_module_text_address(unsigned long addr) | ||
2795 | { | ||
2796 | bool ret; | ||
2797 | |||
2798 | preempt_disable(); | ||
2799 | ret = __module_text_address(addr) != NULL; | ||
2800 | preempt_enable(); | ||
2801 | |||
2802 | return ret; | ||
2803 | } | ||
2804 | |||
2805 | /* | ||
2806 | * __module_text_address - get the module whose code contains an address. | ||
2807 | * @addr: the address. | ||
2808 | * | ||
2809 | * Must be called with preempt disabled or module mutex held so that | ||
2810 | * module doesn't get freed during this. | ||
2811 | */ | ||
2812 | struct module *__module_text_address(unsigned long addr) | ||
2813 | { | ||
2814 | struct module *mod = __module_address(addr); | ||
2815 | if (mod) { | ||
2816 | /* Make sure it's within the text section. */ | ||
2817 | if (!within(addr, mod->module_init, mod->init_text_size) | ||
2818 | && !within(addr, mod->module_core, mod->core_text_size)) | ||
2819 | mod = NULL; | ||
2820 | } | ||
2821 | return mod; | ||
2822 | } | ||
2823 | |||
2784 | struct module *module_text_address(unsigned long addr) | 2824 | struct module *module_text_address(unsigned long addr) |
2785 | { | 2825 | { |
2786 | struct module *mod; | 2826 | struct module *mod; |