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 9db11911e04..661d73db786 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 | ||
