This series add DYNAMC_FTRACE_WITH_REGS support without depending _mcount and -pg, and try to address following issue +. _mcount stub size is 3 insns in vmlinux and 4 insns in .ko, too much +. complex handing MIPS32 and MIPS64 in _mcount, especially sp pointer in MIPS32 +. _mcount is called with sp adjusted in Callee(the traced function), which is hard for livepatch to restore the sp pointer GCC ######### +. gcc 8 add -fpatchable-function-entry=N[, M] support to insert N nops before real start, for more info, see gcc 8 manual +. gcc/mips has two bug: 93242 (fixed in gcc 10), 99217 (with a fix, but not accepted) about this option. With fixes applyed in gcc 8.3, vmlinux is OK Design ######### +. Caller A calls Callee B, with -fpatchable-function-entry=3, B has three nops at its entry ------------ :: A: jal B nop ...... B: nop nop nop #B: real start INSN_B_first +. With ftrace initialized or module loaded, this three nop got replaced, ------------ :: A: jal B nop ...... B: lui at, %hi(ftrace_regs_caller) nop li t0, 0 #B: real start INSN_B_first Obviously, ftrace_regs_caller is 64KB aligned, thanks He Jinyang <hejinyang@xxxxxxxxxxx> +. To enable tracing , take nop into "jalr at, at“, ------------ :: A: jal B nop ...... B: lui at, %hi(ftrace_regs_caller) jalr at, at li t0, 0 #B: real start INSN_B_first +. To disable tracing, take "jalr at, at" into nop ------------ :: A: jal B nop ...... B: lui at, %hi(ftrace_regs_caller) nop li t0, 0 #B: real start INSN_B_first +. when tracing without regs, replace "li t0, 0' with "li t0, 1" ------------ :: A: jal B nop ...... B: lui at, %hi(ftrace_regs_caller) jalr at, at li t0, 1 #B: real start INSN_B_first With only one instruction modified, it is atomic and no sync needed ( _mcount need sync between two writes) on both MIPS32 and MIPS64, I got this from ARM64. we need transfrom from tracing disabled into tracing without regs, first replace "li t0, 0" with "li t0, 1", then "nop" with "jalr at, at", still no sync between ------------ :: A: jal B nop ...... B: lui at, %hi(ftrace_regs_caller) jalr at, at li t0, 1 #B: real start INSN_B_first +. When B is ok to be patched, replace first four instruction with new function B' ------------ :: A: jal B nop ...... B: lui at, %hi(B') // second, fill new B'high addiu at, %lo(B') // first, fill nop // third, fill new B' low jr at // at last, fill jr #B: real start nop //forth, fill nop //Watch Out! //first instruction // clobbered. we //need to save it somewhere //or we must use four nops if tracing enabled, we need to disable tracing first, and we need sync before fill "jr" Patches ########### Patch 1 - Patch 3 This make new MIPS/ftrace with DYNAMIC_FTRACE_WITH_REGS in parallel with old MIPS/Ftrace Patch 4 Add DYNAMC_FTRACE_WITH_REGS support Remaining Issues ################ +. reserve three nops or four nops for <= MIPS R5 ? Without direct call, three nops is enough. With direct call, we need to hack ftrace to save the first instruction somewhere. Four nops is enough for all cases MIPS R6 only need three nops without hacking, but this version does not support MIPS R6 +. MIPS32 support, working on it +. checking for gcc version, can previous two bug back porting to gcc 8.5? We should check gcc's version +. stack backstrace