Unverified Commit f8693f6d authored by Andy Chiu's avatar Andy Chiu Committed by Palmer Dabbelt
Browse files

riscv: ftrace: support fastcc in Clang for WITH_ARGS

Some caller-saved registers which are not defined as function arguments
in the ABI can still be passed as arguments when the kernel is compiled
with Clang. As a result, we must save and restore those registers to
prevent ftrace from clobbering them.

- [1]: https://reviews.llvm.org/D68559



Reported-by: default avatarEvgenii Shatokhin <e.shatokhin@yadro.com>
Closes: https://lore.kernel.org/linux-riscv/7e7c7914-445d-426d-89a0-59a9199c45b1@yadro.com/


Fixes: 7caa9765 ("ftrace: riscv: move from REGS to ARGS")
Acked-by: default avatarNathan Chancellor <nathan@kernel.org>
Reviewed-by: default avatarBjörn Töpel <bjorn@rivosinc.com>
Signed-off-by: default avatarAndy Chiu <andy.chiu@sifive.com>
Tested-by: default avatarBjörn Töpel <bjorn@rivosinc.com>
Link: https://lore.kernel.org/r/20250407180838.42877-1-andybnac@gmail.com


Signed-off-by: default avatarAlexandre Ghiti <alexghiti@rivosinc.com>
Signed-off-by: default avatarPalmer Dabbelt <palmer@dabbelt.com>
parent 9c32cda4
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -146,6 +146,13 @@ struct __arch_ftrace_regs {
			unsigned long a5;
			unsigned long a6;
			unsigned long a7;
#ifdef CONFIG_CC_IS_CLANG
			unsigned long t2;
			unsigned long t3;
			unsigned long t4;
			unsigned long t5;
			unsigned long t6;
#endif
		};
	};
};
+7 −0
Original line number Diff line number Diff line
@@ -501,6 +501,13 @@ void asm_offsets(void)
	DEFINE(FREGS_SP,	    offsetof(struct __arch_ftrace_regs, sp));
	DEFINE(FREGS_S0,	    offsetof(struct __arch_ftrace_regs, s0));
	DEFINE(FREGS_T1,	    offsetof(struct __arch_ftrace_regs, t1));
#ifdef CONFIG_CC_IS_CLANG
	DEFINE(FREGS_T2,	    offsetof(struct __arch_ftrace_regs, t2));
	DEFINE(FREGS_T3,	    offsetof(struct __arch_ftrace_regs, t3));
	DEFINE(FREGS_T4,	    offsetof(struct __arch_ftrace_regs, t4));
	DEFINE(FREGS_T5,	    offsetof(struct __arch_ftrace_regs, t5));
	DEFINE(FREGS_T6,	    offsetof(struct __arch_ftrace_regs, t6));
#endif
	DEFINE(FREGS_A0,	    offsetof(struct __arch_ftrace_regs, a0));
	DEFINE(FREGS_A1,	    offsetof(struct __arch_ftrace_regs, a1));
	DEFINE(FREGS_A2,	    offsetof(struct __arch_ftrace_regs, a2));
+14 −2
Original line number Diff line number Diff line
@@ -96,7 +96,13 @@
	REG_S	x8,  FREGS_S0(sp)
#endif
	REG_S	x6,  FREGS_T1(sp)

#ifdef CONFIG_CC_IS_CLANG
	REG_S	x7,  FREGS_T2(sp)
	REG_S	x28, FREGS_T3(sp)
	REG_S	x29, FREGS_T4(sp)
	REG_S	x30, FREGS_T5(sp)
	REG_S	x31, FREGS_T6(sp)
#endif
	// save the arguments
	REG_S	x10, FREGS_A0(sp)
	REG_S	x11, FREGS_A1(sp)
@@ -115,7 +121,13 @@
	REG_L	x8, FREGS_S0(sp)
#endif
	REG_L	x6,  FREGS_T1(sp)

#ifdef CONFIG_CC_IS_CLANG
	REG_L	x7,  FREGS_T2(sp)
	REG_L	x28, FREGS_T3(sp)
	REG_L	x29, FREGS_T4(sp)
	REG_L	x30, FREGS_T5(sp)
	REG_L	x31, FREGS_T6(sp)
#endif
	// restore the arguments
	REG_L	x10, FREGS_A0(sp)
	REG_L	x11, FREGS_A1(sp)