[PATCH v4 1/2] perf: Extract is_ignored_kernel_symbol() for kernel mapping symbol filtering

From: Rui Qi

Date: Fri May 22 2026 - 04:27:56 EST


Mapping symbol filtering is scattered across multiple files with
inconsistent checks. The kernel's own is_mapping_symbol() covers
x86 local symbols ('.L*' and 'L0*') on top of the '$' prefix used
by ARM/AArch64/RISC-V, but the perf tool only checks '$'.

Extract is_ignored_kernel_symbol() into symbol.h matching the kernel
definition, and convert the kallsyms and ksymbol event paths to
use it. Add ksymbol event name validation and early mapping symbol
filtering before any state mutation.

Signed-off-by: Rui Qi <qirui.001@xxxxxxxxxxxxx>
---
tools/perf/util/machine.c | 18 +++++++++++++++++-
tools/perf/util/symbol.c | 4 ++--
tools/perf/util/symbol.h | 15 +++++++++++++++
3 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index e76f8c86e62a..07e4ad56d757 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -4,6 +4,7 @@
#include <inttypes.h>
#include <regex.h>
#include <stdlib.h>
+#include <string.h>
#include "callchain.h"
#include "debug.h"
#include "dso.h"
@@ -729,9 +730,15 @@ static int machine__process_ksymbol_register(struct machine *machine,
{
struct symbol *sym;
struct dso *dso = NULL;
- struct map *map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr);
+ struct map *map;
int err = 0;

+ /* Ignore mapping symbols in ksymbol events - check early before any state mutation */
+ if (is_ignored_kernel_symbol(event->ksymbol.name))
+ return 0;
+
+ map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr);
+
if (!map) {
dso = dso__new(event->ksymbol.name);

@@ -790,6 +797,10 @@ static int machine__process_ksymbol_unregister(struct machine *machine,
struct symbol *sym;
struct map *map;

+ /* Ignore mapping symbols in ksymbol events */
+ if (is_ignored_kernel_symbol(event->ksymbol.name))
+ return 0;
+
map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr);
if (!map)
return 0;
@@ -814,6 +825,11 @@ int machine__process_ksymbol(struct machine *machine __maybe_unused,
if (dump_trace)
perf_event__fprintf_ksymbol(event, stdout);

+ if (event->header.size < offsetof(struct perf_record_ksymbol, name) + 2 ||
+ !memchr(event->ksymbol.name, '\0',
+ event->header.size - offsetof(struct perf_record_ksymbol, name)))
+ return -EINVAL;
+
/* no need to process non-JIT BPF as it cannot get samples */
if (event->ksymbol.len == 0)
return 0;
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index fcaeeddbbb6b..714b6e6048fa 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -770,8 +770,8 @@ static int map__process_kallsym_symbol(void *arg, const char *name,
if (!symbol_type__filter(type))
return 0;

- /* Ignore local symbols for ARM modules */
- if (name[0] == '$')
+ /* Ignore mapping symbols in kallsyms */
+ if (is_ignored_kernel_symbol(name))
return 0;

/*
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index bd6eb90c8668..95592779eb77 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -28,6 +28,21 @@ struct maps;
struct option;
struct build_id;

+/*
+ * Ignore kernel mapping symbols, matching kernel is_mapping_symbol() logic.
+ * This checks for '$' prefix (used by ARM, AArch64, RISC-V) and
+ * x86 local symbol prefixes (.L* and L0*).
+ * Only use this for kernel symbols (kallsyms, ksymbol events, kernel ELF DSOs).
+ */
+static inline bool is_ignored_kernel_symbol(const char *str)
+{
+ if (str[0] == '.' && str[1] == 'L')
+ return true;
+ if (str[0] == 'L' && str[1] == '0')
+ return true;
+ return str[0] == '$';
+}
+
/*
* libelf 0.8.x and earlier do not support ELF_C_READ_MMAP;
* for newer versions we can use mmap to reduce memory usage:
--
2.20.1