diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/extable.c | 2 | ||||
| -rw-r--r-- | kernel/module.c | 22 | ||||
| -rw-r--r-- | kernel/profile.c | 5 |
3 files changed, 21 insertions, 8 deletions
diff --git a/kernel/extable.c b/kernel/extable.c index d49099854024..6f1fb8c6b75b 100644 --- a/kernel/extable.c +++ b/kernel/extable.c @@ -17,10 +17,10 @@ */ #include <linux/module.h> #include <asm/uaccess.h> +#include <asm/sections.h> extern const struct exception_table_entry __start___ex_table[]; extern const struct exception_table_entry __stop___ex_table[]; -extern char _stext[], _etext[], _sinittext[], _einittext[]; /* Given an address, look for it in the exception tables. */ const struct exception_table_entry *search_exception_tables(unsigned long addr) diff --git a/kernel/module.c b/kernel/module.c index ea1cf83ee2b3..58d73701bbde 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -98,6 +98,17 @@ int init_module(void) } EXPORT_SYMBOL(init_module); +/* A thread that wants to hold a reference to a module only while it + * is running can call ths to safely exit. + * nfsd and lockd use this. + */ +void __module_put_and_exit(struct module *mod, long code) +{ + module_put(mod); + do_exit(code); +} +EXPORT_SYMBOL(__module_put_and_exit); + /* Find a module section: 0 means not found. */ static unsigned int find_sec(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, @@ -374,9 +385,9 @@ static void module_unload_init(struct module *mod) INIT_LIST_HEAD(&mod->modules_which_use_me); for (i = 0; i < NR_CPUS; i++) - atomic_set(&mod->ref[i].count, 0); + local_set(&mod->ref[i].count, 0); /* Hold reference count during initialization. */ - atomic_set(&mod->ref[smp_processor_id()].count, 1); + local_set(&mod->ref[smp_processor_id()].count, 1); /* Backwards compatibility macros put refcount during init. */ mod->waiter = current; } @@ -599,7 +610,7 @@ unsigned int module_refcount(struct module *mod) unsigned int i, total = 0; for (i = 0; i < NR_CPUS; i++) - total += atomic_read(&mod->ref[i].count); + total += local_read(&mod->ref[i].count); return total; } EXPORT_SYMBOL(module_refcount); @@ -610,7 +621,10 @@ static void free_module(struct module *mod); #ifdef CONFIG_MODULE_FORCE_UNLOAD static inline int try_force(unsigned int flags) { - return (flags & O_TRUNC); + int ret = (flags & O_TRUNC); + if (ret) + tainted |= TAINT_FORCED_MODULE; + return ret; } #else static inline int try_force(unsigned int flags) diff --git a/kernel/profile.c b/kernel/profile.c index 4f6d22ce33f2..5c02ac0fbbda 100644 --- a/kernel/profile.c +++ b/kernel/profile.c @@ -8,8 +8,7 @@ #include <linux/bootmem.h> #include <linux/notifier.h> #include <linux/mm.h> - -extern char _stext, _etext; +#include <asm/sections.h> unsigned int * prof_buffer; unsigned long prof_len; @@ -36,7 +35,7 @@ void __init profile_init(void) return; /* only text is profiled */ - prof_len = (unsigned long) &_etext - (unsigned long) &_stext; + prof_len = _etext - _stext; prof_len >>= prof_shift; size = prof_len * sizeof(unsigned int) + PAGE_SIZE - 1; |
