From 28bb030f93334495ddc64ade0bff18721bf7023d Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Fri, 1 Mar 2019 08:50:36 +0800 Subject: csky/ftrace: Add dynamic function tracer (include graph tracer) Support dynamic ftrace including dynamic graph tracer. Gcc-csky with -pg will produce call site in every function prologue and we can use these call site to hook trace function. gcc with -pg origin call site: push lr jbsr _mcount nop32 nop32 If the (callee - caller)'s offset is in range of bsr instruction, we'll modify code with: push lr bsr _mcount nop32 nop32 Else if the (callee - caller)'s offset is out of bsr instrunction, we'll modify code with: push lr movih r26, ... ori r26, ... jsr r26 (r26 is reserved for jsr link reg in csky abiv2 spec.) Signed-off-by: Guo Ren --- arch/csky/include/asm/ftrace.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'arch/csky/include') diff --git a/arch/csky/include/asm/ftrace.h b/arch/csky/include/asm/ftrace.h index 7547c45312a8..ba35d93ecda2 100644 --- a/arch/csky/include/asm/ftrace.h +++ b/arch/csky/include/asm/ftrace.h @@ -4,10 +4,26 @@ #ifndef __ASM_CSKY_FTRACE_H #define __ASM_CSKY_FTRACE_H -#define MCOUNT_INSN_SIZE 4 +#define MCOUNT_INSN_SIZE 14 #define HAVE_FUNCTION_GRAPH_FP_TEST #define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR +#define MCOUNT_ADDR ((unsigned long)_mcount) + +#ifndef __ASSEMBLY__ + +extern void _mcount(unsigned long); + +extern void ftrace_graph_call(void); + +static inline unsigned long ftrace_call_adjust(unsigned long addr) +{ + return addr; +} + +struct dyn_arch_ftrace { +}; +#endif /* !__ASSEMBLY__ */ #endif /* __ASM_CSKY_FTRACE_H */ -- cgit v1.2.3 From 2f7932b011e7fb9f98732f95a68f6017d4d8c542 Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Wed, 20 Mar 2019 18:27:27 +0800 Subject: 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: Guo Ren Cc: Dmitry V. Levin Cc: Arnd Bergmann --- arch/csky/Kconfig | 2 ++ arch/csky/abiv1/inc/abi/entry.h | 4 +++ arch/csky/abiv2/inc/abi/entry.h | 5 ++++ arch/csky/include/asm/syscall.h | 2 ++ arch/csky/include/asm/thread_info.h | 27 +++++++++----------- arch/csky/include/asm/unistd.h | 2 ++ arch/csky/include/uapi/asm/ptrace.h | 5 ++++ arch/csky/kernel/entry.S | 25 +++++++++---------- arch/csky/kernel/ptrace.c | 50 +++++++++++++++++-------------------- 9 files changed, 67 insertions(+), 55 deletions(-) (limited to 'arch/csky/include') diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig index 60ebaa325584..c4974cf6a222 100644 --- a/arch/csky/Kconfig +++ b/arch/csky/Kconfig @@ -29,6 +29,7 @@ config CSKY select GENERIC_SCHED_CLOCK select GENERIC_SMP_IDLE_THREAD select HAVE_ARCH_TRACEHOOK + select HAVE_ARCH_AUDITSYSCALL select HAVE_DYNAMIC_FTRACE select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_GRAPH_TRACER @@ -39,6 +40,7 @@ config CSKY select HAVE_PERF_EVENTS select HAVE_DMA_API_DEBUG select HAVE_DMA_CONTIGUOUS + select HAVE_SYSCALL_TRACEPOINTS select MAY_HAVE_SPARSE_IRQ select MODULES_USE_ELF_RELA if MODULES select OF diff --git a/arch/csky/abiv1/inc/abi/entry.h b/arch/csky/abiv1/inc/abi/entry.h index 3f3faab3d747..7dacce4c0f15 100644 --- a/arch/csky/abiv1/inc/abi/entry.h +++ b/arch/csky/abiv1/inc/abi/entry.h @@ -157,4 +157,8 @@ cpwcr \rx, cpcr31 .endm +.macro ANDI_R3 rx, imm + lsri \rx, 3 + andi \rx, (\imm >> 3) +.endm #endif /* __ASM_CSKY_ENTRY_H */ diff --git a/arch/csky/abiv2/inc/abi/entry.h b/arch/csky/abiv2/inc/abi/entry.h index edc5cc04c4de..ea376ed716c4 100644 --- a/arch/csky/abiv2/inc/abi/entry.h +++ b/arch/csky/abiv2/inc/abi/entry.h @@ -175,4 +175,9 @@ lrw \rx, (PHYS_OFFSET + 0x20000000) | 0xe mtcr \rx, cr<31, 15> .endm + +.macro ANDI_R3 rx, imm + lsri \rx, 3 + andi \rx, (\imm >> 3) +.endm #endif /* __ASM_CSKY_ENTRY_H */ diff --git a/arch/csky/include/asm/syscall.h b/arch/csky/include/asm/syscall.h index bda0a446c63e..850b694a463e 100644 --- a/arch/csky/include/asm/syscall.h +++ b/arch/csky/include/asm/syscall.h @@ -8,6 +8,8 @@ #include #include +extern void *sys_call_table[]; + static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs) { diff --git a/arch/csky/include/asm/thread_info.h b/arch/csky/include/asm/thread_info.h index 0e9d035d712b..0b546a55a8bf 100644 --- a/arch/csky/include/asm/thread_info.h +++ b/arch/csky/include/asm/thread_info.h @@ -51,29 +51,26 @@ static inline struct thread_info *current_thread_info(void) #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_NOTIFY_RESUME 1 /* callback before returning to user */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ -#define TIF_SYSCALL_TRACE 5 /* syscall trace active */ -#define TIF_DELAYED_TRACE 14 /* single step a syscall */ +#define TIF_SYSCALL_TRACE 3 /* syscall trace active */ +#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_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_SECCOMP 21 /* secure computing */ -#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) -#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) -#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) -#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) -#define _TIF_DELAYED_TRACE (1 << TIF_DELAYED_TRACE) -#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) +#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) +#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) +#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) +#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) +#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) +#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) +#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_MEMDIE (1 << TIF_MEMDIE) -#define _TIF_FREEZE (1 << TIF_FREEZE) -#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) -#define _TIF_SECCOMP (1 << TIF_SECCOMP) +#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) +#define _TIF_SECCOMP (1 << TIF_SECCOMP) #endif /* _ASM_CSKY_THREAD_INFO_H */ diff --git a/arch/csky/include/asm/unistd.h b/arch/csky/include/asm/unistd.h index 284487477a61..da7a18295615 100644 --- a/arch/csky/include/asm/unistd.h +++ b/arch/csky/include/asm/unistd.h @@ -2,3 +2,5 @@ // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. #include + +#define NR_syscalls (__NR_syscalls) diff --git a/arch/csky/include/uapi/asm/ptrace.h b/arch/csky/include/uapi/asm/ptrace.h index a4eaa8ddf0b1..9bf5b1a415d0 100644 --- a/arch/csky/include/uapi/asm/ptrace.h +++ b/arch/csky/include/uapi/asm/ptrace.h @@ -62,6 +62,11 @@ struct user_fp { #define instruction_pointer(regs) ((regs)->pc) #define profile_pc(regs) instruction_pointer(regs) +static inline unsigned long regs_return_value(struct pt_regs *regs) +{ + return regs->a0; +} + #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ #endif /* _CSKY_PTRACE_H */ diff --git a/arch/csky/kernel/entry.S b/arch/csky/kernel/entry.S index 5137ed9062bd..ecc6e7d2e95d 100644 --- a/arch/csky/kernel/entry.S +++ b/arch/csky/kernel/entry.S @@ -136,8 +136,9 @@ ENTRY(csky_systemcall) bmaski r10, THREAD_SHIFT andn r9, r10 ldw r8, (r9, TINFO_FLAGS) - btsti r8, TIF_SYSCALL_TRACE - bt 1f + ANDI_R3 r8, (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT) + cmpnei r8, 0 + bt csky_syscall_trace #if defined(__CSKYABIV2__) subi sp, 8 stw r5, (sp, 0x4) @@ -150,10 +151,9 @@ ENTRY(csky_systemcall) stw a0, (sp, LSAVE_A0) /* Save return value */ jmpi ret_from_exception -1: - movi a0, 0 /* enter system call */ - mov a1, sp /* sp = pt_regs pointer */ - jbsr syscall_trace +csky_syscall_trace: + mov a0, sp /* sp = pt_regs pointer */ + jbsr syscall_trace_enter /* Prepare args before do system call */ ldw a0, (sp, LSAVE_A0) ldw a1, (sp, LSAVE_A1) @@ -173,9 +173,8 @@ ENTRY(csky_systemcall) #endif stw a0, (sp, LSAVE_A0) /* Save return value */ - movi a0, 1 /* leave system call */ - mov a1, sp /* right now, sp --> pt_regs */ - jbsr syscall_trace + mov a0, sp /* right now, sp --> pt_regs */ + jbsr syscall_trace_exit br ret_from_exception ENTRY(ret_from_kernel_thread) @@ -191,11 +190,11 @@ ENTRY(ret_from_fork) andn r9, r10 ldw r8, (r9, TINFO_FLAGS) 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 - movi a0, 1 - mov a1, sp /* sp = pt_regs pointer */ - jbsr syscall_trace + mov a0, sp /* sp = pt_regs pointer */ + jbsr syscall_trace_exit 3: jbsr ret_from_exception diff --git a/arch/csky/kernel/ptrace.c b/arch/csky/kernel/ptrace.c index f2f12fff36f7..91bc74bb569f 100644 --- a/arch/csky/kernel/ptrace.c +++ b/arch/csky/kernel/ptrace.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. +#include #include #include #include @@ -11,6 +12,7 @@ #include #include #include +#include #include #include @@ -22,6 +24,9 @@ #include +#define CREATE_TRACE_POINTS +#include + /* sets the trace bits. */ #define TRACE_MODE_SI (1 << 14) #define TRACE_MODE_RUN 0 @@ -207,35 +212,26 @@ long arch_ptrace(struct task_struct *child, long request, return ret; } -/* - * 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) +asmlinkage void syscall_trace_enter(struct pt_regs *regs) { - long saved_why; - /* - * Save saved_why, why is used to denote syscall entry/exit; - * why = 0:entry, why = 1: exit - */ - saved_why = regs->regs[SYSTRACE_SAVENUM]; - regs->regs[SYSTRACE_SAVENUM] = why; - - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) - ? 0x80 : 0)); - - /* - * 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 - * stopping signal is not SIGTRAP. -brl - */ - if (current->exit_code) { - send_sig(current->exit_code, current, 1); - current->exit_code = 0; - } + if (test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_entry(regs); + + if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) + trace_sys_enter(regs, syscall_get_nr(current, regs)); + + audit_syscall_entry(regs_syscallid(regs), regs->a0, regs->a1, regs->a2, regs->a3); +} + +asmlinkage void syscall_trace_exit(struct pt_regs *regs) +{ + audit_syscall_exit(regs); + + if (test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_exit(regs, 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); -- cgit v1.2.3 From 1b2707fb1189b890e538ed09ca3f3512173cb836 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 22 Mar 2019 20:19:14 +0900 Subject: csky: remove redundant generic-y Since commit 7cbbbb8bc297 ("kbuild: warn redundant generic-y"), redundant generic-y is reported. I missed to delete this one. scripts/Makefile.asm-generic:25: redundant generic-y found in arch/csky/include/asm/Kbuild: ftrace.h In this case, csky-specific implementation exists in arch/csky/include/asm/ftrace.h Signed-off-by: Masahiro Yamada Signed-off-by: Guo Ren --- arch/csky/include/asm/Kbuild | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/csky/include') diff --git a/arch/csky/include/asm/Kbuild b/arch/csky/include/asm/Kbuild index 2a0abe8f2a35..e01a5768f89c 100644 --- a/arch/csky/include/asm/Kbuild +++ b/arch/csky/include/asm/Kbuild @@ -12,7 +12,6 @@ generic-y += dma-mapping.h generic-y += emergency-restart.h generic-y += exec.h generic-y += fb.h -generic-y += ftrace.h generic-y += futex.h generic-y += gpio.h generic-y += hardirq.h -- cgit v1.2.3 From f335b10f3b6ca2d11adef95092fff65152c31b48 Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Tue, 26 Mar 2019 15:56:33 +0800 Subject: csky: Add non-uapi asm/ptrace.h namespace Move #ifdef __KERNEL__ code in the uapi namespace to non-uapi include/asm/ptrace.h namespace and remove #ifdef __KERNEL__ in include/asm/ptrace.h. Seperate ptrace.h in uapi and non-uapi is more common and clear. Signed-off-by: Guo Ren Cc: Dmitry V. Levin --- arch/csky/include/asm/ptrace.h | 29 +++++++++++++++++++++++++++++ arch/csky/include/uapi/asm/ptrace.h | 20 -------------------- 2 files changed, 29 insertions(+), 20 deletions(-) create mode 100644 arch/csky/include/asm/ptrace.h (limited to 'arch/csky/include') diff --git a/arch/csky/include/asm/ptrace.h b/arch/csky/include/asm/ptrace.h new file mode 100644 index 000000000000..1e00578166f0 --- /dev/null +++ b/arch/csky/include/asm/ptrace.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_PTRACE_H +#define __ASM_CSKY_PTRACE_H + +#include + +#ifndef __ASSEMBLY__ + +#define PS_S 0x80000000 /* Supervisor Mode */ + +#define arch_has_single_step() (1) +#define current_pt_regs() \ +({ (struct pt_regs *)((char *)current_thread_info() + THREAD_SIZE) - 1; }) + +#define user_stack_pointer(regs) ((regs)->usp) + +#define user_mode(regs) (!((regs)->sr & PS_S)) +#define instruction_pointer(regs) ((regs)->pc) +#define profile_pc(regs) instruction_pointer(regs) + +static inline unsigned long regs_return_value(struct pt_regs *regs) +{ + return regs->a0; +} + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_CSKY_PTRACE_H */ diff --git a/arch/csky/include/uapi/asm/ptrace.h b/arch/csky/include/uapi/asm/ptrace.h index 9bf5b1a415d0..4e248d5b86ef 100644 --- a/arch/csky/include/uapi/asm/ptrace.h +++ b/arch/csky/include/uapi/asm/ptrace.h @@ -48,25 +48,5 @@ struct user_fp { unsigned long reserved; }; -#ifdef __KERNEL__ - -#define PS_S 0x80000000 /* Supervisor Mode */ - -#define arch_has_single_step() (1) -#define current_pt_regs() \ -({ (struct pt_regs *)((char *)current_thread_info() + THREAD_SIZE) - 1; }) - -#define user_stack_pointer(regs) ((regs)->usp) - -#define user_mode(regs) (!((regs)->sr & PS_S)) -#define instruction_pointer(regs) ((regs)->pc) -#define profile_pc(regs) instruction_pointer(regs) - -static inline unsigned long regs_return_value(struct pt_regs *regs) -{ - return regs->a0; -} - -#endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ #endif /* _CSKY_PTRACE_H */ -- cgit v1.2.3 From f4625ee0e40a5c724bb3f3eb7fd89e491bfd7646 Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Sat, 30 Mar 2019 23:44:34 +0800 Subject: csky: Use in_syscall & forget_syscall instead of r11_sig We could use regs->sr 16-24 bits to detect syscall: VEC_TRAP0 and r11_sig is no necessary for current implementation. In this patch, we implement the in_syscall and forget_syscall which are inspired from arm & nds32, but csky pt_regs has no syscall_num element and we just set zero to regs->sr's vector-bits-field instead. For ret_from_fork, current task was forked from parent which is in syscall progress and its regs->sr has been already setted with VEC_TRAP0. See: arch/csky/kernel/process.c: copy_thread() Signed-off-by: Guo Ren --- arch/csky/abiv1/inc/abi/regdef.h | 2 -- arch/csky/abiv2/inc/abi/regdef.h | 2 -- arch/csky/include/asm/ptrace.h | 12 ++++++++++++ arch/csky/kernel/entry.S | 11 +---------- arch/csky/kernel/signal.c | 15 +++++++++------ 5 files changed, 22 insertions(+), 20 deletions(-) (limited to 'arch/csky/include') diff --git a/arch/csky/abiv1/inc/abi/regdef.h b/arch/csky/abiv1/inc/abi/regdef.h index 876689291b71..9e7e692dd271 100644 --- a/arch/csky/abiv1/inc/abi/regdef.h +++ b/arch/csky/abiv1/inc/abi/regdef.h @@ -5,8 +5,6 @@ #define __ASM_CSKY_REGDEF_H #define syscallid r1 -#define r11_sig r11 - #define regs_syscallid(regs) regs->regs[9] /* diff --git a/arch/csky/abiv2/inc/abi/regdef.h b/arch/csky/abiv2/inc/abi/regdef.h index c72abb781bdc..652f5ce4c3dd 100644 --- a/arch/csky/abiv2/inc/abi/regdef.h +++ b/arch/csky/abiv2/inc/abi/regdef.h @@ -5,8 +5,6 @@ #define __ASM_CSKY_REGDEF_H #define syscallid r7 -#define r11_sig r11 - #define regs_syscallid(regs) regs->regs[3] /* diff --git a/arch/csky/include/asm/ptrace.h b/arch/csky/include/asm/ptrace.h index 1e00578166f0..d0aba7b32417 100644 --- a/arch/csky/include/asm/ptrace.h +++ b/arch/csky/include/asm/ptrace.h @@ -5,6 +5,8 @@ #define __ASM_CSKY_PTRACE_H #include +#include +#include #ifndef __ASSEMBLY__ @@ -20,6 +22,16 @@ #define instruction_pointer(regs) ((regs)->pc) #define profile_pc(regs) instruction_pointer(regs) +static inline bool in_syscall(struct pt_regs const *regs) +{ + return ((regs->sr >> 16) & 0xff) == VEC_TRAP0; +} + +static inline void forget_syscall(struct pt_regs *regs) +{ + regs->sr &= ~(0xff << 16); +} + static inline unsigned long regs_return_value(struct pt_regs *regs) { return regs->a0; diff --git a/arch/csky/kernel/entry.S b/arch/csky/kernel/entry.S index ecc6e7d2e95d..b3b3b0bbfcc7 100644 --- a/arch/csky/kernel/entry.S +++ b/arch/csky/kernel/entry.S @@ -99,7 +99,6 @@ ENTRY(csky_\name) mov a0, sp movi a1, \is_write jbsr do_page_fault - movi r11_sig, 0 /* r11 = 0, Not a syscall. */ jmpi ret_from_exception .endm @@ -189,7 +188,6 @@ ENTRY(ret_from_fork) bmaski r10, THREAD_SHIFT andn r9, r10 ldw r8, (r9, TINFO_FLAGS) - movi r11_sig, 1 ANDI_R3 r8, (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT) cmpnei r8, 0 bf 3f @@ -224,12 +222,8 @@ exit_work: /* If thread_info->flag is empty, RESTORE_ALL */ cmpnei r8, 0 bf 1b - mov a1, sp mov a0, r8 - mov a2, r11_sig /* syscall? */ - btsti r8, TIF_SIGPENDING /* delivering a signal? */ - /* prevent further restarts(set r11 = 0) */ - clrt r11_sig + mov a1, sp jbsr do_notify_resume /* do signals */ br resume_userspace @@ -239,13 +233,11 @@ work_resched: jmpi schedule ENTRY(sys_rt_sigreturn) - movi r11_sig, 0 jmpi do_rt_sigreturn ENTRY(csky_trap) SAVE_ALL EPC_KEEP psrset ee - movi r11_sig, 0 /* r11 = 0, Not a syscall. */ mov a0, sp /* Push Stack pointer arg */ jbsr trap_c /* Call C-level trap handler */ jmpi ret_from_exception @@ -279,7 +271,6 @@ ENTRY(csky_get_tls) ENTRY(csky_irq) SAVE_ALL EPC_KEEP psrset ee - movi r11_sig, 0 /* r11 = 0, Not a syscall. */ #ifdef CONFIG_PREEMPT mov r9, sp /* Get current stack pointer */ diff --git a/arch/csky/kernel/signal.c b/arch/csky/kernel/signal.c index 207a891479d2..5a18940f0b09 100644 --- a/arch/csky/kernel/signal.c +++ b/arch/csky/kernel/signal.c @@ -224,7 +224,7 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs) * that the kernel can handle, and then we build all the user-level signal * handling stack-frames in one go after that. */ -static void do_signal(struct pt_regs *regs, int syscall) +static void do_signal(struct pt_regs *regs) { unsigned int retval = 0, continue_addr = 0, restart_addr = 0; struct ksignal ksig; @@ -241,7 +241,9 @@ static void do_signal(struct pt_regs *regs, int syscall) /* * If we were from a system call, check for system call restarting... */ - if (syscall) { + if (in_syscall(regs)) { + forget_syscall(regs); + continue_addr = regs->pc; #if defined(__CSKYABIV2__) restart_addr = continue_addr - 4; @@ -249,7 +251,6 @@ static void do_signal(struct pt_regs *regs, int syscall) restart_addr = continue_addr - 2; #endif retval = regs->a0; - /* * Prepare for system call restart. We do this here so that a * debugger will see the already changed. @@ -304,7 +305,9 @@ static void do_signal(struct pt_regs *regs, int syscall) } no_signal: - if (syscall) { + if (in_syscall(regs)) { + forget_syscall(regs); + /* * Handle restarting a different system call. As above, * if a debugger has chosen to restart at a different PC, @@ -333,10 +336,10 @@ no_signal: } asmlinkage void -do_notify_resume(unsigned int thread_flags, struct pt_regs *regs, int syscall) +do_notify_resume(unsigned int thread_flags, struct pt_regs *regs) { if (thread_flags & _TIF_SIGPENDING) - do_signal(regs, syscall); + do_signal(regs); if (thread_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); -- cgit v1.2.3 From f62e31623d718a7c20d9da98de48361624d7360a Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Mon, 8 Apr 2019 11:12:25 +0800 Subject: csky: Support dynamic start physical address Before this patch csky-linux need CONFIG_RAM_BASE to determine start physical address. Now we use phys_offset variable to replace the macro of PHYS_OFFSET and we setup phys_offset with real physical address which is determined during startup in head.S. With this patch we needn't re-compile kernel for different start physical address. ie: 0x0 / 0xc0000000 start physical address could use the same vmlinux, be care different start address must be 512MB aligned. Signed-off-by: Guo Ren Cc: Arnd Bergmann --- arch/csky/abiv1/inc/abi/ckmmu.h | 20 +++++++++++++++++++ arch/csky/abiv1/inc/abi/entry.h | 19 ++++++++++++++++-- arch/csky/abiv2/inc/abi/ckmmu.h | 20 +++++++++++++++++++ arch/csky/abiv2/inc/abi/entry.h | 24 +++++++++++++++++++++-- arch/csky/include/asm/mmu_context.h | 4 ++-- arch/csky/include/asm/page.h | 39 +++++++++++++++---------------------- arch/csky/kernel/entry.S | 6 ++++-- arch/csky/kernel/setup.c | 5 +++++ 8 files changed, 106 insertions(+), 31 deletions(-) (limited to 'arch/csky/include') diff --git a/arch/csky/abiv1/inc/abi/ckmmu.h b/arch/csky/abiv1/inc/abi/ckmmu.h index 3a002017bebe..85339bd224c4 100644 --- a/arch/csky/abiv1/inc/abi/ckmmu.h +++ b/arch/csky/abiv1/inc/abi/ckmmu.h @@ -40,6 +40,26 @@ static inline void write_mmu_entryhi(int value) cpwcr("cpcr4", value); } +static inline unsigned long read_mmu_msa0(void) +{ + return cprcr("cpcr30"); +} + +static inline void write_mmu_msa0(unsigned long value) +{ + cpwcr("cpcr30", value); +} + +static inline unsigned long read_mmu_msa1(void) +{ + return cprcr("cpcr31"); +} + +static inline void write_mmu_msa1(unsigned long value) +{ + cpwcr("cpcr31", value); +} + /* * TLB operations. */ diff --git a/arch/csky/abiv1/inc/abi/entry.h b/arch/csky/abiv1/inc/abi/entry.h index 4a485b142be1..18e2023bf165 100644 --- a/arch/csky/abiv1/inc/abi/entry.h +++ b/arch/csky/abiv1/inc/abi/entry.h @@ -144,9 +144,24 @@ .endm .macro SETUP_MMU rx - lrw \rx, PHYS_OFFSET | 0xe + /* Select MMU as co-processor */ + cpseti cp15 + + /* + * cpcr30 format: + * 31 - 29 | 28 - 4 | 3 | 2 | 1 | 0 + * BA Reserved C D V + */ + cprcr \rx, cpcr30 + lsri \rx, 28 + lsli \rx, 28 + addi \rx, 0xe cpwcr \rx, cpcr30 - lrw \rx, (PHYS_OFFSET + 0x20000000) | 0xe + + lsri \rx, 28 + addi \rx, 2 + lsli \rx, 28 + addi \rx, 0xe cpwcr \rx, cpcr31 .endm diff --git a/arch/csky/abiv2/inc/abi/ckmmu.h b/arch/csky/abiv2/inc/abi/ckmmu.h index 97230ad9427c..31d75e1a724a 100644 --- a/arch/csky/abiv2/inc/abi/ckmmu.h +++ b/arch/csky/abiv2/inc/abi/ckmmu.h @@ -42,6 +42,26 @@ static inline void write_mmu_entryhi(int value) mtcr("cr<4, 15>", value); } +static inline unsigned long read_mmu_msa0(void) +{ + return mfcr("cr<30, 15>"); +} + +static inline void write_mmu_msa0(unsigned long value) +{ + mtcr("cr<30, 15>", value); +} + +static inline unsigned long read_mmu_msa1(void) +{ + return mfcr("cr<31, 15>"); +} + +static inline void write_mmu_msa1(unsigned long value) +{ + mtcr("cr<31, 15>", value); +} + /* * TLB operations. */ diff --git a/arch/csky/abiv2/inc/abi/entry.h b/arch/csky/abiv2/inc/abi/entry.h index 6a0df655182c..c0a76c43cded 100644 --- a/arch/csky/abiv2/inc/abi/entry.h +++ b/arch/csky/abiv2/inc/abi/entry.h @@ -163,9 +163,29 @@ .endm .macro SETUP_MMU rx - lrw \rx, PHYS_OFFSET | 0xe + /* Check MMU on | off */ + mfcr \rx, cr18 + btsti \rx, 0 + bt 1f + grs \rx, 1f + br 2f +1: + /* + * cr<30, 15> format: + * 31 - 29 | 28 - 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 + * BA Reserved SH WA B SO SEC C D V + */ + mfcr \rx, cr<30, 15> +2: + lsri \rx, 28 + lsli \rx, 28 + addi \rx, 0x1ce mtcr \rx, cr<30, 15> - lrw \rx, (PHYS_OFFSET + 0x20000000) | 0xe + + lsri \rx, 28 + addi \rx, 2 + lsli \rx, 28 + addi \rx, 0x1ce mtcr \rx, cr<31, 15> .endm diff --git a/arch/csky/include/asm/mmu_context.h b/arch/csky/include/asm/mmu_context.h index b2905c0485a7..c41f86b22460 100644 --- a/arch/csky/include/asm/mmu_context.h +++ b/arch/csky/include/asm/mmu_context.h @@ -17,7 +17,7 @@ static inline void tlbmiss_handler_setup_pgd(unsigned long pgd, bool kernel) { pgd -= PAGE_OFFSET; - pgd += PHYS_OFFSET; + pgd += phys_offset; pgd |= 1; setup_pgd(pgd, kernel); } @@ -29,7 +29,7 @@ static inline void tlbmiss_handler_setup_pgd(unsigned long pgd, bool kernel) static inline unsigned long tlb_get_pgd(void) { - return ((get_pgd() - PHYS_OFFSET) & ~1) + PAGE_OFFSET; + return ((get_pgd() - phys_offset) & ~1) + PAGE_OFFSET; } #define cpu_context(cpu, mm) ((mm)->context.asid[cpu]) diff --git a/arch/csky/include/asm/page.h b/arch/csky/include/asm/page.h index 73cf2bd66a13..4ce3d5c28ffc 100644 --- a/arch/csky/include/asm/page.h +++ b/arch/csky/include/asm/page.h @@ -8,7 +8,7 @@ #include /* - * PAGE_SHIFT determines the page size + * PAGE_SHIFT determines the page size: 4KB */ #define PAGE_SHIFT 12 #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) @@ -17,12 +17,18 @@ #define THREAD_MASK (~(THREAD_SIZE - 1)) #define THREAD_SHIFT (PAGE_SHIFT + 1) + /* - * NOTE: virtual isn't really correct, actually it should be the offset into the - * memory node, but we have no highmem, so that works for now. - * TODO: implement (fast) pfn<->pgdat_idx conversion functions, this makes lots - * of the shifts unnecessary. + * For C-SKY "User-space:Kernel-space" is "2GB:2GB" fixed by hardware and there + * are two segment registers (MSA0 + MSA1) to mapping 512MB + 512MB physical + * address region. We use them mapping kernel 1GB direct-map address area and + * for more than 1GB of memory we use highmem. */ +#define PAGE_OFFSET 0x80000000 +#define SSEG_SIZE 0x20000000 +#define LOWMEM_LIMIT (SSEG_SIZE * 2) + +#define PHYS_OFFSET_OFFSET (CONFIG_RAM_BASE & (SSEG_SIZE - 1)) #ifndef __ASSEMBLY__ @@ -50,9 +56,6 @@ struct page; struct vm_area_struct; -/* - * These are used to make use of C type-checking.. - */ typedef struct { unsigned long pte_low; } pte_t; #define pte_val(x) ((x).pte_low) @@ -69,18 +72,13 @@ typedef struct page *pgtable_t; #define __pgd(x) ((pgd_t) { (x) }) #define __pgprot(x) ((pgprot_t) { (x) }) -#endif /* !__ASSEMBLY__ */ - -#define PHYS_OFFSET (CONFIG_RAM_BASE & ~(LOWMEM_LIMIT - 1)) -#define PHYS_OFFSET_OFFSET (CONFIG_RAM_BASE & (LOWMEM_LIMIT - 1)) -#define ARCH_PFN_OFFSET PFN_DOWN(CONFIG_RAM_BASE) +extern unsigned long phys_offset; -#define PAGE_OFFSET 0x80000000 -#define LOWMEM_LIMIT 0x40000000 +#define ARCH_PFN_OFFSET PFN_DOWN(phys_offset + PHYS_OFFSET_OFFSET) -#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET) +#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + phys_offset) #define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - \ - PHYS_OFFSET)) + phys_offset)) #define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0)) #define MAP_NR(x) PFN_DOWN((unsigned long)(x) - PAGE_OFFSET - \ @@ -90,15 +88,10 @@ typedef struct page *pgtable_t; #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) -/* - * main RAM and kernel working space are coincident at 0x80000000, but to make - * life more interesting, there's also an uncached virtual shadow at 0xb0000000 - * - these mappings are fixed in the MMU - */ - #define pfn_to_kaddr(x) __va(PFN_PHYS(x)) #include #include +#endif /* !__ASSEMBLY__ */ #endif /* __ASM_CSKY_PAGE_H */ diff --git a/arch/csky/kernel/entry.S b/arch/csky/kernel/entry.S index c0f80736dac6..e5bbd8c184f3 100644 --- a/arch/csky/kernel/entry.S +++ b/arch/csky/kernel/entry.S @@ -40,7 +40,8 @@ ENTRY(csky_\name) WR_MCIR a2 #endif bclri r6, 0 - lrw a2, PHYS_OFFSET + lrw a2, phys_offset + ld.w a2, (a2, 0) subu r6, a2 bseti r6, 31 @@ -50,7 +51,8 @@ ENTRY(csky_\name) addu r6, a2 ldw r6, (r6) - lrw a2, PHYS_OFFSET + lrw a2, phys_offset + ld.w a2, (a2, 0) subu r6, a2 bseti r6, 31 diff --git a/arch/csky/kernel/setup.c b/arch/csky/kernel/setup.c index dff8b89444ec..c377194e4b8f 100644 --- a/arch/csky/kernel/setup.c +++ b/arch/csky/kernel/setup.c @@ -142,11 +142,16 @@ void __init setup_arch(char **cmdline_p) #endif } +unsigned long phys_offset; +EXPORT_SYMBOL(phys_offset); + asmlinkage __visible void __init csky_start(unsigned int unused, void *param) { /* Clean up bss section */ memset(__bss_start, 0, __bss_stop - __bss_start); + phys_offset = read_mmu_msa0() & ~(SSEG_SIZE - 1); + pre_trap_init(); pre_mmu_init(); -- cgit v1.2.3 From b4bf274198bd415e66af0b54a2e181c59fd43ba4 Mon Sep 17 00:00:00 2001 From: Mao Han Date: Wed, 10 Apr 2019 10:27:10 +0800 Subject: csky: Add perf_arch_fetch_caller_regs support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In trace events as tracepoints context are not able to be retrieve with task_pt_regs. Without arch caller regs support the pt_regs context will be all zero, perf can not parsing the callchain and resolving the symbols correctly, some time will even get into deadlock while handling the page fault, eg: perf kmem —page record ls Changelog - Add test case cmd in comment - Use regs_fp(regs) which is defined in abi/regdef.h Signed-off-by: Mao Han Signed-off-by: Guo Ren --- arch/csky/abiv1/inc/abi/regdef.h | 1 + arch/csky/abiv2/inc/abi/regdef.h | 1 + arch/csky/include/asm/perf_event.h | 8 ++++++++ 3 files changed, 10 insertions(+) (limited to 'arch/csky/include') diff --git a/arch/csky/abiv1/inc/abi/regdef.h b/arch/csky/abiv1/inc/abi/regdef.h index 729b1c3edcfd..104707fbdcc1 100644 --- a/arch/csky/abiv1/inc/abi/regdef.h +++ b/arch/csky/abiv1/inc/abi/regdef.h @@ -6,6 +6,7 @@ #define syscallid r1 #define regs_syscallid(regs) regs->regs[9] +#define regs_fp(regs) regs->regs[2] /* * PSR format: diff --git a/arch/csky/abiv2/inc/abi/regdef.h b/arch/csky/abiv2/inc/abi/regdef.h index 77cb1788b04c..d7328bbc1ce7 100644 --- a/arch/csky/abiv2/inc/abi/regdef.h +++ b/arch/csky/abiv2/inc/abi/regdef.h @@ -6,6 +6,7 @@ #define syscallid r7 #define regs_syscallid(regs) regs->regs[3] +#define regs_fp(regs) regs->regs[4] /* * PSR format: diff --git a/arch/csky/include/asm/perf_event.h b/arch/csky/include/asm/perf_event.h index ea8193122294..572093e11001 100644 --- a/arch/csky/include/asm/perf_event.h +++ b/arch/csky/include/asm/perf_event.h @@ -4,4 +4,12 @@ #ifndef __ASM_CSKY_PERF_EVENT_H #define __ASM_CSKY_PERF_EVENT_H +#include + +#define perf_arch_fetch_caller_regs(regs, __ip) { \ + (regs)->pc = (__ip); \ + regs_fp(regs) = (unsigned long) __builtin_frame_address(0); \ + asm volatile("mov %0, sp\n":"=r"((regs)->usp)); \ +} + #endif /* __ASM_PERF_EVENT_ELF_H */ -- cgit v1.2.3 From 683fafebf93bcde9948246849348b888e185cb22 Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Fri, 19 Apr 2019 17:10:52 +0800 Subject: csky: Use va_pa_offset instead of phys_offset The name of phys_offset is so common for global export and it may conflict with some local name. So change phys_offset to va_pa_offset which also used by riscv. Also use __pa() and __va() instead of using phys_offset directly. Signed-off-by: Guo Ren Cc: Arnd Bergmann --- arch/csky/abiv1/inc/abi/ckmmu.h | 4 ++-- arch/csky/abiv2/inc/abi/ckmmu.h | 14 ++++++-------- arch/csky/include/asm/mmu_context.h | 17 ++--------------- arch/csky/include/asm/page.h | 10 +++++----- arch/csky/kernel/entry.S | 4 ++-- arch/csky/kernel/setup.c | 6 +++--- arch/csky/mm/fault.c | 2 +- 7 files changed, 21 insertions(+), 36 deletions(-) (limited to 'arch/csky/include') diff --git a/arch/csky/abiv1/inc/abi/ckmmu.h b/arch/csky/abiv1/inc/abi/ckmmu.h index 85339bd224c4..81f37715c0d2 100644 --- a/arch/csky/abiv1/inc/abi/ckmmu.h +++ b/arch/csky/abiv1/inc/abi/ckmmu.h @@ -85,11 +85,11 @@ static inline void tlb_invalid_indexed(void) static inline void setup_pgd(unsigned long pgd, bool kernel) { - cpwcr("cpcr29", pgd); + cpwcr("cpcr29", pgd | BIT(0)); } static inline unsigned long get_pgd(void) { - return cprcr("cpcr29"); + return cprcr("cpcr29") & ~BIT(0); } #endif /* __ASM_CSKY_CKMMUV1_H */ diff --git a/arch/csky/abiv2/inc/abi/ckmmu.h b/arch/csky/abiv2/inc/abi/ckmmu.h index 31d75e1a724a..e4480e6bc3b3 100644 --- a/arch/csky/abiv2/inc/abi/ckmmu.h +++ b/arch/csky/abiv2/inc/abi/ckmmu.h @@ -90,18 +90,16 @@ static inline void tlb_invalid_indexed(void) mtcr("cr<8, 15>", 0x02000000); } -/* setup hardrefil pgd */ -static inline unsigned long get_pgd(void) -{ - return mfcr("cr<29, 15>"); -} - static inline void setup_pgd(unsigned long pgd, bool kernel) { if (kernel) - mtcr("cr<28, 15>", pgd); + mtcr("cr<28, 15>", pgd | BIT(0)); else - mtcr("cr<29, 15>", pgd); + mtcr("cr<29, 15>", pgd | BIT(0)); } +static inline unsigned long get_pgd(void) +{ + return mfcr("cr<29, 15>") & ~BIT(0); +} #endif /* __ASM_CSKY_CKMMUV2_H */ diff --git a/arch/csky/include/asm/mmu_context.h b/arch/csky/include/asm/mmu_context.h index c41f86b22460..734db3a122e1 100644 --- a/arch/csky/include/asm/mmu_context.h +++ b/arch/csky/include/asm/mmu_context.h @@ -14,23 +14,10 @@ #include #include -static inline void tlbmiss_handler_setup_pgd(unsigned long pgd, bool kernel) -{ - pgd -= PAGE_OFFSET; - pgd += phys_offset; - pgd |= 1; - setup_pgd(pgd, kernel); -} - #define TLBMISS_HANDLER_SETUP_PGD(pgd) \ - tlbmiss_handler_setup_pgd((unsigned long)pgd, 0) + setup_pgd(__pa(pgd), false) #define TLBMISS_HANDLER_SETUP_PGD_KERNEL(pgd) \ - tlbmiss_handler_setup_pgd((unsigned long)pgd, 1) - -static inline unsigned long tlb_get_pgd(void) -{ - return ((get_pgd() - phys_offset) & ~1) + PAGE_OFFSET; -} + setup_pgd(__pa(pgd), true) #define cpu_context(cpu, mm) ((mm)->context.asid[cpu]) #define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK) diff --git a/arch/csky/include/asm/page.h b/arch/csky/include/asm/page.h index 4ce3d5c28ffc..9738eacefdc7 100644 --- a/arch/csky/include/asm/page.h +++ b/arch/csky/include/asm/page.h @@ -72,13 +72,13 @@ typedef struct page *pgtable_t; #define __pgd(x) ((pgd_t) { (x) }) #define __pgprot(x) ((pgprot_t) { (x) }) -extern unsigned long phys_offset; +extern unsigned long va_pa_offset; -#define ARCH_PFN_OFFSET PFN_DOWN(phys_offset + PHYS_OFFSET_OFFSET) +#define ARCH_PFN_OFFSET PFN_DOWN(va_pa_offset + PHYS_OFFSET_OFFSET) + +#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + va_pa_offset) +#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - va_pa_offset)) -#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + phys_offset) -#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - \ - phys_offset)) #define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0)) #define MAP_NR(x) PFN_DOWN((unsigned long)(x) - PAGE_OFFSET - \ diff --git a/arch/csky/kernel/entry.S b/arch/csky/kernel/entry.S index e5bbd8c184f3..a7e84ccccbd8 100644 --- a/arch/csky/kernel/entry.S +++ b/arch/csky/kernel/entry.S @@ -40,7 +40,7 @@ ENTRY(csky_\name) WR_MCIR a2 #endif bclri r6, 0 - lrw a2, phys_offset + lrw a2, va_pa_offset ld.w a2, (a2, 0) subu r6, a2 bseti r6, 31 @@ -51,7 +51,7 @@ ENTRY(csky_\name) addu r6, a2 ldw r6, (r6) - lrw a2, phys_offset + lrw a2, va_pa_offset ld.w a2, (a2, 0) subu r6, a2 bseti r6, 31 diff --git a/arch/csky/kernel/setup.c b/arch/csky/kernel/setup.c index 36fc04b9417d..23ee604aafdb 100644 --- a/arch/csky/kernel/setup.c +++ b/arch/csky/kernel/setup.c @@ -142,8 +142,8 @@ void __init setup_arch(char **cmdline_p) #endif } -unsigned long phys_offset; -EXPORT_SYMBOL(phys_offset); +unsigned long va_pa_offset; +EXPORT_SYMBOL(va_pa_offset); asmlinkage __visible void __init csky_start(unsigned int unused, void *dtb_start) @@ -151,7 +151,7 @@ asmlinkage __visible void __init csky_start(unsigned int unused, /* Clean up bss section */ memset(__bss_start, 0, __bss_stop - __bss_start); - phys_offset = read_mmu_msa0() & ~(SSEG_SIZE - 1); + va_pa_offset = read_mmu_msa0() & ~(SSEG_SIZE - 1); pre_trap_init(); pre_mmu_init(); diff --git a/arch/csky/mm/fault.c b/arch/csky/mm/fault.c index e1725f8a06f9..5beb25ca1c79 100644 --- a/arch/csky/mm/fault.c +++ b/arch/csky/mm/fault.c @@ -81,7 +81,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, unsigned long pgd_base; - pgd_base = tlb_get_pgd(); + pgd_base = __va(get_pgd()); pgd = (pgd_t *)pgd_base + offset; pgd_k = init_mm.pgd + offset; -- cgit v1.2.3 From daac95e70f482e7add3305ee5e38f00dca505268 Mon Sep 17 00:00:00 2001 From: Mao Han Date: Mon, 15 Apr 2019 17:17:29 +0800 Subject: csky: Add support for perf registers sampling This patch implements the perf registers sampling and validation API for csky arch. The valid registers and their register ID are defined in perf_regs.h. Perf tool can backtrace in userspace with unwind library and the registers/user stack dump support. Signed-off-by: Mao Han Signed-off-by: Guo Ren --- arch/csky/Kconfig | 2 ++ arch/csky/include/uapi/asm/perf_regs.h | 51 ++++++++++++++++++++++++++++++++++ arch/csky/kernel/Makefile | 1 + arch/csky/kernel/perf_regs.c | 40 ++++++++++++++++++++++++++ 4 files changed, 94 insertions(+) create mode 100644 arch/csky/include/uapi/asm/perf_regs.h create mode 100644 arch/csky/kernel/perf_regs.c (limited to 'arch/csky/include') diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig index c4974cf6a222..8e45c7ac8e24 100644 --- a/arch/csky/Kconfig +++ b/arch/csky/Kconfig @@ -38,6 +38,8 @@ config CSKY select HAVE_KERNEL_LZO select HAVE_KERNEL_LZMA select HAVE_PERF_EVENTS + select HAVE_PERF_REGS + select HAVE_PERF_USER_STACK_DUMP select HAVE_DMA_API_DEBUG select HAVE_DMA_CONTIGUOUS select HAVE_SYSCALL_TRACEPOINTS diff --git a/arch/csky/include/uapi/asm/perf_regs.h b/arch/csky/include/uapi/asm/perf_regs.h new file mode 100644 index 000000000000..ee323d818592 --- /dev/null +++ b/arch/csky/include/uapi/asm/perf_regs.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef _ASM_CSKY_PERF_REGS_H +#define _ASM_CSKY_PERF_REGS_H + +/* Index of struct pt_regs */ +enum perf_event_csky_regs { + PERF_REG_CSKY_TLS, + PERF_REG_CSKY_LR, + PERF_REG_CSKY_PC, + PERF_REG_CSKY_SR, + PERF_REG_CSKY_SP, + PERF_REG_CSKY_ORIG_A0, + PERF_REG_CSKY_A0, + PERF_REG_CSKY_A1, + PERF_REG_CSKY_A2, + PERF_REG_CSKY_A3, + PERF_REG_CSKY_REGS0, + PERF_REG_CSKY_REGS1, + PERF_REG_CSKY_REGS2, + PERF_REG_CSKY_REGS3, + PERF_REG_CSKY_REGS4, + PERF_REG_CSKY_REGS5, + PERF_REG_CSKY_REGS6, + PERF_REG_CSKY_REGS7, + PERF_REG_CSKY_REGS8, + PERF_REG_CSKY_REGS9, +#if defined(__CSKYABIV2__) + PERF_REG_CSKY_EXREGS0, + PERF_REG_CSKY_EXREGS1, + PERF_REG_CSKY_EXREGS2, + PERF_REG_CSKY_EXREGS3, + PERF_REG_CSKY_EXREGS4, + PERF_REG_CSKY_EXREGS5, + PERF_REG_CSKY_EXREGS6, + PERF_REG_CSKY_EXREGS7, + PERF_REG_CSKY_EXREGS8, + PERF_REG_CSKY_EXREGS9, + PERF_REG_CSKY_EXREGS10, + PERF_REG_CSKY_EXREGS11, + PERF_REG_CSKY_EXREGS12, + PERF_REG_CSKY_EXREGS13, + PERF_REG_CSKY_EXREGS14, + PERF_REG_CSKY_HI, + PERF_REG_CSKY_LO, + PERF_REG_CSKY_DCSR, +#endif + PERF_REG_CSKY_MAX, +}; +#endif /* _ASM_CSKY_PERF_REGS_H */ diff --git a/arch/csky/kernel/Makefile b/arch/csky/kernel/Makefile index 4c462f584dd1..1624b04bffb5 100644 --- a/arch/csky/kernel/Makefile +++ b/arch/csky/kernel/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_CSKY_PMU_V1) += perf_event.o obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o +obj-$(CONFIG_HAVE_PERF_REGS) += perf_regs.o ifdef CONFIG_FUNCTION_TRACER CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE) diff --git a/arch/csky/kernel/perf_regs.c b/arch/csky/kernel/perf_regs.c new file mode 100644 index 000000000000..eb32838b8210 --- /dev/null +++ b/arch/csky/kernel/perf_regs.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. + +#include +#include +#include +#include +#include +#include + +u64 perf_reg_value(struct pt_regs *regs, int idx) +{ + if (WARN_ON_ONCE((u32)idx >= PERF_REG_CSKY_MAX)) + return 0; + + return (u64)*((u32 *)regs + idx); +} + +#define REG_RESERVED (~((1ULL << PERF_REG_CSKY_MAX) - 1)) + +int perf_reg_validate(u64 mask) +{ + if (!mask || mask & REG_RESERVED) + return -EINVAL; + + return 0; +} + +u64 perf_reg_abi(struct task_struct *task) +{ + return PERF_SAMPLE_REGS_ABI_32; +} + +void perf_get_regs_user(struct perf_regs *regs_user, + struct pt_regs *regs, + struct pt_regs *regs_user_copy) +{ + regs_user->regs = task_pt_regs(current); + regs_user->abi = perf_reg_abi(current); +} -- cgit v1.2.3 From a691f3334d58b833e41d56de1b9820e687edcd78 Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Mon, 22 Apr 2019 14:46:44 +0800 Subject: csky/syscall_trace: Fixup return processing flow The function tracehook_report_syscall_entry's return value is __must_check attribute. We should add return processing flow in ptrace.c and set the syscall number to -1 when failed just like riscv's. Signed-off-by: Guo Ren Cc: Arnd Bergmann --- arch/csky/include/asm/syscall.h | 7 +++++++ arch/csky/kernel/ptrace.c | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'arch/csky/include') diff --git a/arch/csky/include/asm/syscall.h b/arch/csky/include/asm/syscall.h index 850b694a463e..8278658e74f9 100644 --- a/arch/csky/include/asm/syscall.h +++ b/arch/csky/include/asm/syscall.h @@ -16,6 +16,13 @@ syscall_get_nr(struct task_struct *task, struct pt_regs *regs) return regs_syscallid(regs); } +static inline void +syscall_set_nr(struct task_struct *task, struct pt_regs *regs, + int sysno) +{ + regs_syscallid(regs) = sysno; +} + static inline void syscall_rollback(struct task_struct *task, struct pt_regs *regs) { diff --git a/arch/csky/kernel/ptrace.c b/arch/csky/kernel/ptrace.c index 91bc74bb569f..313623a19ecb 100644 --- a/arch/csky/kernel/ptrace.c +++ b/arch/csky/kernel/ptrace.c @@ -215,7 +215,8 @@ long arch_ptrace(struct task_struct *child, long request, asmlinkage void syscall_trace_enter(struct pt_regs *regs) { if (test_thread_flag(TIF_SYSCALL_TRACE)) - tracehook_report_syscall_entry(regs); + if (tracehook_report_syscall_entry(regs)) + syscall_set_nr(current, regs, -1); if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) trace_sys_enter(regs, syscall_get_nr(current, regs)); -- cgit v1.2.3