Skip to content

ARCv3: Implemented ftrace #146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions arch/arc/Kconfig
Original file line number Diff line number Diff line change
@@ -38,6 +38,8 @@ config ARC
select HAVE_KERNEL_LZMA
select HAVE_KPROBES
select HAVE_KRETPROBES
select HAVE_FUNCTION_TRACER if ISA_ARCV3
select HAVE_FUNCTION_GRAPH_TRACER if ISA_ARCV3
select HAVE_MOD_ARCH_SPECIFIC
select HAVE_PERF_EVENTS
select HANDLE_DOMAIN_IRQ
4 changes: 4 additions & 0 deletions arch/arc/Makefile
Original file line number Diff line number Diff line change
@@ -61,6 +61,10 @@ cflags-$(CONFIG_64BIT) += -mcmodel=large
cflags-$(CONFIG_ARC_HAS_LL128) += -m128
endif

ifdef CONFIG_FTRACE
cflags-y += -fno-omit-frame-pointer
endif

cflags-y += -Wa,-I$(srctree)/arch/arc/include

ifdef CONFIG_ARC_CURR_IN_REG
17 changes: 17 additions & 0 deletions arch/arc/kernel/Makefile
Original file line number Diff line number Diff line change
@@ -13,6 +13,23 @@ else
obj-y += intc-arcv2.o
endif

ifdef CONFIG_FTRACE

# Currently ftrace only works on arcv3 due to ABI
ifdef CONFIG_ISA_ARCV3

# ftrace cant be traced (infinite loop)
CFLAGS_REMOVE_ftrace.o = -pg
CFLAGS_REMOVE_mcount.o = -pg


obj-$(CONFIG_FUNCTION_TRACER) += mcount.o
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o

endif

endif

obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o
obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o
obj-$(CONFIG_ISA_ARCV3) += entry-arcv3.o
31 changes: 31 additions & 0 deletions arch/arc/kernel/ftrace.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Function tracing support for ARC
*
* Copyright (C) 2023 Synopsys, Inc. (www.synopsys.com)
*/

#include <linux/ftrace.h>

#ifdef CONFIG_FUNCTION_GRAPH_TRACER

/*
* Setup return hook in traced routine
* Function copied from riscv
*/
void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
unsigned long frame_pointer)
{
unsigned long return_hooker = (unsigned long)&return_to_handler;
unsigned long old;

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

old = *parent;

if (!function_graph_enter(old, self_addr, frame_pointer, parent))
*parent = return_hooker;
}

#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
119 changes: 119 additions & 0 deletions arch/arc/kernel/mcount.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Function tracing support for ARC
*
* Copyright (C) 2023 Synopsys, Inc. (www.synopsys.com)
*/


#include <linux/init.h>
#include <linux/linkage.h>
#include <asm-generic/export.h>
#include <asm/asm-macro-64-bit.h>

.text
; ftrace placeholder, just return to caller
ENTRY(ftrace_stub)
j_s [blink]
ENDPROC(ftrace_stub)

; save ABI necessary registers
.macro SAVE_ABI
PUSHR blink
PUSHR fp
.endm

.macro LOAD_ABI
POPR fp
POPR blink
.endm

.macro SAVE_ABI_RET
PUSHR r0
PUSHR r1
PUSHR blink
.endm

.macro LOAD_ABI_RET
POPR blink
POPR r1
POPR r0
.endm

#ifdef CONFIG_FUNCTION_GRAPH_TRACER

; Return to the actual caller
ENTRY(return_to_handler)
; Save return value (if any) from handled routine
SAVE_ABI_RET

; Will return true blink on r0
MOVA r0, @ftrace_return_to_handler
jl [r0]

MOVR r2, r0

LOAD_ABI_RET

j [r2]

ENDPROC(return_to_handler)
#endif

; r0 has the frompc (targets parent ip)
; blink has the selfpc (target ip)
ENTRY(_mcount)

#ifdef CONFIG_FUNCTION_GRAPH_TRACER

; *ftrace_graph_return != ftrace_stub
MOVA r3, ftrace_graph_return
LD64 r3, r3
MOVA r4, @ftrace_stub
brne r3, r4, @do_ftrace_graph_caller

; *ftrace_graph_entry != *ftrace_graph_entry_stub
MOVA r3, @ftrace_graph_entry
LD64 r3, r3
MOVA r4, @ftrace_graph_entry_stub
brne r3, r4, @do_ftrace_graph_caller

#endif

; *ftrace_trace_function != ftrace_stub
MOVA r2, ftrace_trace_function
LD64 r2, r2

MOVA r3, @ftrace_stub
brne r2, r3, @do_trace

; Return
j_s [blink]

ENDPROC(_mcount)

#ifdef CONFIG_FUNCTION_GRAPH_TRACER
do_ftrace_graph_caller:

SAVE_ABI

ADDR r0, fp, 8
MOVR r1, blink

MOVA r2, @prepare_ftrace_return
jl [r2]

LOAD_ABI

j_s [blink]
#endif

do_trace:
SAVE_ABI
MOVR r1, r0
MOVR r0, blink

jl [r2]

LOAD_ABI
j_s [blink]