1
0
mirror of https://github.com/torvalds/linux.git synced 2024-12-13 22:53:20 +00:00
linux/tools
Jianlin Lv 105f75ebf9 perf probe: Fix kretprobe issue caused by GCC bug
Perf failed to add a kretprobe event with debuginfo of vmlinux which is
compiled by gcc with -fpatchable-function-entry option enabled.  The
same issue with kernel module.

Issue:

  # perf probe  -v 'kernel_clone%return $retval'
  ......
  Writing event: r:probe/kernel_clone__return _text+599624 $retval
  Failed to write event: Invalid argument
    Error: Failed to add events. Reason: Invalid argument (Code: -22)

  # cat /sys/kernel/debug/tracing/error_log
  [156.75] trace_kprobe: error: Retprobe address must be an function entry
  Command: r:probe/kernel_clone__return _text+599624 $retval
                                        ^

  # llvm-dwarfdump  vmlinux |grep  -A 10  -w 0x00df2c2b
  0x00df2c2b:   DW_TAG_subprogram
                DW_AT_external  (true)
                DW_AT_name      ("kernel_clone")
                DW_AT_decl_file ("/home/code/linux-next/kernel/fork.c")
                DW_AT_decl_line (2423)
                DW_AT_decl_column       (0x07)
                DW_AT_prototyped        (true)
                DW_AT_type      (0x00dcd492 "pid_t")
                DW_AT_low_pc    (0xffff800010092648)
                DW_AT_high_pc   (0xffff800010092b9c)
                DW_AT_frame_base        (DW_OP_call_frame_cfa)

  # cat /proc/kallsyms |grep kernel_clone
  ffff800010092640 T kernel_clone
  # readelf -s vmlinux |grep -i kernel_clone
  183173: ffff800010092640  1372 FUNC    GLOBAL DEFAULT    2 kernel_clone

  # objdump -d vmlinux |grep -A 10  -w \<kernel_clone\>:
  ffff800010092640 <kernel_clone>:
  ffff800010092640:       d503201f        nop
  ffff800010092644:       d503201f        nop
  ffff800010092648:       d503233f        paciasp
  ffff80001009264c:       a9b87bfd        stp     x29, x30, [sp, #-128]!
  ffff800010092650:       910003fd        mov     x29, sp
  ffff800010092654:       a90153f3        stp     x19, x20, [sp, ]

The entry address of kernel_clone converted by debuginfo is _text+599624
(0x92648), which is consistent with the value of DW_AT_low_pc attribute.
But the symbolic address of kernel_clone from /proc/kallsyms is
ffff800010092640.

This issue is found on arm64, -fpatchable-function-entry=2 is enabled when
CONFIG_DYNAMIC_FTRACE_WITH_REGS=y;
Just as objdump displayed the assembler contents of kernel_clone,
GCC generate 2 NOPs  at the beginning of each function.

kprobe_on_func_entry detects that (_text+599624) is not the entry address
of the function, which leads to the failure of adding kretprobe event.

  kprobe_on_func_entry
  ->_kprobe_addr
  ->kallsyms_lookup_size_offset
  ->arch_kprobe_on_func_entry		// FALSE

The cause of the issue is that the first instruction in the compile unit
indicated by DW_AT_low_pc does not include NOPs.
This issue exists in all gcc versions that support
-fpatchable-function-entry option.

I have reported it to the GCC community:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98776

Currently arm64 and PA-RISC may enable fpatchable-function-entry option.
The kernel compiled with clang does not have this issue.

FIX:

This GCC issue only cause the registration failure of the kretprobe event
which doesn't need debuginfo. So, stop using debuginfo for retprobe.
map will be used to query the probe function address.

Signed-off-by: Jianlin Lv <Jianlin.Lv@arm.com>
Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: clang-built-linux@googlegroups.com
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sumanth Korikkar <sumanthk@linux.ibm.com>
Link: http://lore.kernel.org/lkml/20210210062646.2377995-1-Jianlin.Lv@arm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-02-12 18:34:25 -03:00
..
accounting
arch tools headers UAPI: Synch KVM's svm.h header with the kernel 2020-12-24 09:24:20 -03:00
bootconfig tools/bootconfig: Add tracing_on support to helper scripts 2021-01-14 10:32:20 -05:00
bpf bpftool: Fix compilation failure for net.o with older glibc 2021-01-06 15:27:38 -08:00
build Merge remote-tracking branch 'torvalds/master' into perf/core 2020-12-17 14:37:24 -03:00
cgroup blk-iocost: update iocost_monitor.py 2020-09-01 19:38:33 -06:00
debugging docs: Update documentation to reflect what TAINT_CPU_OUT_OF_SPEC means 2020-12-08 10:53:58 -07:00
edid
firewire
firmware
gpio tools: gpio: fix %llu warning in gpio-watch.c 2021-01-18 10:05:35 +01:00
hv
iio iio: add IIO_MOD_O2 modifier 2020-08-22 10:53:12 +01:00
include tools headers UAPI: Sync linux/prctl.h with the kernel sources 2021-02-11 12:50:52 -03:00
io_uring tools/io_uring: fix compile breakage 2020-09-21 07:50:58 -06:00
kvm/kvm_stat tools/kvm_stat: Exempt time-based counters 2020-12-11 19:18:51 -05:00
laptop
leds
lib perf evlist: Fix id index for heterogeneous systems 2021-01-21 17:25:33 -03:00
memory-model tools/memory-model: Label MP tests' producers and consumers 2020-11-06 17:25:17 -08:00
objtool objtool: Don't fail on missing symbol table 2021-01-21 15:49:58 -06:00
pci
pcmcia
perf perf probe: Fix kretprobe issue caused by GCC bug 2021-02-12 18:34:25 -03:00
power tools/power/turbostat: Fallback to an MSR read for EPB 2021-02-03 11:58:19 +01:00
scripts tools: Factor HOSTCC, HOSTLD, HOSTAR definitions 2020-11-11 12:18:22 -08:00
spi
testing Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2021-02-10 11:33:39 -08:00
thermal/tmon
time
usb tools: usb: move to tools buildsystem 2020-08-19 14:11:44 +02:00
virtio tools/virtio: add barrier for aarch64 2020-12-18 16:14:30 -05:00
vm mm: Add PG_arch_2 page flag 2020-09-04 12:46:06 +01:00
wmi
Makefile