Skip to content

ARCv2/v3: Implemented ftrace #151

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

Open
wants to merge 2 commits into
base: abrodkin-arc64-5.15.y
Choose a base branch
from
Open
Show file tree
Hide file tree
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
Expand Up @@ -32,6 +32,8 @@ config ARC
select HAVE_ARCH_TRANSPARENT_HUGEPAGE if ARC_MMU_V4
select HAVE_DEBUG_STACKOVERFLOW
select HAVE_DEBUG_KMEMLEAK
select HAVE_FUNCTION_TRACER if (ISA_ARCV2 || ISA_ARCV3)
select HAVE_FUNCTION_GRAPH_TRACER if ISA_ARCV3 || (ISA_ARCV2 && GCC_VERSION >= 140000)
select HAVE_FUTEX_CMPXCHG if FUTEX
select HAVE_IOREMAP_PROT if !(ISA_ARCV3 && !64BIT)
select HAVE_KERNEL_GZIP
Expand Down
6 changes: 6 additions & 0 deletions arch/arc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ endif
endif
endif

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

ifdef CONFIG_ISA_ARCV3
ifdef CONFIG_64BIT
UTS_MACHINE := arc64
Expand Down
10 changes: 10 additions & 0 deletions arch/arc/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ obj-y := arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o
obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o
obj-y += ctx_sw_asm.o

ifdef CONFIG_FTRACE
# ftrace can't 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

ifdef CONFIG_ISA_ARCOMPACT
obj-y += intc-compact.o
else
Expand Down
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 */
112 changes: 112 additions & 0 deletions arch/arc/kernel/mcount.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Function tracing support for ARC
*
* Copyright (C) 2023 Synopsys, Inc. (www.synopsys.com)
*/

#include <linux/linkage.h>
#include <asm-generic/export.h>
#include <asm/assembler.h>

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

.macro SAVE_ABI
PUSHR blink
PUSHR fp
.endm

.macro LOAD_ABI
POPR fp
POPR blink
.endm

.macro SAVE_ABI_RET
PUSHR r0
PUSHR r1
.endm

.macro LOAD_ABI_RET
POPR r1
POPR r0
.endm

; 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
LDR 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
LDR 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
LDR r2, r2
MOVA r3, @ftrace_stub
brne r2, r3, @do_trace
; Return
j_s [blink]

ENDPROC(_mcount)

#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)

do_ftrace_graph_caller:

#ifndef CONFIG_ISA_ARCV3
; ABI does not allow us to infer blink location
; ARC GCC port inserts into r1 the delta between the pushed blink and
; the sp at call time
; We perform calculation before any push (sp change) happens
ADDR r0, r1, sp
SAVE_ABI
SUBR r0, r0, REGSZASM
#else
SAVE_ABI
ADDR r0, fp, REGSZASM
#endif

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 state and jump to blink (in stack)
LOAD_ABI
j_s [blink]

EXPORT_SYMBOL(_mcount)