aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2009-03-31 15:05:31 -0400
committerRusty Russell <rusty@rustcorp.com.au>2009-03-30 22:35:31 -0400
commite610499e2656e61975affd0af56b26eb73964c84 (patch)
treee870def77ba17f717a8cf2766f0b4ac8c2ae89f3 /kernel/module.c
parent414fd31b2553aaf160ca9b9afe45aa0372b01b92 (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/module.c')
-rw-r--r--kernel/module.c76
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
77static BLOCKING_NOTIFIER_HEAD(module_notify_list); 77static 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 */
80static unsigned long module_addr_min = -1UL, module_addr_max = 0; 80static unsigned long module_addr_min = -1UL, module_addr_max = 0;
81 81
82int register_module_notifier(struct notifier_block * nb) 82int 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 */
2750int is_module_address(unsigned long addr) 2754bool 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 */
2794bool 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 */
2812struct 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
2784struct module *module_text_address(unsigned long addr) 2824struct module *module_text_address(unsigned long addr)
2785{ 2825{
2786 struct module *mod; 2826 struct module *mod;