summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-08-26 20:25:21 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2018-08-26 20:25:21 +0200
commitd207ea8e74ff45be0838afa12bdd2492fa9dc8bc (patch)
tree97cfb3ed5c1bb42790e98e62b823526f61000b9f /kernel
parentMerge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/ker... (diff)
parentMerge tag 'perf-core-for-mingo-4.19-20180820' of git://git.kernel.org/pub/scm... (diff)
downloadlinux-d207ea8e74ff45be0838afa12bdd2492fa9dc8bc.tar.xz
linux-d207ea8e74ff45be0838afa12bdd2492fa9dc8bc.zip
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Thomas Gleixner: "Kernel: - Improve kallsyms coverage - Add x86 entry trampolines to kcore - Fix ARM SPE handling - Correct PPC event post processing Tools: - Make the build system more robust - Small fixes and enhancements all over the place - Update kernel ABI header copies - Preparatory work for converting libtraceevnt to a shared library - License cleanups" * 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (100 commits) tools arch: Update arch/x86/lib/memcpy_64.S copy used in 'perf bench mem memcpy' tools arch x86: Update tools's copy of cpufeatures.h perf python: Fix pyrf_evlist__read_on_cpu() interface perf mmap: Store real cpu number in 'struct perf_mmap' perf tools: Remove ext from struct kmod_path perf tools: Add gzip_is_compressed function perf tools: Add lzma_is_compressed function perf tools: Add is_compressed callback to compressions array perf tools: Move the temp file processing into decompress_kmodule perf tools: Use compression id in decompress_kmodule() perf tools: Store compression id into struct dso perf tools: Add compression id into 'struct kmod_path' perf tools: Make is_supported_compression() static perf tools: Make decompress_to_file() function static perf tools: Get rid of dso__needs_decompress() call in __open_dso() perf tools: Get rid of dso__needs_decompress() call in symbol__disassemble() perf tools: Get rid of dso__needs_decompress() call in read_object_code() tools lib traceevent: Change to SPDX License format perf llvm: Allow passing options to llc in addition to clang perf parser: Improve error message for PMU address filters ...
Diffstat (limited to 'kernel')
-rw-r--r--kernel/kallsyms.c51
1 files changed, 37 insertions, 14 deletions
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index a23e21ada81b..02a0b01380d8 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -432,6 +432,7 @@ int sprint_backtrace(char *buffer, unsigned long address)
/* To avoid using get_symbol_offset for every symbol, we carry prefix along. */
struct kallsym_iter {
loff_t pos;
+ loff_t pos_arch_end;
loff_t pos_mod_end;
loff_t pos_ftrace_mod_end;
unsigned long value;
@@ -443,9 +444,29 @@ struct kallsym_iter {
int show_value;
};
+int __weak arch_get_kallsym(unsigned int symnum, unsigned long *value,
+ char *type, char *name)
+{
+ return -EINVAL;
+}
+
+static int get_ksymbol_arch(struct kallsym_iter *iter)
+{
+ int ret = arch_get_kallsym(iter->pos - kallsyms_num_syms,
+ &iter->value, &iter->type,
+ iter->name);
+
+ if (ret < 0) {
+ iter->pos_arch_end = iter->pos;
+ return 0;
+ }
+
+ return 1;
+}
+
static int get_ksymbol_mod(struct kallsym_iter *iter)
{
- int ret = module_get_kallsym(iter->pos - kallsyms_num_syms,
+ int ret = module_get_kallsym(iter->pos - iter->pos_arch_end,
&iter->value, &iter->type,
iter->name, iter->module_name,
&iter->exported);
@@ -501,32 +522,34 @@ static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
iter->nameoff = get_symbol_offset(new_pos);
iter->pos = new_pos;
if (new_pos == 0) {
+ iter->pos_arch_end = 0;
iter->pos_mod_end = 0;
iter->pos_ftrace_mod_end = 0;
}
}
+/*
+ * The end position (last + 1) of each additional kallsyms section is recorded
+ * in iter->pos_..._end as each section is added, and so can be used to
+ * determine which get_ksymbol_...() function to call next.
+ */
static int update_iter_mod(struct kallsym_iter *iter, loff_t pos)
{
iter->pos = pos;
- if (iter->pos_ftrace_mod_end > 0 &&
- iter->pos_ftrace_mod_end < iter->pos)
- return get_ksymbol_bpf(iter);
+ if ((!iter->pos_arch_end || iter->pos_arch_end > pos) &&
+ get_ksymbol_arch(iter))
+ return 1;
- if (iter->pos_mod_end > 0 &&
- iter->pos_mod_end < iter->pos) {
- if (!get_ksymbol_ftrace_mod(iter))
- return get_ksymbol_bpf(iter);
+ if ((!iter->pos_mod_end || iter->pos_mod_end > pos) &&
+ get_ksymbol_mod(iter))
return 1;
- }
- if (!get_ksymbol_mod(iter)) {
- if (!get_ksymbol_ftrace_mod(iter))
- return get_ksymbol_bpf(iter);
- }
+ if ((!iter->pos_ftrace_mod_end || iter->pos_ftrace_mod_end > pos) &&
+ get_ksymbol_ftrace_mod(iter))
+ return 1;
- return 1;
+ return get_ksymbol_bpf(iter);
}
/* Returns false if pos at or past end of file. */