Christophe Leroy wrote:
Le 19/06/2023 à 11:47, Naveen N Rao a écrit :
GCC v13.1 updated support for -fpatchable-function-entry on ppc64le to
emit nops after the local entry point, rather than before it. This
allows us to use this in the kernel for ftrace purposes. A new script is
added under arch/powerpc/tools/ to help detect if nops are emitted after
the function local entry point, or before the global entry point.
With -fpatchable-function-entry, we no longer have the profiling
instructions generated at function entry, so we only need to validate
the presence of two nops at the ftrace location in ftrace_init_nop(). We
patch the preceding instruction with 'mflr r0' to match the
-mprofile-kernel ABI for subsequent ftrace use.
This changes the profiling instructions used on ppc32. The default -pg
option emits an additional 'stw' instruction after 'mflr r0' and before
the branch to _mcount 'bl _mcount'. This is very similar to the original
-mprofile-kernel implementation on ppc64le, where an additional 'std'
instruction was used to save LR to its save location in the caller's
stackframe. Subsequently, this additional store was removed in later
compiler versions for performance reasons. The same reasons apply for
ppc32 so we only patch in a 'mflr r0'.
Signed-off-by: Naveen N Rao <nav...@kernel.org>
Reviewed-by: Christophe Leroy <christophe.le...@csgroup.eu>
Nit below
---
arch/powerpc/Kconfig | 14 +++++++---
arch/powerpc/Makefile | 5 ++++
arch/powerpc/include/asm/ftrace.h | 6 +++--
arch/powerpc/include/asm/vermagic.h | 4 ++-
arch/powerpc/kernel/module_64.c | 2 +-
arch/powerpc/kernel/trace/ftrace.c | 14 ++++++++--
arch/powerpc/kernel/trace/ftrace_entry.S | 2 ++
.../gcc-check-fpatchable-function-entry.sh | 26 +++++++++++++++++++
8 files changed, 64 insertions(+), 9 deletions(-)
create mode 100755 arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index bff5820b7cda14..9352d8e68152e1 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -187,6 +187,7 @@ config PPC
select DYNAMIC_FTRACE if FUNCTION_TRACER
select EDAC_ATOMIC_SCRUB
select EDAC_SUPPORT
+ select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY if
ARCH_USING_PATCHABLE_FUNCTION_ENTRY
select GENERIC_ATOMIC64 if PPC32
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
select GENERIC_CMOS_UPDATE
@@ -227,8 +228,8 @@ config PPC
select HAVE_DEBUG_KMEMLEAK
select HAVE_DEBUG_STACKOVERFLOW
select HAVE_DYNAMIC_FTRACE
- select HAVE_DYNAMIC_FTRACE_WITH_ARGS if MPROFILE_KERNEL || PPC32
- select HAVE_DYNAMIC_FTRACE_WITH_REGS if MPROFILE_KERNEL || PPC32
+ select HAVE_DYNAMIC_FTRACE_WITH_ARGS if
ARCH_USING_PATCHABLE_FUNCTION_ENTRY || MPROFILE_KERNEL || PPC32
+ select HAVE_DYNAMIC_FTRACE_WITH_REGS if
ARCH_USING_PATCHABLE_FUNCTION_ENTRY || MPROFILE_KERNEL || PPC32
ARCH_USING_PATCHABLE_FUNCTION_ENTRY defaults to y if PPC32, so you can
remove PPC32 from the condition here.
ARCH_USING_PATCHABLE_FUNCTION_ENTRY also depends on compiler support for
-fpatchable-function-entry, and gcc v5.x doesn't support that. So, we
need to retain PPC32 here.
- Naveen
select HAVE_EBPF_JIT
select HAVE_EFFICIENT_UNALIGNED_ACCESS
select HAVE_FAST_GUP
@@ -256,7 +257,7 @@ config PPC
select HAVE_MOD_ARCH_SPECIFIC
select HAVE_NMI if PERF_EVENTS || (PPC64 &&
PPC_BOOK3S)
select HAVE_OPTPROBES
- select HAVE_OBJTOOL if PPC32 || MPROFILE_KERNEL
+ select HAVE_OBJTOOL if
ARCH_USING_PATCHABLE_FUNCTION_ENTRY || MPROFILE_KERNEL || PPC32
Same
select HAVE_OBJTOOL_MCOUNT if HAVE_OBJTOOL
select HAVE_PERF_EVENTS
select HAVE_PERF_EVENTS_NMI if PPC64
@@ -550,6 +551,13 @@ config MPROFILE_KERNEL
depends on PPC64 && CPU_LITTLE_ENDIAN && FUNCTION_TRACER
def_bool
$(success,$(srctree)/arch/powerpc/tools/gcc-check-mprofile-kernel.sh $(CC)
-I$(srctree)/include -D__KERNEL__)
+config ARCH_USING_PATCHABLE_FUNCTION_ENTRY
+ depends on FUNCTION_TRACER && (PPC32 || PPC64_ELF_ABI_V2)
+ depends on $(cc-option,-fpatchable-function-entry=2)
+ def_bool y if PPC32
+ def_bool
$(success,$(srctree)/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh $(CC)
-mlittle-endian) if PPC64 && CPU_LITTLE_ENDIAN
+ def_bool
$(success,$(srctree)/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh $(CC)
-mbig-endian) if PPC64 && CPU_BIG_ENDIAN
+
...