void prepare_ftrace_return()

in kernel/ftrace.c [22:67]


void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
{
	unsigned long old;
	int faulted;
	unsigned long return_hooker = (unsigned long)
				&return_to_handler;

	if (unlikely(ftrace_graph_is_dead()))
		return;

	if (unlikely(atomic_read(&current->tracing_graph_pause)))
		return;

	/*
	 * Protect against fault, even if it shouldn't
	 * happen. This tool is too much intrusive to
	 * ignore such a protection.
	 */
	asm volatile("	1:	lwi	%0, %2, 0;"		\
			"2:	swi	%3, %2, 0;"		\
			"	addik	%1, r0, 0;"		\
			"3:"					\
			"	.section .fixup, \"ax\";"	\
			"4:	brid	3b;"			\
			"	addik	%1, r0, 1;"		\
			"	.previous;"			\
			"	.section __ex_table,\"a\";"	\
			"	.word	1b,4b;"			\
			"	.word	2b,4b;"			\
			"	.previous;"			\
			: "=&r" (old), "=r" (faulted)
			: "r" (parent), "r" (return_hooker)
	);

	flush_dcache_range((u32)parent, (u32)parent + 4);
	flush_icache_range((u32)parent, (u32)parent + 4);

	if (unlikely(faulted)) {
		ftrace_graph_stop();
		WARN_ON(1);
		return;
	}

	if (function_graph_enter(old, self_addr, 0, NULL))
		*parent = old;
}