Commit 378bac820be6a0ec95df8151524de73ad2b2d2ac

Authored by Thomas Koeller
Committed by Linus Torvalds
1 parent 19b4946ca9

[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>

Showing 1 changed file with 19 additions and 14 deletions Side-by-side Diff

... ... @@ -1509,6 +1509,7 @@
1509 1509 long err = 0;
1510 1510 void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
1511 1511 struct exception_table_entry *extable;
  1512 + mm_segment_t old_fs;
1512 1513  
1513 1514 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
1514 1515 umod, len, uargs);
... ... @@ -1779,6 +1780,24 @@
1779 1780 if (err < 0)
1780 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 1801 mod->args = args;
1783 1802 if (obsparmindex) {
1784 1803 err = obsolete_params(mod->name, mod->args,
... ... @@ -1860,7 +1879,6 @@
1860 1879 const char __user *uargs)
1861 1880 {
1862 1881 struct module *mod;
1863   - mm_segment_t old_fs = get_fs();
1864 1882 int ret = 0;
1865 1883  
1866 1884 /* Must have permission */
... ... @@ -1877,19 +1895,6 @@
1877 1895 up(&module_mutex);
1878 1896 return PTR_ERR(mod);
1879 1897 }
1880   -
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 1898  
1894 1899 /* Now sew it into the lists. They won't access us, since
1895 1900 strong_try_module_get() will fail. */