Commit 2f7932b0 authored by Guo Ren's avatar Guo Ren

csky: Update syscall_trace_enter/exit implementation

Previous syscall_trace implementation couldn't support AUDITSYSCALL and
SYSCALL_TRACEPOINTS. Now we redesign it to support audit_syscall
and syscall_tracepoints just like other archs'.
Signed-off-by: default avatarGuo Ren <ren_guo@c-sky.com>
Cc: Dmitry V. Levin <ldv@altlinux.org>
Cc: Arnd Bergmann <arnd@arndb.de>
parent cfa4d93b
...@@ -29,6 +29,7 @@ config CSKY ...@@ -29,6 +29,7 @@ config CSKY
select GENERIC_SCHED_CLOCK select GENERIC_SCHED_CLOCK
select GENERIC_SMP_IDLE_THREAD select GENERIC_SMP_IDLE_THREAD
select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRACEHOOK
select HAVE_ARCH_AUDITSYSCALL
select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE
select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_GRAPH_TRACER
...@@ -39,6 +40,7 @@ config CSKY ...@@ -39,6 +40,7 @@ config CSKY
select HAVE_PERF_EVENTS select HAVE_PERF_EVENTS
select HAVE_DMA_API_DEBUG select HAVE_DMA_API_DEBUG
select HAVE_DMA_CONTIGUOUS select HAVE_DMA_CONTIGUOUS
select HAVE_SYSCALL_TRACEPOINTS
select MAY_HAVE_SPARSE_IRQ select MAY_HAVE_SPARSE_IRQ
select MODULES_USE_ELF_RELA if MODULES select MODULES_USE_ELF_RELA if MODULES
select OF select OF
......
...@@ -157,4 +157,8 @@ ...@@ -157,4 +157,8 @@
cpwcr \rx, cpcr31 cpwcr \rx, cpcr31
.endm .endm
.macro ANDI_R3 rx, imm
lsri \rx, 3
andi \rx, (\imm >> 3)
.endm
#endif /* __ASM_CSKY_ENTRY_H */ #endif /* __ASM_CSKY_ENTRY_H */
...@@ -175,4 +175,9 @@ ...@@ -175,4 +175,9 @@
lrw \rx, (PHYS_OFFSET + 0x20000000) | 0xe lrw \rx, (PHYS_OFFSET + 0x20000000) | 0xe
mtcr \rx, cr<31, 15> mtcr \rx, cr<31, 15>
.endm .endm
.macro ANDI_R3 rx, imm
lsri \rx, 3
andi \rx, (\imm >> 3)
.endm
#endif /* __ASM_CSKY_ENTRY_H */ #endif /* __ASM_CSKY_ENTRY_H */
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include <abi/regdef.h> #include <abi/regdef.h>
#include <uapi/linux/audit.h> #include <uapi/linux/audit.h>
extern void *sys_call_table[];
static inline int static inline int
syscall_get_nr(struct task_struct *task, struct pt_regs *regs) syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
{ {
......
...@@ -51,29 +51,26 @@ static inline struct thread_info *current_thread_info(void) ...@@ -51,29 +51,26 @@ static inline struct thread_info *current_thread_info(void)
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
/* entry.S relies on these definitions!
* bits 0-5 are tested at every exception exit
*/
#define TIF_SIGPENDING 0 /* signal pending */ #define TIF_SIGPENDING 0 /* signal pending */
#define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ #define TIF_NOTIFY_RESUME 1 /* callback before returning to user */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_SYSCALL_TRACE 5 /* syscall trace active */ #define TIF_SYSCALL_TRACE 3 /* syscall trace active */
#define TIF_DELAYED_TRACE 14 /* single step a syscall */ #define TIF_SYSCALL_TRACEPOINT 4 /* syscall tracepoint instrumentation */
#define TIF_SYSCALL_AUDIT 5 /* syscall auditing */
#define TIF_POLLING_NRFLAG 16 /* poll_idle() is TIF_NEED_RESCHED */ #define TIF_POLLING_NRFLAG 16 /* poll_idle() is TIF_NEED_RESCHED */
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_FREEZE 19 /* thread is freezing for suspend */
#define TIF_RESTORE_SIGMASK 20 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 20 /* restore signal mask in do_signal() */
#define TIF_SECCOMP 21 /* secure computing */ #define TIF_SECCOMP 21 /* secure computing */
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_DELAYED_TRACE (1 << TIF_DELAYED_TRACE) #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_MEMDIE (1 << TIF_MEMDIE) #define _TIF_MEMDIE (1 << TIF_MEMDIE)
#define _TIF_FREEZE (1 << TIF_FREEZE) #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) #define _TIF_SECCOMP (1 << TIF_SECCOMP)
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
#endif /* _ASM_CSKY_THREAD_INFO_H */ #endif /* _ASM_CSKY_THREAD_INFO_H */
...@@ -2,3 +2,5 @@ ...@@ -2,3 +2,5 @@
// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
#include <uapi/asm/unistd.h> #include <uapi/asm/unistd.h>
#define NR_syscalls (__NR_syscalls)
...@@ -62,6 +62,11 @@ struct user_fp { ...@@ -62,6 +62,11 @@ struct user_fp {
#define instruction_pointer(regs) ((regs)->pc) #define instruction_pointer(regs) ((regs)->pc)
#define profile_pc(regs) instruction_pointer(regs) #define profile_pc(regs) instruction_pointer(regs)
static inline unsigned long regs_return_value(struct pt_regs *regs)
{
return regs->a0;
}
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* _CSKY_PTRACE_H */ #endif /* _CSKY_PTRACE_H */
...@@ -136,8 +136,9 @@ ENTRY(csky_systemcall) ...@@ -136,8 +136,9 @@ ENTRY(csky_systemcall)
bmaski r10, THREAD_SHIFT bmaski r10, THREAD_SHIFT
andn r9, r10 andn r9, r10
ldw r8, (r9, TINFO_FLAGS) ldw r8, (r9, TINFO_FLAGS)
btsti r8, TIF_SYSCALL_TRACE ANDI_R3 r8, (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT)
bt 1f cmpnei r8, 0
bt csky_syscall_trace
#if defined(__CSKYABIV2__) #if defined(__CSKYABIV2__)
subi sp, 8 subi sp, 8
stw r5, (sp, 0x4) stw r5, (sp, 0x4)
...@@ -150,10 +151,9 @@ ENTRY(csky_systemcall) ...@@ -150,10 +151,9 @@ ENTRY(csky_systemcall)
stw a0, (sp, LSAVE_A0) /* Save return value */ stw a0, (sp, LSAVE_A0) /* Save return value */
jmpi ret_from_exception jmpi ret_from_exception
1: csky_syscall_trace:
movi a0, 0 /* enter system call */ mov a0, sp /* sp = pt_regs pointer */
mov a1, sp /* sp = pt_regs pointer */ jbsr syscall_trace_enter
jbsr syscall_trace
/* Prepare args before do system call */ /* Prepare args before do system call */
ldw a0, (sp, LSAVE_A0) ldw a0, (sp, LSAVE_A0)
ldw a1, (sp, LSAVE_A1) ldw a1, (sp, LSAVE_A1)
...@@ -173,9 +173,8 @@ ENTRY(csky_systemcall) ...@@ -173,9 +173,8 @@ ENTRY(csky_systemcall)
#endif #endif
stw a0, (sp, LSAVE_A0) /* Save return value */ stw a0, (sp, LSAVE_A0) /* Save return value */
movi a0, 1 /* leave system call */ mov a0, sp /* right now, sp --> pt_regs */
mov a1, sp /* right now, sp --> pt_regs */ jbsr syscall_trace_exit
jbsr syscall_trace
br ret_from_exception br ret_from_exception
ENTRY(ret_from_kernel_thread) ENTRY(ret_from_kernel_thread)
...@@ -191,11 +190,11 @@ ENTRY(ret_from_fork) ...@@ -191,11 +190,11 @@ ENTRY(ret_from_fork)
andn r9, r10 andn r9, r10
ldw r8, (r9, TINFO_FLAGS) ldw r8, (r9, TINFO_FLAGS)
movi r11_sig, 1 movi r11_sig, 1
btsti r8, TIF_SYSCALL_TRACE ANDI_R3 r8, (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT)
cmpnei r8, 0
bf 3f bf 3f
movi a0, 1 mov a0, sp /* sp = pt_regs pointer */
mov a1, sp /* sp = pt_regs pointer */ jbsr syscall_trace_exit
jbsr syscall_trace
3: 3:
jbsr ret_from_exception jbsr ret_from_exception
......
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
#include <linux/audit.h>
#include <linux/elf.h> #include <linux/elf.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -11,6 +12,7 @@ ...@@ -11,6 +12,7 @@
#include <linux/sched/task_stack.h> #include <linux/sched/task_stack.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/tracehook.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/user.h> #include <linux/user.h>
...@@ -22,6 +24,9 @@ ...@@ -22,6 +24,9 @@
#include <abi/regdef.h> #include <abi/regdef.h>
#define CREATE_TRACE_POINTS
#include <trace/events/syscalls.h>
/* sets the trace bits. */ /* sets the trace bits. */
#define TRACE_MODE_SI (1 << 14) #define TRACE_MODE_SI (1 << 14)
#define TRACE_MODE_RUN 0 #define TRACE_MODE_RUN 0
...@@ -207,35 +212,26 @@ long arch_ptrace(struct task_struct *child, long request, ...@@ -207,35 +212,26 @@ long arch_ptrace(struct task_struct *child, long request,
return ret; return ret;
} }
/* asmlinkage void syscall_trace_enter(struct pt_regs *regs)
* If process's system calls is traces, do some corresponding handles in this
* function before entering system call function and after exiting system call
* function.
*/
asmlinkage void syscall_trace(int why, struct pt_regs *regs)
{ {
long saved_why; if (test_thread_flag(TIF_SYSCALL_TRACE))
/* tracehook_report_syscall_entry(regs);
* Save saved_why, why is used to denote syscall entry/exit;
* why = 0:entry, why = 1: exit if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
*/ trace_sys_enter(regs, syscall_get_nr(current, regs));
saved_why = regs->regs[SYSTRACE_SAVENUM];
regs->regs[SYSTRACE_SAVENUM] = why; audit_syscall_entry(regs_syscallid(regs), regs->a0, regs->a1, regs->a2, regs->a3);
}
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0)); asmlinkage void syscall_trace_exit(struct pt_regs *regs)
{
/* audit_syscall_exit(regs);
* this isn't the same as continuing with a signal, but it will do
* for normal use. strace only continues with a signal if the if (test_thread_flag(TIF_SYSCALL_TRACE))
* stopping signal is not SIGTRAP. -brl tracehook_report_syscall_exit(regs, 0);
*/
if (current->exit_code) {
send_sig(current->exit_code, current, 1);
current->exit_code = 0;
}
regs->regs[SYSTRACE_SAVENUM] = saved_why; if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_exit(regs, syscall_get_return_value(current, regs));
} }
extern void show_stack(struct task_struct *task, unsigned long *stack); extern void show_stack(struct task_struct *task, unsigned long *stack);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment