arch/microblaze/kernel/ftrace.c

Source file repositories/reference/linux-study-clean/arch/microblaze/kernel/ftrace.c

File Facts

System
Linux kernel
Corpus path
arch/microblaze/kernel/ftrace.c
Extension
.c
Size
5915 bytes
Lines
218
Domain
Architecture Layer
Bucket
arch/microblaze
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <asm/cacheflush.h>
#include <linux/ftrace.h>

#ifdef CONFIG_FUNCTION_GRAPH_TRACER
/*
 * Hook the return address and push it in the stack of return addrs
 * in current thread info.
 */
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;
}
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */

#ifdef CONFIG_DYNAMIC_FTRACE
/* save value to addr - it is save to do it in asm */
static int ftrace_modify_code(unsigned long addr, unsigned int value)
{
	int faulted = 0;

	__asm__ __volatile__("	1:	swi	%2, %1, 0;"		\
				"	addik	%0, r0, 0;"		\
				"2:"					\
				"	.section .fixup, \"ax\";"	\
				"3:	brid	2b;"			\
				"	addik	%0, r0, 1;"		\
				"	.previous;"			\
				"	.section __ex_table,\"a\";"	\
				"	.word	1b,3b;"			\
				"	.previous;"			\
				: "=r" (faulted)
				: "r" (addr), "r" (value)
	);

	if (unlikely(faulted))
		return -EFAULT;

	flush_dcache_range(addr, addr + 4);
	flush_icache_range(addr, addr + 4);

	return 0;
}

#define MICROBLAZE_NOP 0x80000000
#define MICROBLAZE_BRI 0xb800000C

static unsigned int recorded; /* if save was or not */
static unsigned int imm; /* saving whole imm instruction */

Annotation

Implementation Notes