Skip to content

Commit

Permalink
ARC: implement syscall tracepoints
Browse files Browse the repository at this point in the history
Implement all the bits required to support HAVE_SYSCALL_TRACEPOINTS
according to Documentation/trace/ftrace-design.rst.

Signed-off-by: Sergey Matyukevich <sergey.matyukevich@synopsys.com>
Signed-off-by: Vineet Gupta <vgupta@kernel.org>
  • Loading branch information
Sergey Matyukevich authored and Vineet Gupta committed Apr 25, 2022
1 parent b3bbf6a commit fb0b549
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 10 deletions.
1 change: 1 addition & 0 deletions arch/arc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ config ARC
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_MOD_ARCH_SPECIFIC
select HAVE_PERF_EVENTS
select HAVE_SYSCALL_TRACEPOINTS
select IRQ_DOMAIN
select MODULES_USE_ELF_RELA
select OF
Expand Down
2 changes: 2 additions & 0 deletions arch/arc/include/asm/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <asm/unistd.h>
#include <asm/ptrace.h> /* in_syscall() */

extern void *sys_call_table[];

static inline long
syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
{
Expand Down
5 changes: 4 additions & 1 deletion arch/arc/include/asm/thread_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ static inline __attribute_const__ struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_AUDIT 4 /* syscall auditing active */
#define TIF_NOTIFY_SIGNAL 5 /* signal notifications exist */
#define TIF_SYSCALL_TRACE 15 /* syscall trace active */

/* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 16
#define TIF_SYSCALL_TRACEPOINT 17 /* syscall tracepoint instrumentation */

#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
Expand All @@ -89,11 +89,14 @@ static inline __attribute_const__ struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_NOTIFY_SIGNAL (1<<TIF_NOTIFY_SIGNAL)
#define _TIF_MEMDIE (1<<TIF_MEMDIE)
#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)

/* work to do on interrupt/exception return */
#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
_TIF_NOTIFY_RESUME | _TIF_NOTIFY_SIGNAL)

#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT)

/*
* _TIF_ALLWORK_MASK includes SYSCALL_TRACE, but we don't need it.
* SYSCALL_TRACE is anyway separately/unconditionally tested right after a
Expand Down
12 changes: 6 additions & 6 deletions arch/arc/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ ENTRY(sys_clone_wrapper)
DISCARD_CALLEE_SAVED_USER

GET_CURR_THR_INFO_FLAGS r10
btst r10, TIF_SYSCALL_TRACE
bnz tracesys_exit
and.f 0, r10, _TIF_SYSCALL_WORK
bnz tracesys_exit

b .Lret_from_system_call
END(sys_clone_wrapper)
Expand All @@ -41,8 +41,8 @@ ENTRY(sys_clone3_wrapper)
DISCARD_CALLEE_SAVED_USER

GET_CURR_THR_INFO_FLAGS r10
btst r10, TIF_SYSCALL_TRACE
bnz tracesys_exit
and.f 0, r10, _TIF_SYSCALL_WORK
bnz tracesys_exit

b .Lret_from_system_call
END(sys_clone3_wrapper)
Expand Down Expand Up @@ -247,8 +247,8 @@ ENTRY(EV_Trap)

; If syscall tracing ongoing, invoke pre-post-hooks
GET_CURR_THR_INFO_FLAGS r10
btst r10, TIF_SYSCALL_TRACE
bnz tracesys ; this never comes back
and.f 0, r10, _TIF_SYSCALL_WORK
bnz tracesys ; this never comes back

;============ Normal syscall case

Expand Down
21 changes: 18 additions & 3 deletions arch/arc/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#include <linux/unistd.h>
#include <linux/elf.h>

#define CREATE_TRACE_POINTS
#include <trace/events/syscalls.h>

struct pt_regs_offset {
const char *name;
int offset;
Expand Down Expand Up @@ -340,15 +343,27 @@ long arch_ptrace(struct task_struct *child, long request,

asmlinkage int syscall_trace_entry(struct pt_regs *regs)
{
if (ptrace_report_syscall_entry(regs))
return ULONG_MAX;
if (test_thread_flag(TIF_SYSCALL_TRACE))
if (ptrace_report_syscall_entry(regs))
return ULONG_MAX;

#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_enter(regs, syscall_get_nr(current, regs));
#endif

return regs->r8;
}

asmlinkage void syscall_trace_exit(struct pt_regs *regs)
{
ptrace_report_syscall_exit(regs, 0);
if (test_thread_flag(TIF_SYSCALL_TRACE))
ptrace_report_syscall_exit(regs, 0);

#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_exit(regs, regs_return_value(regs));
#endif
}

int regs_query_register_offset(const char *name)
Expand Down

0 comments on commit fb0b549

Please sign in to comment.