V2: +. fix ftrace regs test failure +. fix kprobe test failure with adding KPROBES_ON_FTRACE This series add DYNAMC_FTRACE_WITH_REGS and KPROBES_ON_FTRACE support without depending on _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 +. stub is called with sp adjusted in Callee(the traced function), which is hard for livepatch to restore the original sp pointer 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 +. 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 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“, PS: "jalr at, at" jump and link into addr in "at", and save the return address in "at"; With this, no touching parent return address in ra ------------ :: 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 PS: In mcount-based ftrace of MIPS32 vmlinux, the _mcount calling sequence like this: ------------ :: A: ...... jal B nop ...... B: move at, ra jal _mcount addiu sp, sp, -32 #B: real start INSN_B_first ------------ :: A: ...... jal B nop ...... B: move at, ra nop nop #B: real start INSN_B_first no matter disabing and enabling tracing, we can not atomically change both "jalr" and "addiu"(sync does not help here), on MIP32/SMP, whether this ------------ :: A: ...... jal B nop ...... B: move at, ra nop addiu sp, sp, -32 #B: real start INSN_B_first or this ------------ :: A: ...... jal B nop ...... B: move at, ra nop addiu sp, sp, -32 #B: real start INSN_B_first would wreck the ftrace +. 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" ***Or use 4 nops for stub*** Patches ########### Patch 1 - Patch 3 This prepares new MIPS/ftrace with DYNAMIC_FTRACE_WITH_REGS and KPROBES_ON_FTACE in parallel with old MIPS/Ftrace NO function changed, these three patches can be merge into one patch Patch 4 - Patch 5 this is needed for all RISC Patch 6 Add DYNAMC_FTRACE_WITH_REGS and KPROBES_ON_FTACE support