aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c92
1 files changed, 91 insertions, 1 deletions
diff --git a/kernel/module.c b/kernel/module.c
index b7205f67cfaf..0d8d21ee792c 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -46,6 +46,8 @@
46#include <asm/cacheflush.h> 46#include <asm/cacheflush.h>
47#include <linux/license.h> 47#include <linux/license.h>
48#include <asm/sections.h> 48#include <asm/sections.h>
49#include <linux/tracepoint.h>
50#include <linux/ftrace.h>
49 51
50#if 0 52#if 0
51#define DEBUGP printk 53#define DEBUGP printk
@@ -1430,6 +1432,9 @@ static void free_module(struct module *mod)
1430 /* Module unload stuff */ 1432 /* Module unload stuff */
1431 module_unload_free(mod); 1433 module_unload_free(mod);
1432 1434
1435 /* release any pointers to mcount in this module */
1436 ftrace_release(mod->module_core, mod->core_size);
1437
1433 /* This may be NULL, but that's OK */ 1438 /* This may be NULL, but that's OK */
1434 module_free(mod, mod->module_init); 1439 module_free(mod, mod->module_init);
1435 kfree(mod->args); 1440 kfree(mod->args);
@@ -1834,6 +1839,7 @@ static noinline struct module *load_module(void __user *umod,
1834 Elf_Ehdr *hdr; 1839 Elf_Ehdr *hdr;
1835 Elf_Shdr *sechdrs; 1840 Elf_Shdr *sechdrs;
1836 char *secstrings, *args, *modmagic, *strtab = NULL; 1841 char *secstrings, *args, *modmagic, *strtab = NULL;
1842 char *staging;
1837 unsigned int i; 1843 unsigned int i;
1838 unsigned int symindex = 0; 1844 unsigned int symindex = 0;
1839 unsigned int strindex = 0; 1845 unsigned int strindex = 0;
@@ -1860,9 +1866,13 @@ static noinline struct module *load_module(void __user *umod,
1860 unsigned int markersindex; 1866 unsigned int markersindex;
1861 unsigned int markersstringsindex; 1867 unsigned int markersstringsindex;
1862 unsigned int verboseindex; 1868 unsigned int verboseindex;
1869 unsigned int tracepointsindex;
1870 unsigned int tracepointsstringsindex;
1871 unsigned int mcountindex;
1863 struct module *mod; 1872 struct module *mod;
1864 long err = 0; 1873 long err = 0;
1865 void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ 1874 void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
1875 void *mseg;
1866 struct exception_table_entry *extable; 1876 struct exception_table_entry *extable;
1867 mm_segment_t old_fs; 1877 mm_segment_t old_fs;
1868 1878
@@ -1989,6 +1999,14 @@ static noinline struct module *load_module(void __user *umod,
1989 goto free_hdr; 1999 goto free_hdr;
1990 } 2000 }
1991 2001
2002 staging = get_modinfo(sechdrs, infoindex, "staging");
2003 if (staging) {
2004 add_taint_module(mod, TAINT_CRAP);
2005 printk(KERN_WARNING "%s: module is from the staging directory,"
2006 " the quality is unknown, you have been warned.\n",
2007 mod->name);
2008 }
2009
1992 /* Now copy in args */ 2010 /* Now copy in args */
1993 args = strndup_user(uargs, ~0UL >> 1); 2011 args = strndup_user(uargs, ~0UL >> 1);
1994 if (IS_ERR(args)) { 2012 if (IS_ERR(args)) {
@@ -2147,6 +2165,12 @@ static noinline struct module *load_module(void __user *umod,
2147 markersstringsindex = find_sec(hdr, sechdrs, secstrings, 2165 markersstringsindex = find_sec(hdr, sechdrs, secstrings,
2148 "__markers_strings"); 2166 "__markers_strings");
2149 verboseindex = find_sec(hdr, sechdrs, secstrings, "__verbose"); 2167 verboseindex = find_sec(hdr, sechdrs, secstrings, "__verbose");
2168 tracepointsindex = find_sec(hdr, sechdrs, secstrings, "__tracepoints");
2169 tracepointsstringsindex = find_sec(hdr, sechdrs, secstrings,
2170 "__tracepoints_strings");
2171
2172 mcountindex = find_sec(hdr, sechdrs, secstrings,
2173 "__mcount_loc");
2150 2174
2151 /* Now do relocations. */ 2175 /* Now do relocations. */
2152 for (i = 1; i < hdr->e_shnum; i++) { 2176 for (i = 1; i < hdr->e_shnum; i++) {
@@ -2174,6 +2198,12 @@ static noinline struct module *load_module(void __user *umod,
2174 mod->num_markers = 2198 mod->num_markers =
2175 sechdrs[markersindex].sh_size / sizeof(*mod->markers); 2199 sechdrs[markersindex].sh_size / sizeof(*mod->markers);
2176#endif 2200#endif
2201#ifdef CONFIG_TRACEPOINTS
2202 mod->tracepoints = (void *)sechdrs[tracepointsindex].sh_addr;
2203 mod->num_tracepoints =
2204 sechdrs[tracepointsindex].sh_size / sizeof(*mod->tracepoints);
2205#endif
2206
2177 2207
2178 /* Find duplicate symbols */ 2208 /* Find duplicate symbols */
2179 err = verify_export_symbols(mod); 2209 err = verify_export_symbols(mod);
@@ -2192,12 +2222,22 @@ static noinline struct module *load_module(void __user *umod,
2192 2222
2193 add_kallsyms(mod, sechdrs, symindex, strindex, secstrings); 2223 add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
2194 2224
2225 if (!mod->taints) {
2195#ifdef CONFIG_MARKERS 2226#ifdef CONFIG_MARKERS
2196 if (!mod->taints)
2197 marker_update_probe_range(mod->markers, 2227 marker_update_probe_range(mod->markers,
2198 mod->markers + mod->num_markers); 2228 mod->markers + mod->num_markers);
2199#endif 2229#endif
2200 dynamic_printk_setup(sechdrs, verboseindex); 2230 dynamic_printk_setup(sechdrs, verboseindex);
2231#ifdef CONFIG_TRACEPOINTS
2232 tracepoint_update_probe_range(mod->tracepoints,
2233 mod->tracepoints + mod->num_tracepoints);
2234#endif
2235 }
2236
2237 /* sechdrs[0].sh_size is always zero */
2238 mseg = (void *)sechdrs[mcountindex].sh_addr;
2239 ftrace_init_module(mseg, mseg + sechdrs[mcountindex].sh_size);
2240
2201 err = module_finalize(hdr, sechdrs, mod); 2241 err = module_finalize(hdr, sechdrs, mod);
2202 if (err < 0) 2242 if (err < 0)
2203 goto cleanup; 2243 goto cleanup;
@@ -2267,6 +2307,7 @@ static noinline struct module *load_module(void __user *umod,
2267 cleanup: 2307 cleanup:
2268 kobject_del(&mod->mkobj.kobj); 2308 kobject_del(&mod->mkobj.kobj);
2269 kobject_put(&mod->mkobj.kobj); 2309 kobject_put(&mod->mkobj.kobj);
2310 ftrace_release(mod->module_core, mod->core_size);
2270 free_unload: 2311 free_unload:
2271 module_unload_free(mod); 2312 module_unload_free(mod);
2272 module_free(mod, mod->module_init); 2313 module_free(mod, mod->module_init);
@@ -2587,6 +2628,8 @@ static char *module_flags(struct module *mod, char *buf)
2587 buf[bx++] = 'P'; 2628 buf[bx++] = 'P';
2588 if (mod->taints & (1 << TAINT_FORCED_MODULE)) 2629 if (mod->taints & (1 << TAINT_FORCED_MODULE))
2589 buf[bx++] = 'F'; 2630 buf[bx++] = 'F';
2631 if (mod->taints & (1 << TAINT_CRAP))
2632 buf[bx++] = 'C';
2590 /* 2633 /*
2591 * TAINT_FORCED_RMMOD: could be added. 2634 * TAINT_FORCED_RMMOD: could be added.
2592 * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't 2635 * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
@@ -2748,3 +2791,50 @@ void module_update_markers(void)
2748 mutex_unlock(&module_mutex); 2791 mutex_unlock(&module_mutex);
2749} 2792}
2750#endif 2793#endif
2794
2795#ifdef CONFIG_TRACEPOINTS
2796void module_update_tracepoints(void)
2797{
2798 struct module *mod;
2799
2800 mutex_lock(&module_mutex);
2801 list_for_each_entry(mod, &modules, list)
2802 if (!mod->taints)
2803 tracepoint_update_probe_range(mod->tracepoints,
2804 mod->tracepoints + mod->num_tracepoints);
2805 mutex_unlock(&module_mutex);
2806}
2807
2808/*
2809 * Returns 0 if current not found.
2810 * Returns 1 if current found.
2811 */
2812int module_get_iter_tracepoints(struct tracepoint_iter *iter)
2813{
2814 struct module *iter_mod;
2815 int found = 0;
2816
2817 mutex_lock(&module_mutex);
2818 list_for_each_entry(iter_mod, &modules, list) {
2819 if (!iter_mod->taints) {
2820 /*
2821 * Sorted module list
2822 */
2823 if (iter_mod < iter->module)
2824 continue;
2825 else if (iter_mod > iter->module)
2826 iter->tracepoint = NULL;
2827 found = tracepoint_get_iter_range(&iter->tracepoint,
2828 iter_mod->tracepoints,
2829 iter_mod->tracepoints
2830 + iter_mod->num_tracepoints);
2831 if (found) {
2832 iter->module = iter_mod;
2833 break;
2834 }
2835 }
2836 }
2837 mutex_unlock(&module_mutex);
2838 return found;
2839}
2840#endif