diff options
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); |
