diff options
author | Thomas Koeller <thomas@koeller.dyndns.org> | 2005-09-06 18:17:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-07 19:57:26 -0400 |
commit | 378bac820be6a0ec95df8151524de73ad2b2d2ac (patch) | |
tree | 457827b58dcbf923e151b08128d84c33d13c1149 /kernel/module.c | |
parent | 19b4946ca9d1e35d4c641dcebe27378de34f3ddd (diff) |
[PATCH] flush icache early when loading module
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>
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/kernel/module.c b/kernel/module.c index c32995fbd8fd..4b39d3793c72 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -1509,6 +1509,7 @@ static struct module *load_module(void __user *umod, | |||
1509 | long err = 0; | 1509 | long err = 0; |
1510 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ | 1510 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ |
1511 | struct exception_table_entry *extable; | 1511 | struct exception_table_entry *extable; |
1512 | mm_segment_t old_fs; | ||
1512 | 1513 | ||
1513 | DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n", | 1514 | DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n", |
1514 | umod, len, uargs); | 1515 | umod, len, uargs); |
@@ -1779,6 +1780,24 @@ static struct module *load_module(void __user *umod, | |||
1779 | if (err < 0) | 1780 | if (err < 0) |
1780 | goto cleanup; | 1781 | goto cleanup; |
1781 | 1782 | ||
1783 | /* flush the icache in correct context */ | ||
1784 | old_fs = get_fs(); | ||
1785 | set_fs(KERNEL_DS); | ||
1786 | |||
1787 | /* | ||
1788 | * Flush the instruction cache, since we've played with text. | ||
1789 | * Do it before processing of module parameters, so the module | ||
1790 | * can provide parameter accessor functions of its own. | ||
1791 | */ | ||
1792 | if (mod->module_init) | ||
1793 | flush_icache_range((unsigned long)mod->module_init, | ||
1794 | (unsigned long)mod->module_init | ||
1795 | + mod->init_size); | ||
1796 | flush_icache_range((unsigned long)mod->module_core, | ||
1797 | (unsigned long)mod->module_core + mod->core_size); | ||
1798 | |||
1799 | set_fs(old_fs); | ||
1800 | |||
1782 | mod->args = args; | 1801 | mod->args = args; |
1783 | if (obsparmindex) { | 1802 | if (obsparmindex) { |
1784 | err = obsolete_params(mod->name, mod->args, | 1803 | err = obsolete_params(mod->name, mod->args, |
@@ -1860,7 +1879,6 @@ sys_init_module(void __user *umod, | |||
1860 | const char __user *uargs) | 1879 | const char __user *uargs) |
1861 | { | 1880 | { |
1862 | struct module *mod; | 1881 | struct module *mod; |
1863 | mm_segment_t old_fs = get_fs(); | ||
1864 | int ret = 0; | 1882 | int ret = 0; |
1865 | 1883 | ||
1866 | /* Must have permission */ | 1884 | /* Must have permission */ |
@@ -1878,19 +1896,6 @@ sys_init_module(void __user *umod, | |||
1878 | return PTR_ERR(mod); | 1896 | return PTR_ERR(mod); |
1879 | } | 1897 | } |
1880 | 1898 | ||
1881 | /* flush the icache in correct context */ | ||
1882 | set_fs(KERNEL_DS); | ||
1883 | |||
1884 | /* Flush the instruction cache, since we've played with text */ | ||
1885 | if (mod->module_init) | ||
1886 | flush_icache_range((unsigned long)mod->module_init, | ||
1887 | (unsigned long)mod->module_init | ||
1888 | + mod->init_size); | ||
1889 | flush_icache_range((unsigned long)mod->module_core, | ||
1890 | (unsigned long)mod->module_core + mod->core_size); | ||
1891 | |||
1892 | set_fs(old_fs); | ||
1893 | |||
1894 | /* Now sew it into the lists. They won't access us, since | 1899 | /* Now sew it into the lists. They won't access us, since |
1895 | strong_try_module_get() will fail. */ | 1900 | strong_try_module_get() will fail. */ |
1896 | stop_machine_run(__link_module, mod, NR_CPUS); | 1901 | stop_machine_run(__link_module, mod, NR_CPUS); |