diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/kernel/module.c b/kernel/module.c index 9db11911e04b..661d73db786e 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -46,6 +46,7 @@ | |||
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> | ||
49 | 50 | ||
50 | #if 0 | 51 | #if 0 |
51 | #define DEBUGP printk | 52 | #define DEBUGP printk |
@@ -1831,6 +1832,8 @@ static noinline struct module *load_module(void __user *umod, | |||
1831 | #endif | 1832 | #endif |
1832 | unsigned int markersindex; | 1833 | unsigned int markersindex; |
1833 | unsigned int markersstringsindex; | 1834 | unsigned int markersstringsindex; |
1835 | unsigned int tracepointsindex; | ||
1836 | unsigned int tracepointsstringsindex; | ||
1834 | struct module *mod; | 1837 | struct module *mod; |
1835 | long err = 0; | 1838 | long err = 0; |
1836 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ | 1839 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ |
@@ -2117,6 +2120,9 @@ static noinline struct module *load_module(void __user *umod, | |||
2117 | markersindex = find_sec(hdr, sechdrs, secstrings, "__markers"); | 2120 | markersindex = find_sec(hdr, sechdrs, secstrings, "__markers"); |
2118 | markersstringsindex = find_sec(hdr, sechdrs, secstrings, | 2121 | markersstringsindex = find_sec(hdr, sechdrs, secstrings, |
2119 | "__markers_strings"); | 2122 | "__markers_strings"); |
2123 | tracepointsindex = find_sec(hdr, sechdrs, secstrings, "__tracepoints"); | ||
2124 | tracepointsstringsindex = find_sec(hdr, sechdrs, secstrings, | ||
2125 | "__tracepoints_strings"); | ||
2120 | 2126 | ||
2121 | /* Now do relocations. */ | 2127 | /* Now do relocations. */ |
2122 | for (i = 1; i < hdr->e_shnum; i++) { | 2128 | for (i = 1; i < hdr->e_shnum; i++) { |
@@ -2144,6 +2150,12 @@ static noinline struct module *load_module(void __user *umod, | |||
2144 | mod->num_markers = | 2150 | mod->num_markers = |
2145 | sechdrs[markersindex].sh_size / sizeof(*mod->markers); | 2151 | sechdrs[markersindex].sh_size / sizeof(*mod->markers); |
2146 | #endif | 2152 | #endif |
2153 | #ifdef CONFIG_TRACEPOINTS | ||
2154 | mod->tracepoints = (void *)sechdrs[tracepointsindex].sh_addr; | ||
2155 | mod->num_tracepoints = | ||
2156 | sechdrs[tracepointsindex].sh_size / sizeof(*mod->tracepoints); | ||
2157 | #endif | ||
2158 | |||
2147 | 2159 | ||
2148 | /* Find duplicate symbols */ | 2160 | /* Find duplicate symbols */ |
2149 | err = verify_export_symbols(mod); | 2161 | err = verify_export_symbols(mod); |
@@ -2162,11 +2174,16 @@ static noinline struct module *load_module(void __user *umod, | |||
2162 | 2174 | ||
2163 | add_kallsyms(mod, sechdrs, symindex, strindex, secstrings); | 2175 | add_kallsyms(mod, sechdrs, symindex, strindex, secstrings); |
2164 | 2176 | ||
2177 | if (!mod->taints) { | ||
2165 | #ifdef CONFIG_MARKERS | 2178 | #ifdef CONFIG_MARKERS |
2166 | if (!mod->taints) | ||
2167 | marker_update_probe_range(mod->markers, | 2179 | marker_update_probe_range(mod->markers, |
2168 | mod->markers + mod->num_markers); | 2180 | mod->markers + mod->num_markers); |
2169 | #endif | 2181 | #endif |
2182 | #ifdef CONFIG_TRACEPOINTS | ||
2183 | tracepoint_update_probe_range(mod->tracepoints, | ||
2184 | mod->tracepoints + mod->num_tracepoints); | ||
2185 | #endif | ||
2186 | } | ||
2170 | err = module_finalize(hdr, sechdrs, mod); | 2187 | err = module_finalize(hdr, sechdrs, mod); |
2171 | if (err < 0) | 2188 | if (err < 0) |
2172 | goto cleanup; | 2189 | goto cleanup; |
@@ -2717,3 +2734,50 @@ void module_update_markers(void) | |||
2717 | mutex_unlock(&module_mutex); | 2734 | mutex_unlock(&module_mutex); |
2718 | } | 2735 | } |
2719 | #endif | 2736 | #endif |
2737 | |||
2738 | #ifdef CONFIG_TRACEPOINTS | ||
2739 | void module_update_tracepoints(void) | ||
2740 | { | ||
2741 | struct module *mod; | ||
2742 | |||
2743 | mutex_lock(&module_mutex); | ||
2744 | list_for_each_entry(mod, &modules, list) | ||
2745 | if (!mod->taints) | ||
2746 | tracepoint_update_probe_range(mod->tracepoints, | ||
2747 | mod->tracepoints + mod->num_tracepoints); | ||
2748 | mutex_unlock(&module_mutex); | ||
2749 | } | ||
2750 | |||
2751 | /* | ||
2752 | * Returns 0 if current not found. | ||
2753 | * Returns 1 if current found. | ||
2754 | */ | ||
2755 | int module_get_iter_tracepoints(struct tracepoint_iter *iter) | ||
2756 | { | ||
2757 | struct module *iter_mod; | ||
2758 | int found = 0; | ||
2759 | |||
2760 | mutex_lock(&module_mutex); | ||
2761 | list_for_each_entry(iter_mod, &modules, list) { | ||
2762 | if (!iter_mod->taints) { | ||
2763 | /* | ||
2764 | * Sorted module list | ||
2765 | */ | ||
2766 | if (iter_mod < iter->module) | ||
2767 | continue; | ||
2768 | else if (iter_mod > iter->module) | ||
2769 | iter->tracepoint = NULL; | ||
2770 | found = tracepoint_get_iter_range(&iter->tracepoint, | ||
2771 | iter_mod->tracepoints, | ||
2772 | iter_mod->tracepoints | ||
2773 | + iter_mod->num_tracepoints); | ||
2774 | if (found) { | ||
2775 | iter->module = iter_mod; | ||
2776 | break; | ||
2777 | } | ||
2778 | } | ||
2779 | } | ||
2780 | mutex_unlock(&module_mutex); | ||
2781 | return found; | ||
2782 | } | ||
2783 | #endif | ||