Skip to contentSkip to conversation

FAILED: patch "[PATCH] riscv: ftrace: Reduce the detour code size to half" failed to apply to 5.4-stable tree

PATCH [email protected] 1 participant 1 message Mar 7, 2023

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

To reproduce the conflict and resubmit, you may use the following commands:

git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.4.y
git checkout FETCH_HEAD
git cherry-pick -x 6724a76cff85ee271bbbff42ac527e4643b2ec52
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '[email protected]' --subject-prefix 'PATCH 5.4.y' HEAD^..

Possible dependencies:

6724a76cff85 ("riscv: ftrace: Reduce the detour code size to half") 409c8fb20c66 ("riscv: ftrace: Remove wasted nops for !RISCV_ISA_C") afc76b8b8011 ("riscv: Using PATCHABLE_FUNCTION_ENTRY instead of MCOUNT") 66d18dbda846 ("RISC-V: Take text_mutex in ftrace_init_nop()")

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From 6724a76cff85ee271bbbff42ac527e4643b2ec52 Mon Sep 17 00:00:00 2001
From: Guo Ren <[email protected]>
Date: Thu, 12 Jan 2023 04:05:59 -0500
Subject: [PATCH] riscv: ftrace: Reduce the detour code size to half

Use a temporary register to reduce the size of detour code from 16 bytes to 8 bytes. The previous implementation is from 'commit afc76b8b8011 ("riscv:
Using PATCHABLE_FUNCTION_ENTRY instead of MCOUNT")'.

Before the patch:
<func_prolog>:

 0: REG_S  ra, -SZREG(sp)
 4: auipc  ra, ?
 8: jalr   ?(ra)
12: REG_L  ra, -SZREG(sp)

(func_boddy)

After the patch:
<func_prolog>:
0: auipc t0, ?
4: jalr t0, ?(t0)
(func_boddy)

This patch not just reduces the size of detour code, but also fixes an important issue:

An Ftrace callback registered with FTRACE_OPS_FL_IPMODIFY flag can actually change the instruction pointer, e.g. to "replace" the given kernel function with a new one, which is needed for livepatching, etc.

In this case, the trampoline (ftrace_regs_caller) would not return to <func_prolog+12> but would rather jump to the new function. So, "REG_L ra, -SZREG(sp)" would not run and the original return address would not be restored. The kernel is likely to hang or crash as a result.

This can be easily demonstrated if one tries to "replace", say, cmdline_proc_show() with a new function with the same signature using instruction_pointer_set(&fregs->regs, new_func_addr) in the Ftrace callback.

arch/riscv/Makefile +2 -2
index e194916cb5a2..ab50724cc554 100644
@@ -12,9 +12,9 @@ ifeq ($(CONFIG_DYNAMIC_FTRACE),y)
 	LDFLAGS_vmlinux := --no-relax
 	KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY
 ifeq ($(CONFIG_RISCV_ISA_C),y)
-	CC_FLAGS_FTRACE := -fpatchable-function-entry=8
-else
 	CC_FLAGS_FTRACE := -fpatchable-function-entry=4
+else
+	CC_FLAGS_FTRACE := -fpatchable-function-entry=2
 endif
 endif
 
arch/riscv/include/asm/ftrace.h +38 -12

69 lines not on this page · raw message

arch/riscv/kernel/ftrace.c +19 -46

138 lines not on this page · raw message

arch/riscv/kernel/mcount-dyn.S +16 -26

127 lines not on this page · raw message