[PATCH] Module rewrite 19/20: module_bound removal

From: Rusty Russell (rusty@rustcorp.com.au)
Date: Tue Sep 24 2002 - 22:19:32 EST


Name: module_bound removal patch
Author: Rusty Russell
Status: Tested on 2.5.38
Depends: Module/extable.patch.gz

D: This removes the mod_bound macro, and its usage in determining
D: whether an address is in the kernel (on some archs). It is
D: replaced with a module_is_address() function which does the right
D: locking, and finally makes the modules list static to module.c.

diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .19547-linux-2.5.38/arch/i386/kernel/traps.c .19547-linux-2.5.38.updated/arch/i386/kernel/traps.c
--- .19547-linux-2.5.38/arch/i386/kernel/traps.c 2002-09-25 10:43:21.000000000 +1000
+++ .19547-linux-2.5.38.updated/arch/i386/kernel/traps.c 2002-09-25 10:43:44.000000000 +1000
@@ -92,43 +92,15 @@ static int kstack_depth_to_print = 24;
  * be the address of a calling routine
  */
 
-#ifdef CONFIG_MODULES
-
-/* FIXME: Accessed without a lock --RR */
-extern struct list_head modules;
-
 static inline int kernel_text_address(unsigned long addr)
 {
- int retval = 0;
- struct module *mod;
-
         if (addr >= (unsigned long) &_stext &&
             addr <= (unsigned long) &_etext)
                 return 1;
 
- list_for_each_entry(mod, &modules, list) {
- /* mod_bound tests for addr being inside the vmalloc'ed
- * module area. Of course it'd be better to test only
- * for the .text subset... */
- if (mod_bound((void *)addr, 0, mod)) {
- retval = 1;
- break;
- }
- }
-
- return retval;
-}
-
-#else
-
-static inline int kernel_text_address(unsigned long addr)
-{
- return (addr >= (unsigned long) &_stext &&
- addr <= (unsigned long) &_etext);
+ return module_is_address(addr);
 }
 
-#endif
-
 void show_trace(unsigned long * stack)
 {
         int i;
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .19547-linux-2.5.38/arch/m68k/kernel/traps.c .19547-linux-2.5.38.updated/arch/m68k/kernel/traps.c
--- .19547-linux-2.5.38/arch/m68k/kernel/traps.c 2002-07-25 10:13:02.000000000 +1000
+++ .19547-linux-2.5.38.updated/arch/m68k/kernel/traps.c 2002-09-25 10:43:44.000000000 +1000
@@ -820,30 +820,16 @@ asmlinkage void buserr_c(struct frame *f
 
 
 static int kstack_depth_to_print = 48;
-extern struct module kernel_module;
 
 static inline int kernel_text_address(unsigned long addr)
 {
-#ifdef CONFIG_MODULES
- struct module *mod;
-#endif
         extern char _stext, _etext;
 
         if (addr >= (unsigned long) &_stext &&
             addr <= (unsigned long) &_etext)
                 return 1;
 
-#ifdef CONFIG_MODULES
- for (mod = module_list; mod != &kernel_module; mod = mod->next) {
- /* mod_bound tests for addr being inside the vmalloc'ed
- * module area. Of course it'd be better to test only
- * for the .text subset... */
- if (mod_bound(addr, 0, mod))
- return 1;
- }
-#endif
-
- return 0;
+ return module_is_address(addr);
 }
 
 void show_trace(unsigned long *stack)
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .19547-linux-2.5.38/arch/s390/kernel/traps.c .19547-linux-2.5.38.updated/arch/s390/kernel/traps.c
--- .19547-linux-2.5.38/arch/s390/kernel/traps.c 2002-07-25 10:13:05.000000000 +1000
+++ .19547-linux-2.5.38.updated/arch/s390/kernel/traps.c 2002-09-25 10:43:44.000000000 +1000
@@ -70,43 +70,15 @@ static int kstack_depth_to_print = 12;
  */
 extern char _stext, _etext;
 
-#ifdef CONFIG_MODULES
-
-extern struct module *module_list;
-extern struct module kernel_module;
-
 static inline int kernel_text_address(unsigned long addr)
 {
- int retval = 0;
- struct module *mod;
-
         if (addr >= (unsigned long) &_stext &&
             addr <= (unsigned long) &_etext)
                 return 1;
 
- for (mod = module_list; mod != &kernel_module; mod = mod->next) {
- /* mod_bound tests for addr being inside the vmalloc'ed
- * module area. Of course it'd be better to test only
- * for the .text subset... */
- if (mod_bound(addr, 0, mod)) {
- retval = 1;
- break;
- }
- }
-
- return retval;
-}
-
-#else
-
-static inline int kernel_text_address(unsigned long addr)
-{
- return (addr >= (unsigned long) &_stext &&
- addr <= (unsigned long) &_etext);
+ return module_is_address(addr);
 }
 
-#endif
-
 void show_trace(unsigned long * stack)
 {
         unsigned long backchain, low_addr, high_addr, ret_addr;
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .19547-linux-2.5.38/arch/s390x/kernel/traps.c .19547-linux-2.5.38.updated/arch/s390x/kernel/traps.c
--- .19547-linux-2.5.38/arch/s390x/kernel/traps.c 2002-07-25 10:13:05.000000000 +1000
+++ .19547-linux-2.5.38.updated/arch/s390x/kernel/traps.c 2002-09-25 10:43:44.000000000 +1000
@@ -72,43 +72,15 @@ static int kstack_depth_to_print = 20;
  */
 extern char _stext, _etext;
 
-#ifdef CONFIG_MODULES
-
-extern struct module *module_list;
-extern struct module kernel_module;
-
 static inline int kernel_text_address(unsigned long addr)
 {
- int retval = 0;
- struct module *mod;
-
         if (addr >= (unsigned long) &_stext &&
             addr <= (unsigned long) &_etext)
                 return 1;
 
- for (mod = module_list; mod != &kernel_module; mod = mod->next) {
- /* mod_bound tests for addr being inside the vmalloc'ed
- * module area. Of course it'd be better to test only
- * for the .text subset... */
- if (mod_bound(addr, 0, mod)) {
- retval = 1;
- break;
- }
- }
-
- return retval;
-}
-
-#else
-
-static inline int kernel_text_address(unsigned long addr)
-{
- return (addr >= (unsigned long) &_stext &&
- addr <= (unsigned long) &_etext);
+ return module_is_address(addr);
 }
 
-#endif
-
 void show_trace(unsigned long * stack)
 {
         unsigned long backchain, low_addr, high_addr, ret_addr;
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .19547-linux-2.5.38/arch/um/kernel/sysrq.c .19547-linux-2.5.38.updated/arch/um/kernel/sysrq.c
--- .19547-linux-2.5.38/arch/um/kernel/sysrq.c 2002-09-18 16:03:56.000000000 +1000
+++ .19547-linux-2.5.38.updated/arch/um/kernel/sysrq.c 2002-09-25 10:43:44.000000000 +1000
@@ -16,44 +16,15 @@
   * kernel, or in the vmalloc'ed module regions, it *may*
   * be the address of a calling routine
   */
-
-#ifdef CONFIG_MODULES
-
-extern struct module *module_list;
-extern struct module kernel_module;
-
 static inline int kernel_text_address(unsigned long addr)
 {
- int retval = 0;
- struct module *mod;
-
         if (addr >= (unsigned long) &_stext &&
             addr <= (unsigned long) &_etext)
                 return 1;
 
- for (mod = module_list; mod != &kernel_module; mod = mod->next) {
- /* mod_bound tests for addr being inside the vmalloc'ed
- * module area. Of course it'd be better to test only
- * for the .text subset... */
- if (mod_bound(addr, 0, mod)) {
- retval = 1;
- break;
- }
- }
-
- return retval;
-}
-
-#else
-
-static inline int kernel_text_address(unsigned long addr)
-{
- return (addr >= (unsigned long) &_stext &&
- addr <= (unsigned long) &_etext);
+ return module_is_address(addr);
 }
 
-#endif
-
 void show_trace(unsigned long * stack)
 {
         int i;
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .19547-linux-2.5.38/arch/x86_64/kernel/traps.c .19547-linux-2.5.38.updated/arch/x86_64/kernel/traps.c
--- .19547-linux-2.5.38/arch/x86_64/kernel/traps.c 2002-07-25 10:13:05.000000000 +1000
+++ .19547-linux-2.5.38.updated/arch/x86_64/kernel/traps.c 2002-09-25 10:43:44.000000000 +1000
@@ -111,44 +111,15 @@ int printk_address(unsigned long address
 }
 #endif
 
-
-#ifdef CONFIG_MODULES
-
-extern struct module *module_list;
-extern struct module kernel_module;
-
 static inline int kernel_text_address(unsigned long addr)
 {
- int retval = 0;
- struct module *mod;
-
- if (addr >= (unsigned long) &_stext &&
- addr <= (unsigned long) &_etext)
- return 1;
-
- for (mod = module_list; mod != &kernel_module; mod = mod->next) {
- /* mod_bound tests for addr being inside the vmalloc'ed
- * module area. Of course it'd be better to test only
- * for the .text subset... */
- if (mod_bound(addr, 0, mod)) {
- retval = 1;
- break;
- }
- }
-
- return retval;
-}
-
-#else
+ if (addr >= (unsigned long) &_stext &&
+ addr <= (unsigned long) &_etext)
+ return 1;
 
-static inline int kernel_text_address(unsigned long addr)
-{
- return (addr >= (unsigned long) &_stext &&
- addr <= (unsigned long) &_etext);
+ return module_is_address(addr);
 }
 
-#endif
-
 /*
  * These constants are for searching for possible module text
  * segments. MODULE_RANGE is a guess of how much space is likely
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .19547-linux-2.5.38/include/linux/module.h .19547-linux-2.5.38.updated/include/linux/module.h
--- .19547-linux-2.5.38/include/linux/module.h 2002-09-25 10:43:21.000000000 +1000
+++ .19547-linux-2.5.38.updated/include/linux/module.h 2002-09-25 10:43:44.000000000 +1000
@@ -244,6 +244,9 @@ int module_finalize(const Elf_Ehdr *hdr,
 /* Free memory returned from module_core_alloc/module_init_alloc */
 void module_free(struct module *mod, void *module_region);
 
+/* Is this address in a module? */
+int module_is_address(unsigned long addr);
+
 #ifdef CONFIG_MODULE_UNLOAD
 #define symbol_put(x) __put_symbol(#x)
 
@@ -311,6 +314,12 @@ search_exception_tables(unsigned long ad
                               add);
 }
 
+/* Is this address in a module? */
+static inline int module_is_address(unsigned long addr)
+{
+ return 0;
+}
+
 /* Get/put a kernel symbol (calls should be symmetric) */
 #define symbol_get(x) ((typeof(&x))(0))
 
@@ -354,14 +363,6 @@ extern int module_dummy_usage;
 #define GET_USE_COUNT(module) (module_dummy_usage)
 #define MOD_IN_USE 0
 #define __MODULE_STRING(x) __stringify(x)
-#define __mod_between(a_start, a_len, b_start, b_len) \
-(((a_start) >= (b_start) && (a_start) <= (b_start)+(b_len)) \
- || ((a_start)+(a_len) >= (b_start) \
- && (a_start)+(a_len) <= (b_start)+(b_len)))
-#define mod_bound(p, n, m) \
-(((m)->module_init \
- && __mod_between((p),(n),(m)->module_init,(m)->init_size)) \
- || __mod_between((p),(n),(m)->module_core,(m)->core_size))
 
 #ifdef __GENKSYMS__
 /* We want the EXPORT_SYMBOL tag left intact for recognition. */
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .19547-linux-2.5.38/kernel/module.c .19547-linux-2.5.38.updated/kernel/module.c
--- .19547-linux-2.5.38/kernel/module.c 2002-09-25 10:43:21.000000000 +1000
+++ .19547-linux-2.5.38.updated/kernel/module.c 2002-09-25 10:44:55.000000000 +1000
@@ -54,9 +54,9 @@ static struct exception_table kernel_ext
 static struct kernel_symbol_group kernel_symbols;
 static struct kernel_symbol_group kernel_gpl_symbols;
 
-/* List of modules, protected by module_mutex */
+/* List of modules, protected by module_mutex AND module_lock */
 static DECLARE_MUTEX(module_mutex);
-LIST_HEAD(modules); /* FIXME: Accessed w/o lock on oops by some archs */
+static LIST_HEAD(modules);
 
 /* Convenient structure for holding init and core sizes */
 struct sizes
@@ -583,8 +583,8 @@ unsigned long find_symbol_internal(Elf_S
 static void free_module(struct module *mod)
 {
         /* Delete from various lists */
- list_del(&mod->list);
         spin_lock_irq(&module_lock);
+ list_del(&mod->list);
         list_del(&mod->symbols.list);
         list_del(&mod->gpl_symbols.list);
         list_del(&mod->extable.list);
@@ -1174,8 +1174,8 @@ sys_init_module(void *umod,
         spin_lock_irq(&module_lock);
         list_add(&mod->symbols.list, &kernel_symbols.list);
         list_add(&mod->gpl_symbols.list, &kernel_symbols.list);
- spin_unlock_irq(&module_lock);
         list_add(&mod->list, &modules);
+ spin_unlock_irq(&module_lock);
 
         module_free(mod, mod->module_init);
         mod->module_init = NULL;
@@ -1213,6 +1213,31 @@ const struct exception_table_entry *sear
         return found;
 }
 
+/* Is this a valid kernel address? */
+int module_is_address(unsigned long addr)
+{
+ unsigned long flags;
+ struct module *mod;
+ int ret = 0;
+
+ spin_lock_irqsave(&module_lock, flags);
+ list_for_each_entry(mod, &modules, list) {
+ if (mod->module_init
+ && (void *)addr >= mod->module_init
+ && (void *)addr < mod->module_init + mod->init_size) {
+ ret = 1;
+ break;
+ }
+ if ((void *)addr >= mod->module_core
+ && (void *)addr < mod->module_core + mod->core_size) {
+ ret = 1;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&module_lock, flags);
+ return ret;
+}
+
 /* Called by the /proc file system to return a current list of
    modules. Al Viro came up with this interface as an "improvement".
    God save us from any more such interface improvements. */

--
  Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Sep 30 2002 - 22:00:21 EST