summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/extable.c2
-rw-r--r--kernel/module.c22
-rw-r--r--kernel/profile.c5
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;