Skip to content

Commit

Permalink
[PATCH] flush icache early when loading module
Browse files Browse the repository at this point in the history
Change the sequence of operations performed during module loading to flush
the instruction cache before module parameters are processed.  If a module
has parameters of an unusual type that cannot be handled using the standard
accessor functions param_set_xxx and param_get_xxx, it has to to provide a
set of accessor functions for this type.  This requires module code to be
executed during parameter processing, which is of course only possible
after the icache has been flushed.

Signed-off-by: Thomas Koeller <thomas@koeller.dyndns.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Thomas Koeller authored and Linus Torvalds committed Sep 7, 2005
1 parent 19b4946 commit 378bac8
Showing 1 changed file with 19 additions and 14 deletions.
33 changes: 19 additions & 14 deletions kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -1509,6 +1509,7 @@ static struct module *load_module(void __user *umod,
long err = 0;
void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
struct exception_table_entry *extable;
mm_segment_t old_fs;

DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
umod, len, uargs);
Expand Down Expand Up @@ -1779,6 +1780,24 @@ static struct module *load_module(void __user *umod,
if (err < 0)
goto cleanup;

/* flush the icache in correct context */
old_fs = get_fs();
set_fs(KERNEL_DS);

/*
* Flush the instruction cache, since we've played with text.
* Do it before processing of module parameters, so the module
* can provide parameter accessor functions of its own.
*/
if (mod->module_init)
flush_icache_range((unsigned long)mod->module_init,
(unsigned long)mod->module_init
+ mod->init_size);
flush_icache_range((unsigned long)mod->module_core,
(unsigned long)mod->module_core + mod->core_size);

set_fs(old_fs);

mod->args = args;
if (obsparmindex) {
err = obsolete_params(mod->name, mod->args,
Expand Down Expand Up @@ -1860,7 +1879,6 @@ sys_init_module(void __user *umod,
const char __user *uargs)
{
struct module *mod;
mm_segment_t old_fs = get_fs();
int ret = 0;

/* Must have permission */
Expand All @@ -1878,19 +1896,6 @@ sys_init_module(void __user *umod,
return PTR_ERR(mod);
}

/* flush the icache in correct context */
set_fs(KERNEL_DS);

/* Flush the instruction cache, since we've played with text */
if (mod->module_init)
flush_icache_range((unsigned long)mod->module_init,
(unsigned long)mod->module_init
+ mod->init_size);
flush_icache_range((unsigned long)mod->module_core,
(unsigned long)mod->module_core + mod->core_size);

set_fs(old_fs);

/* Now sew it into the lists. They won't access us, since
strong_try_module_get() will fail. */
stop_machine_run(__link_module, mod, NR_CPUS);
Expand Down

0 comments on commit 378bac8

Please sign in to comment.