[RFC PATCH V2]: add DYNAMC_FTRACE_WITH_REGS and

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 






[Index of Archives]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux