From c23dd2405fc2054345be33f8bb1d04b3b805202d Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 10 Jun 2020 17:39:35 +0200 Subject: csky: remove unusued thread_saved_pc and *_segments functions/macros These are used nowhere in the tree (except for some architectures which define them for their own use) and were already removed for other architectures in: commit 6474924e2b5d ("arch: remove unused macro/function thread_saved_pc()") commit c17c02040bf0 ("arch: remove unused *_segments() macros/functions") Remove them from arch/csky as well. Signed-off-by: Tobias Klauser Signed-off-by: Guo Ren Cc: Arnd Bergmann --- arch/csky/include/asm/processor.h | 6 ------ arch/csky/kernel/process.c | 10 ---------- 2 files changed, 16 deletions(-) diff --git a/arch/csky/include/asm/processor.h b/arch/csky/include/asm/processor.h index 24442d8e86f9..4800f6563abb 100644 --- a/arch/csky/include/asm/processor.h +++ b/arch/csky/include/asm/processor.h @@ -82,12 +82,6 @@ static inline void release_thread(struct task_struct *dead_task) extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); -#define copy_segments(tsk, mm) do { } while (0) -#define release_segments(mm) do { } while (0) -#define forget_segments() do { } while (0) - -extern unsigned long thread_saved_pc(struct task_struct *tsk); - unsigned long get_wchan(struct task_struct *p); #define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc) diff --git a/arch/csky/kernel/process.c b/arch/csky/kernel/process.c index 8b3fad062ab2..3da63cf0bfde 100644 --- a/arch/csky/kernel/process.c +++ b/arch/csky/kernel/process.c @@ -30,16 +30,6 @@ asmlinkage void ret_from_kernel_thread(void); */ void flush_thread(void){} -/* - * Return saved PC from a blocked thread - */ -unsigned long thread_saved_pc(struct task_struct *tsk) -{ - struct switch_stack *sw = (struct switch_stack *)tsk->thread.sp; - - return sw->r15; -} - int copy_thread_tls(unsigned long clone_flags, unsigned long usp, unsigned long kthread_arg, -- cgit v1.2.3 From e95a4f8cb985e759648b32ed0b721a472deb86a5 Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Tue, 26 May 2020 08:11:52 +0000 Subject: csky: Add SECCOMP_FILTER supported secure_computing() is called first in syscall_trace_enter() so that a system call will be aborted quickly without doing succeeding syscall tracing if seccomp rules want to deny that system call. TODO: - Update https://github.com/seccomp/libseccomp csky support Signed-off-by: Guo Ren Cc: Arnd Bergmann --- arch/csky/Kconfig | 14 ++++++++++++++ arch/csky/include/asm/Kbuild | 1 + arch/csky/include/asm/thread_info.h | 2 +- arch/csky/kernel/entry.S | 3 +++ arch/csky/kernel/ptrace.c | 8 ++++++-- tools/testing/selftests/seccomp/seccomp_bpf.c | 13 ++++++++++++- 6 files changed, 37 insertions(+), 4 deletions(-) diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig index bd31ab12f77d..822362d0598e 100644 --- a/arch/csky/Kconfig +++ b/arch/csky/Kconfig @@ -38,6 +38,7 @@ config CSKY select GX6605S_TIMER if CPU_CK610 select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_AUDITSYSCALL + select HAVE_ARCH_SECCOMP_FILTER select HAVE_COPY_THREAD_TLS select HAVE_DEBUG_BUGVERBOSE select HAVE_DYNAMIC_FTRACE @@ -296,3 +297,16 @@ endmenu source "arch/csky/Kconfig.platforms" source "kernel/Kconfig.hz" + +config SECCOMP + bool "Enable seccomp to safely compute untrusted bytecode" + help + This kernel feature is useful for number crunching applications + that may need to compute untrusted bytecode during their + execution. By using pipes or other transports made available to + the process as file descriptors supporting the read/write + syscalls, it's possible to isolate those applications in + their own address space using seccomp. Once seccomp is + enabled via prctl(PR_SET_SECCOMP), it cannot be disabled + and the task is only allowed to execute a few safe syscalls + defined by each seccomp mode. diff --git a/arch/csky/include/asm/Kbuild b/arch/csky/include/asm/Kbuild index 93372255984d..64876e59e2ef 100644 --- a/arch/csky/include/asm/Kbuild +++ b/arch/csky/include/asm/Kbuild @@ -4,5 +4,6 @@ generic-y += gpio.h generic-y += kvm_para.h generic-y += local64.h generic-y += qrwlock.h +generic-y += seccomp.h generic-y += user.h generic-y += vmlinux.lds.h diff --git a/arch/csky/include/asm/thread_info.h b/arch/csky/include/asm/thread_info.h index 8980e4e64391..68e7a1227170 100644 --- a/arch/csky/include/asm/thread_info.h +++ b/arch/csky/include/asm/thread_info.h @@ -85,6 +85,6 @@ static inline struct thread_info *current_thread_info(void) _TIF_NOTIFY_RESUME | _TIF_UPROBE) #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ - _TIF_SYSCALL_TRACEPOINT) + _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP) #endif /* _ASM_CSKY_THREAD_INFO_H */ diff --git a/arch/csky/kernel/entry.S b/arch/csky/kernel/entry.S index f13800383a19..efd2e696e3cd 100644 --- a/arch/csky/kernel/entry.S +++ b/arch/csky/kernel/entry.S @@ -168,6 +168,8 @@ ENTRY(csky_systemcall) csky_syscall_trace: mov a0, sp /* sp = pt_regs pointer */ jbsr syscall_trace_enter + cmpnei a0, 0 + bt 1f /* Prepare args before do system call */ ldw a0, (sp, LSAVE_A0) ldw a1, (sp, LSAVE_A1) @@ -188,6 +190,7 @@ csky_syscall_trace: #endif stw a0, (sp, LSAVE_A0) /* Save return value */ +1: #ifdef CONFIG_DEBUG_RSEQ mov a0, sp jbsr rseq_syscall diff --git a/arch/csky/kernel/ptrace.c b/arch/csky/kernel/ptrace.c index 944ca2fdcdd9..0de10f7beae6 100644 --- a/arch/csky/kernel/ptrace.c +++ b/arch/csky/kernel/ptrace.c @@ -320,16 +320,20 @@ long arch_ptrace(struct task_struct *child, long request, return ret; } -asmlinkage void syscall_trace_enter(struct pt_regs *regs) +asmlinkage int syscall_trace_enter(struct pt_regs *regs) { if (test_thread_flag(TIF_SYSCALL_TRACE)) if (tracehook_report_syscall_entry(regs)) - syscall_set_nr(current, regs, -1); + return -1; + + if (secure_computing() == -1) + return -1; 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); + return 0; } asmlinkage void syscall_trace_exit(struct pt_regs *regs) diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 252140a52553..8d18a0ddafdd 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -116,6 +116,8 @@ struct seccomp_data { # define __NR_seccomp 277 # elif defined(__riscv) # define __NR_seccomp 277 +# elif defined(__csky__) +# define __NR_seccomp 277 # elif defined(__hppa__) # define __NR_seccomp 338 # elif defined(__powerpc__) @@ -1603,6 +1605,14 @@ TEST_F(TRACE_poke, getpid_runs_normally) # define ARCH_REGS struct user_regs_struct # define SYSCALL_NUM a7 # define SYSCALL_RET a0 +#elif defined(__csky__) +# define ARCH_REGS struct pt_regs +#if defined(__CSKYABIV2__) +# define SYSCALL_NUM regs[3] +#else +# define SYSCALL_NUM regs[9] +#endif +# define SYSCALL_RET a0 #elif defined(__hppa__) # define ARCH_REGS struct user_regs_struct # define SYSCALL_NUM gr[20] @@ -1693,7 +1703,8 @@ void change_syscall(struct __test_metadata *_metadata, EXPECT_EQ(0, ret) {} #if defined(__x86_64__) || defined(__i386__) || defined(__powerpc__) || \ - defined(__s390__) || defined(__hppa__) || defined(__riscv) + defined(__s390__) || defined(__hppa__) || defined(__riscv) || \ + defined(__csky__) { regs.SYSCALL_NUM = syscall; } -- cgit v1.2.3 From 8077e66bc381988d0ef6f60d2eb71d8812b26333 Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Tue, 28 Jul 2020 10:44:57 +0000 Subject: csky: Add cpu feature register hint for smp CPU features registers are setup by customers' bootloader, but Linux must help transfer them from the primary to secondary cores. This patch add hint2 CPU feature register supported. Signed-off-by: Guo Ren Cc: Arnd Bergmann --- arch/csky/kernel/smp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/csky/kernel/smp.c b/arch/csky/kernel/smp.c index b5c5bc3afeb5..1945fb29007d 100644 --- a/arch/csky/kernel/smp.c +++ b/arch/csky/kernel/smp.c @@ -156,6 +156,7 @@ void __init setup_smp(void) extern void _start_smp_secondary(void); volatile unsigned int secondary_hint; +volatile unsigned int secondary_hint2; volatile unsigned int secondary_ccr; volatile unsigned int secondary_stack; @@ -168,6 +169,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle) secondary_stack = (unsigned int) task_stack_page(tidle) + THREAD_SIZE - 8; secondary_hint = mfcr("cr31"); + secondary_hint2 = mfcr("cr<21, 1>"); secondary_ccr = mfcr("cr18"); secondary_msa1 = read_mmu_msa1(); @@ -209,6 +211,7 @@ void csky_start_secondary(void) unsigned int cpu = smp_processor_id(); mtcr("cr31", secondary_hint); + mtcr("cr<21, 1>", secondary_hint2); mtcr("cr18", secondary_ccr); mtcr("vbr", vec_base); -- cgit v1.2.3 From f788bb2fb915a79eae0a160580766ba52984d61f Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Tue, 28 Jul 2020 16:18:54 +0000 Subject: csky: Fixup duplicated restore sp in RESTORE_REGS_FTRACE There is no user return for RESTORE_REGS_FTRACE, so it's no need to save sp into ss0 as RESTORE_REGS_ALL. Signed-off-by: Guo Ren Cc: Arnd Bergmann --- arch/csky/abiv2/inc/abi/entry.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/csky/abiv2/inc/abi/entry.h b/arch/csky/abiv2/inc/abi/entry.h index 4fdd6c12e7ff..bedcc6f06bba 100644 --- a/arch/csky/abiv2/inc/abi/entry.h +++ b/arch/csky/abiv2/inc/abi/entry.h @@ -136,8 +136,6 @@ .macro RESTORE_REGS_FTRACE ldw tls, (sp, 0) - ldw a0, (sp, 16) - mtcr a0, ss0 #ifdef CONFIG_CPU_HAS_HILO ldw a0, (sp, 140) @@ -158,7 +156,6 @@ addi sp, 40 ldm r16-r30, (sp) addi sp, 72 - mfcr sp, ss0 .endm .macro SAVE_SWITCH_STACK -- cgit v1.2.3 From a5447fb9b32eb33b2f0f09a63e4852b46af5b056 Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Tue, 28 Jul 2020 16:25:23 +0000 Subject: csky: Fixup kprobes handler couldn't change pc The "Changing Execution Path" section in the Documentation/kprobes.txt said: Since kprobes can probe into a running kernel code, it can change the register set, including instruction pointer. Signed-off-by: Guo Ren Cc: Arnd Bergmann --- arch/csky/abiv2/mcount.S | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/csky/abiv2/mcount.S b/arch/csky/abiv2/mcount.S index 911512bf480f..d745e10c10b0 100644 --- a/arch/csky/abiv2/mcount.S +++ b/arch/csky/abiv2/mcount.S @@ -55,7 +55,9 @@ .macro mcount_exit_regs RESTORE_REGS_FTRACE - ldw t1, (sp, 0) + subi sp, 152 + ldw t1, (sp, 4) + addi sp, 152 ldw r8, (sp, 4) ldw lr, (sp, 8) addi sp, 12 -- cgit v1.2.3 From 71e193d7cbcfc988c3802e15261bd807171adb6b Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Tue, 28 Jul 2020 16:30:46 +0000 Subject: csky: Add support for function error injection Inspired by the commit 42d038c4fb00 ("arm64: Add support for function error injection"), this patch supports function error injection for csky. This patch mainly support two functions: one is regs_set_return_value() which is used to overwrite the return value; the another function is override_function_with_return() which is to override the probed function returning and jump to its caller. Test log: cd /sys/kernel/debug/fail_function/ echo sys_clone > inject echo 100 > probability echo 1 > interval ls / [ 108.644163] FAULT_INJECTION: forcing a failure. [ 108.644163] name fail_function, interval 1, probability 100, space 0, times 1 [ 108.647799] CPU: 0 PID: 104 Comm: sh Not tainted 5.8.0-rc5+ #46 [ 108.648384] Call Trace: [ 108.649339] [<8005eed4>] walk_stackframe+0x0/0xf0 [ 108.649679] [<8005f16a>] show_stack+0x32/0x5c [ 108.649927] [<8040f9d2>] dump_stack+0x6e/0x9c [ 108.650271] [<80406f7e>] should_fail+0x15e/0x1ac [ 108.650720] [<80118ba8>] fei_kprobe_handler+0x28/0x5c [ 108.651519] [<80754110>] kprobe_breakpoint_handler+0x144/0x1cc [ 108.652289] [<8005d6da>] trap_c+0x8e/0x110 [ 108.652816] [<8005ce8c>] csky_trap+0x5c/0x70 -sh: can't fork: Invalid argument Signed-off-by: Guo Ren Cc: Arnd Bergmann --- arch/csky/Kconfig | 1 + arch/csky/include/asm/ptrace.h | 6 ++++++ arch/csky/lib/Makefile | 1 + arch/csky/lib/error-inject.c | 10 ++++++++++ 4 files changed, 18 insertions(+) create mode 100644 arch/csky/lib/error-inject.c diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig index 822362d0598e..c51f64c14391 100644 --- a/arch/csky/Kconfig +++ b/arch/csky/Kconfig @@ -45,6 +45,7 @@ config CSKY select HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_GRAPH_TRACER + select HAVE_FUNCTION_ERROR_INJECTION select HAVE_FTRACE_MCOUNT_RECORD select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZO diff --git a/arch/csky/include/asm/ptrace.h b/arch/csky/include/asm/ptrace.h index bcfb7070e48d..82da5e08558d 100644 --- a/arch/csky/include/asm/ptrace.h +++ b/arch/csky/include/asm/ptrace.h @@ -52,6 +52,12 @@ static inline unsigned long regs_return_value(struct pt_regs *regs) return regs->a0; } +static inline void regs_set_return_value(struct pt_regs *regs, + unsigned long val) +{ + regs->a0 = val; +} + /* Valid only for Kernel mode traps. */ static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) { diff --git a/arch/csky/lib/Makefile b/arch/csky/lib/Makefile index 078e2d5f32e1..7fbdbb2c4d12 100644 --- a/arch/csky/lib/Makefile +++ b/arch/csky/lib/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only lib-y := usercopy.o delay.o +obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o diff --git a/arch/csky/lib/error-inject.c b/arch/csky/lib/error-inject.c new file mode 100644 index 000000000000..c15fb36fe067 --- /dev/null +++ b/arch/csky/lib/error-inject.c @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include + +void override_function_with_return(struct pt_regs *regs) +{ + instruction_pointer_set(regs, regs->lr); +} +NOKPROBE_SYMBOL(override_function_with_return); -- cgit v1.2.3 From 5bc46ce26cfc42fa066b2206621587f9dea9a8a8 Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Thu, 30 Jul 2020 11:09:51 +0000 Subject: csky: Optimize the trap processing flow - Seperate different trap functions - Add trap_no() - Remove panic code print - Redesign die_if_kerenl to die with riscv's - Print exact trap info for app segment fault [ 17.389321] gzip[126]: unhandled signal 11 code 0x3 at 0x0007835a in busybox[8000+d4000] [ 17.393882] [ 17.393882] CURRENT PROCESS: [ 17.393882] [ 17.394309] COMM=gzip PID=126 [ 17.394513] TEXT=00008000-000db2e4 DATA=000dcf14-000dd1ad BSS=000dd1ad-000ff000 [ 17.395499] USER-STACK=7f888e50 KERNEL-STACK=bf130300 [ 17.395499] [ 17.396801] PC: 0x0007835a (0x7835a) [ 17.397048] LR: 0x000058b4 (0x58b4) [ 17.397285] SP: 0xbe519f68 [ 17.397555] orig_a0: 0x00002852 [ 17.397886] PSR: 0x00020341 [ 17.398356] a0: 0x00002852 a1: 0x000f2f5a a2: 0x0000d7ae a3: 0x0000005d [ 17.399289] r4: 0x000de150 r5: 0x00000002 r6: 0x00000102 r7: 0x00007efa [ 17.399800] r8: 0x7f888bc4 r9: 0x00000001 r10: 0x000002eb r11: 0x0000aac1 [ 17.400166] r12: 0x00002ef2 r13: 0x00000007 r15: 0x000058b4 [ 17.400531] r16: 0x0000004c r17: 0x00000031 r18: 0x000f5816 r19: 0x000e8068 [ 17.401006] r20: 0x000f5818 r21: 0x000e8068 r22: 0x000f5918 r23: 0x90000000 [ 17.401721] r24: 0x00000031 r25: 0x000000c8 r26: 0x00000000 r27: 0x00000000 [ 17.402199] r28: 0x2ac2a000 r29: 0x00000000 r30: 0x00000000 tls: 0x2aadbaa8 [ 17.402686] hi: 0x00120340 lo: 0x7f888bec /etc/init.ci/ntfs3g_run: line 61: 126 Segmentation fault gzip -c -9 /mnt/test.bin > /mnt/test_bin.gz Signed-off-by: Guo Ren Cc: Arnd Bergmann --- arch/csky/include/asm/bug.h | 3 +- arch/csky/include/asm/ptrace.h | 1 + arch/csky/kernel/ptrace.c | 29 +----- arch/csky/kernel/traps.c | 223 +++++++++++++++++++++++++++-------------- arch/csky/mm/fault.c | 10 +- 5 files changed, 157 insertions(+), 109 deletions(-) diff --git a/arch/csky/include/asm/bug.h b/arch/csky/include/asm/bug.h index bd7b3235bb84..33ebd16b9c78 100644 --- a/arch/csky/include/asm/bug.h +++ b/arch/csky/include/asm/bug.h @@ -20,7 +20,8 @@ do { \ struct pt_regs; -void die_if_kernel(char *str, struct pt_regs *regs, int nr); +void die(struct pt_regs *regs, const char *str); void show_regs(struct pt_regs *regs); +void show_code(struct pt_regs *regs); #endif /* __ASM_CSKY_BUG_H */ diff --git a/arch/csky/include/asm/ptrace.h b/arch/csky/include/asm/ptrace.h index 82da5e08558d..91ceb1b454c9 100644 --- a/arch/csky/include/asm/ptrace.h +++ b/arch/csky/include/asm/ptrace.h @@ -24,6 +24,7 @@ #define user_mode(regs) (!((regs)->sr & PS_S)) #define instruction_pointer(regs) ((regs)->pc) #define profile_pc(regs) instruction_pointer(regs) +#define trap_no(regs) ((regs->sr >> 16) & 0xff) static inline void instruction_pointer_set(struct pt_regs *regs, unsigned long val) diff --git a/arch/csky/kernel/ptrace.c b/arch/csky/kernel/ptrace.c index 0de10f7beae6..b06612c408c4 100644 --- a/arch/csky/kernel/ptrace.c +++ b/arch/csky/kernel/ptrace.c @@ -347,13 +347,8 @@ asmlinkage void syscall_trace_exit(struct pt_regs *regs) trace_sys_exit(regs, syscall_get_return_value(current, regs)); } -extern void show_stack(struct task_struct *task, unsigned long *stack, const char *loglvl); void show_regs(struct pt_regs *fp) { - unsigned long *sp; - unsigned char *tp; - int i; - pr_info("\nCURRENT PROCESS:\n\n"); pr_info("COMM=%s PID=%d\n", current->comm, current->pid); @@ -400,29 +395,9 @@ void show_regs(struct pt_regs *fp) fp->regs[0], fp->regs[1], fp->regs[2], fp->regs[3]); pr_info("r10: 0x%08lx r11: 0x%08lx r12: 0x%08lx r13: 0x%08lx\n", fp->regs[4], fp->regs[5], fp->regs[6], fp->regs[7]); - pr_info("r14: 0x%08lx r1: 0x%08lx r15: 0x%08lx\n", - fp->regs[8], fp->regs[9], fp->lr); + pr_info("r14: 0x%08lx r1: 0x%08lx\n", + fp->regs[8], fp->regs[9]); #endif - pr_info("\nCODE:"); - tp = ((unsigned char *) fp->pc) - 0x20; - tp += ((int)tp % 4) ? 2 : 0; - for (sp = (unsigned long *) tp, i = 0; (i < 0x40); i += 4) { - if ((i % 0x10) == 0) - pr_cont("\n%08x: ", (int) (tp + i)); - pr_cont("%08x ", (int) *sp++); - } - pr_cont("\n"); - - pr_info("\nKERNEL STACK:"); - tp = ((unsigned char *) fp) - 0x40; - for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) { - if ((i % 0x10) == 0) - pr_cont("\n%08x: ", (int) (tp + i)); - pr_cont("%08x ", (int) *sp++); - } - pr_cont("\n"); - - show_stack(NULL, (unsigned long *)fp->regs[4], KERN_INFO); return; } diff --git a/arch/csky/kernel/traps.c b/arch/csky/kernel/traps.c index fcc3a69831ad..959a917c989d 100644 --- a/arch/csky/kernel/traps.c +++ b/arch/csky/kernel/traps.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include @@ -27,6 +29,8 @@ #include #endif +int show_unhandled_signals = 1; + /* Defined in entry.S */ asmlinkage void csky_trap(void); @@ -77,117 +81,184 @@ void __init trap_init(void) #endif } -void die_if_kernel(char *str, struct pt_regs *regs, int nr) +static DEFINE_SPINLOCK(die_lock); + +void die(struct pt_regs *regs, const char *str) { - if (user_mode(regs)) - return; + static int die_counter; + int ret; + oops_enter(); + + spin_lock_irq(&die_lock); console_verbose(); - pr_err("%s: %08x\n", str, nr); + bust_spinlocks(1); + + pr_emerg("%s [#%d]\n", str, ++die_counter); + print_modules(); show_regs(regs); + show_stack(current, (unsigned long *)regs->regs[4], KERN_INFO); + + ret = notify_die(DIE_OOPS, str, regs, 0, trap_no(regs), SIGSEGV); + + bust_spinlocks(0); add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); - do_exit(SIGSEGV); + spin_unlock_irq(&die_lock); + oops_exit(); + + if (in_interrupt()) + panic("Fatal exception in interrupt"); + if (panic_on_oops) + panic("Fatal exception"); + if (ret != NOTIFY_STOP) + do_exit(SIGSEGV); } -void buserr(struct pt_regs *regs) +void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr) { -#ifdef CONFIG_CPU_CK810 - static unsigned long prev_pc; + struct task_struct *tsk = current; - if ((regs->pc == prev_pc) && prev_pc != 0) { - prev_pc = 0; - } else { - prev_pc = regs->pc; - return; + if (show_unhandled_signals && unhandled_signal(tsk, signo) + && printk_ratelimit()) { + pr_info("%s[%d]: unhandled signal %d code 0x%x at 0x%08lx", + tsk->comm, task_pid_nr(tsk), signo, code, addr); + print_vma_addr(KERN_CONT " in ", instruction_pointer(regs)); + pr_cont("\n"); + show_regs(regs); } -#endif - die_if_kernel("Kernel mode BUS error", regs, 0); + force_sig_fault(signo, code, (void __user *)addr); +} - pr_err("User mode Bus Error\n"); - show_regs(regs); +static void do_trap_error(struct pt_regs *regs, int signo, int code, + unsigned long addr, const char *str) +{ + current->thread.trap_no = trap_no(regs); - force_sig_fault(SIGSEGV, 0, (void __user *)regs->pc); + if (user_mode(regs)) { + do_trap(regs, signo, code, addr); + } else { + if (!fixup_exception(regs)) + die(regs, str); + } } -asmlinkage void trap_c(struct pt_regs *regs) -{ - int sig; - unsigned long vector; - siginfo_t info; - struct task_struct *tsk = current; +#define DO_ERROR_INFO(name, signo, code, str) \ +asmlinkage __visible void name(struct pt_regs *regs) \ +{ \ + do_trap_error(regs, signo, code, regs->pc, "Oops - " str); \ +} - vector = (regs->sr >> 16) & 0xff; +DO_ERROR_INFO(do_trap_unknown, + SIGILL, ILL_ILLTRP, "unknown exception"); +DO_ERROR_INFO(do_trap_zdiv, + SIGFPE, FPE_INTDIV, "error zero div exception"); +DO_ERROR_INFO(do_trap_buserr, + SIGSEGV, ILL_ILLADR, "error bus error exception"); - switch (vector) { - case VEC_ZERODIV: - die_if_kernel("Kernel mode ZERO DIV", regs, vector); - sig = SIGFPE; - break; - /* ptrace */ - case VEC_TRACE: +asmlinkage void do_trap_misaligned(struct pt_regs *regs) +{ +#ifdef CONFIG_CPU_NEED_SOFTALIGN + csky_alignment(regs); +#else + current->thread.trap_no = trap_no(regs); + do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->pc, + "Oops - load/store address misaligned"); +#endif +} + +asmlinkage void do_trap_bkpt(struct pt_regs *regs) +{ #ifdef CONFIG_KPROBES - if (kprobe_single_step_handler(regs)) - return; + if (kprobe_single_step_handler(regs)) + return; #endif #ifdef CONFIG_UPROBES - if (uprobe_single_step_handler(regs)) - return; + if (uprobe_single_step_handler(regs)) + return; #endif - info.si_code = TRAP_TRACE; - sig = SIGTRAP; - break; - case VEC_ILLEGAL: - tsk->thread.trap_no = vector; + if (user_mode(regs)) { + send_sig(SIGTRAP, current, 0); + return; + } + + do_trap_error(regs, SIGILL, ILL_ILLTRP, regs->pc, + "Oops - illegal trap exception"); +} + +asmlinkage void do_trap_illinsn(struct pt_regs *regs) +{ + current->thread.trap_no = trap_no(regs); + #ifdef CONFIG_KPROBES - if (kprobe_breakpoint_handler(regs)) - return; + if (kprobe_breakpoint_handler(regs)) + return; #endif #ifdef CONFIG_UPROBES - if (uprobe_breakpoint_handler(regs)) - return; + if (uprobe_breakpoint_handler(regs)) + return; #endif - die_if_kernel("Kernel mode ILLEGAL", regs, vector); #ifndef CONFIG_CPU_NO_USER_BKPT - if (*(uint16_t *)instruction_pointer(regs) != USR_BKPT) + if (*(uint16_t *)instruction_pointer(regs) != USR_BKPT) { + send_sig(SIGTRAP, current, 0); + return; + } #endif - { - sig = SIGILL; - break; - } - /* gdbserver breakpoint */ + + do_trap_error(regs, SIGILL, ILL_ILLOPC, regs->pc, + "Oops - illegal instruction exception"); +} + +asmlinkage void do_trap_fpe(struct pt_regs *regs) +{ +#ifdef CONFIG_CPU_HAS_FP + return fpu_fpe(regs); +#else + do_trap_error(regs, SIGILL, ILL_ILLOPC, regs->pc, + "Oops - fpu instruction exception"); +#endif +} + +asmlinkage void do_trap_priv(struct pt_regs *regs) +{ +#ifdef CONFIG_CPU_HAS_FP + if (user_mode(regs) && fpu_libc_helper(regs)) + return; +#endif + do_trap_error(regs, SIGILL, ILL_PRVOPC, regs->pc, + "Oops - illegal privileged exception"); +} + +asmlinkage void trap_c(struct pt_regs *regs) +{ + switch (trap_no(regs)) { + case VEC_ZERODIV: + do_trap_zdiv(regs); + break; + case VEC_TRACE: + do_trap_bkpt(regs); + break; + case VEC_ILLEGAL: + do_trap_illinsn(regs); + break; case VEC_TRAP1: - /* jtagserver breakpoint */ case VEC_BREAKPOINT: - die_if_kernel("Kernel mode BKPT", regs, vector); - info.si_code = TRAP_BRKPT; - sig = SIGTRAP; + do_trap_bkpt(regs); break; case VEC_ACCESS: - tsk->thread.trap_no = vector; - return buserr(regs); -#ifdef CONFIG_CPU_NEED_SOFTALIGN + do_trap_buserr(regs); + break; case VEC_ALIGN: - tsk->thread.trap_no = vector; - return csky_alignment(regs); -#endif -#ifdef CONFIG_CPU_HAS_FPU + do_trap_misaligned(regs); + break; case VEC_FPE: - tsk->thread.trap_no = vector; - die_if_kernel("Kernel mode FPE", regs, vector); - return fpu_fpe(regs); + do_trap_fpe(regs); + break; case VEC_PRIV: - tsk->thread.trap_no = vector; - die_if_kernel("Kernel mode PRIV", regs, vector); - if (fpu_libc_helper(regs)) - return; -#endif + do_trap_priv(regs); + break; default: - sig = SIGSEGV; + do_trap_unknown(regs); break; } - - tsk->thread.trap_no = vector; - - send_sig(sig, current, 0); } diff --git a/arch/csky/mm/fault.c b/arch/csky/mm/fault.c index 0b9cbf2cf6a9..b1dce9f2f04d 100644 --- a/arch/csky/mm/fault.c +++ b/arch/csky/mm/fault.c @@ -183,13 +183,13 @@ bad_area: bad_area_nosemaphore: /* User mode accesses just cause a SIGSEGV */ if (user_mode(regs)) { - tsk->thread.trap_no = (regs->sr >> 16) & 0xff; + tsk->thread.trap_no = trap_no(regs); force_sig_fault(SIGSEGV, si_code, (void __user *)address); return; } no_context: - tsk->thread.trap_no = (regs->sr >> 16) & 0xff; + tsk->thread.trap_no = trap_no(regs); /* Are we prepared to handle this kernel fault? */ if (fixup_exception(regs)) @@ -202,10 +202,10 @@ no_context: bust_spinlocks(1); pr_alert("Unable to handle kernel paging request at virtual " "address 0x%08lx, pc: 0x%08lx\n", address, regs->pc); - die_if_kernel("Oops", regs, write); + die(regs, "Oops"); out_of_memory: - tsk->thread.trap_no = (regs->sr >> 16) & 0xff; + tsk->thread.trap_no = trap_no(regs); /* * We ran out of memory, call the OOM killer, and return the userspace @@ -215,7 +215,7 @@ out_of_memory: return; do_sigbus: - tsk->thread.trap_no = (regs->sr >> 16) & 0xff; + tsk->thread.trap_no = trap_no(regs); mmap_read_unlock(mm); -- cgit v1.2.3 From 953131e5b5a5bb1b493fab413be41e4944f3c75d Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Thu, 30 Jul 2020 12:44:12 +0000 Subject: csky: Use top-down mmap layout Follow riscv mmap layout with commit "riscv: make mmap allocation top-down by default (54c95a11cc1b)". Before: cat /proc/self/maps 00008000-000dc000 r-xp 00000000 fe:00 17 /bin/busybox 000dc000-000dd000 r--p 000d3000 fe:00 17 /bin/busybox 000dd000-000de000 rw-p 000d4000 fe:00 17 /bin/busybox 2aaa8000-2aac6000 r-xp 00000000 fe:00 196 /lib/ld-2.28.9000.so 2aac6000-2aac7000 r-xp 00000000 00:00 0 [vdso] 2aac7000-2aac8000 r--p 0001e000 fe:00 196 /lib/ld-2.28.9000.so 2aac8000-2aac9000 rw-p 0001f000 fe:00 196 /lib/ld-2.28.9000.so 2aac9000-2aad9000 r-xp 00000000 fe:00 219 /lib/libresolv-2.28.9000.so 2aad9000-2aada000 r--p 0000f000 fe:00 219 /lib/libresolv-2.28.9000.so 2aada000-2aadb000 rw-p 00010000 fe:00 219 /lib/libresolv-2.28.9000.so 2aadb000-2aadd000 rw-p 00000000 00:00 0 2aadd000-2ac27000 r-xp 00000000 fe:00 203 /lib/libc-2.28.9000.so 2ac27000-2ac28000 ---p 0014a000 fe:00 203 /lib/libc-2.28.9000.so 2ac28000-2ac2a000 r--p 0014a000 fe:00 203 /lib/libc-2.28.9000.so 2ac2a000-2ac2b000 rw-p 0014c000 fe:00 203 /lib/libc-2.28.9000.so 2ac2b000-2ac2e000 rw-p 00000000 00:00 0 7fb99000-7fbba000 rwxp 00000000 00:00 0 [stack] After: cat /proc/self/maps 00008000-000dc000 r-xp 00000000 fe:00 17 /bin/busybox 000dc000-000dd000 r--p 000d3000 fe:00 17 /bin/busybox 000dd000-000de000 rw-p 000d4000 fe:00 17 /bin/busybox 77e13000-77f5d000 r-xp 00000000 fe:00 203 /lib/libc-2.28.9000.so 77f5d000-77f5e000 ---p 0014a000 fe:00 203 /lib/libc-2.28.9000.so 77f5e000-77f60000 r--p 0014a000 fe:00 203 /lib/libc-2.28.9000.so 77f60000-77f61000 rw-p 0014c000 fe:00 203 /lib/libc-2.28.9000.so 77f61000-77f66000 rw-p 00000000 00:00 0 77f66000-77f76000 r-xp 00000000 fe:00 219 /lib/libresolv-2.28.9000.so 77f76000-77f77000 r--p 0000f000 fe:00 219 /lib/libresolv-2.28.9000.so 77f77000-77f78000 rw-p 00010000 fe:00 219 /lib/libresolv-2.28.9000.so 77f78000-77f96000 r-xp 00000000 fe:00 196 /lib/ld-2.28.9000.so 77f96000-77f97000 r-xp 00000000 00:00 0 [vdso] 77f97000-77f98000 r--p 0001e000 fe:00 196 /lib/ld-2.28.9000.so 77f98000-77f99000 rw-p 0001f000 fe:00 196 /lib/ld-2.28.9000.so 7fd7b000-7fd9c000 rwxp 00000000 00:00 0 [stack] Signed-off-by: Guo Ren Cc: Arnd Bergmann --- arch/csky/Kconfig | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig index c51f64c14391..fd92d7348f32 100644 --- a/arch/csky/Kconfig +++ b/arch/csky/Kconfig @@ -9,6 +9,7 @@ config CSKY select ARCH_USE_BUILTIN_BSWAP select ARCH_USE_QUEUED_RWLOCKS if NR_CPUS>2 select ARCH_WANT_FRAME_POINTERS if !CPU_CK610 + select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT select COMMON_CLK select CLKSRC_MMIO select CSKY_MPINTC if CPU_CK860 @@ -38,6 +39,7 @@ config CSKY select GX6605S_TIMER if CPU_CK610 select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_AUDITSYSCALL + select HAVE_ARCH_MMAP_RND_BITS select HAVE_ARCH_SECCOMP_FILTER select HAVE_COPY_THREAD_TLS select HAVE_DEBUG_BUGVERBOSE @@ -151,6 +153,14 @@ config L1_CACHE_SHIFT default "5" if (CPU_CK807 || CPU_CK810) default "6" if (CPU_CK860) +config ARCH_MMAP_RND_BITS_MIN + default 8 + +# max bits determined by the following formula: +# VA_BITS - PAGE_SHIFT - 3 +config ARCH_MMAP_RND_BITS_MAX + default 17 + menu "Processor type and features" choice -- cgit v1.2.3 From 50d23a1c89051957a67ecaa40b5f833dd9b86c4c Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Thu, 30 Jul 2020 13:12:00 +0000 Subject: csky: Set CONFIG_NR_CPU 4 as default The C860 processors support 4 cores smp for maximum, so set NR_CPU to 4 as default Signed-off-by: Guo Ren Cc: Arnd Bergmann --- arch/csky/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig index fd92d7348f32..ad98b933055e 100644 --- a/arch/csky/Kconfig +++ b/arch/csky/Kconfig @@ -279,7 +279,7 @@ config NR_CPUS int "Maximum number of CPUs (2-32)" range 2 32 depends on SMP - default "2" + default "4" config HIGHMEM bool "High Memory Support" -- cgit v1.2.3 From 667b9324bd83d79abd64ee21bf5fa17ccc9ec246 Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Thu, 30 Jul 2020 13:14:08 +0000 Subject: csky: Fixup warning by EXPORT_SYMBOL(kmap) This a wrong code, and no kmap symbol for export. Signed-off-by: Guo Ren Cc: Arnd Bergmann --- arch/csky/mm/highmem.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/csky/mm/highmem.c b/arch/csky/mm/highmem.c index 89ec32e602a1..89c10800a002 100644 --- a/arch/csky/mm/highmem.c +++ b/arch/csky/mm/highmem.c @@ -19,8 +19,6 @@ void kmap_flush_tlb(unsigned long addr) } EXPORT_SYMBOL(kmap_flush_tlb); -EXPORT_SYMBOL(kmap); - void *kmap_atomic_high_prot(struct page *page, pgprot_t prot) { unsigned long vaddr; -- cgit v1.2.3 From 2c81b0768297fb2fb4d2f39eac49a55f3598375b Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Thu, 30 Jul 2020 17:05:51 +0000 Subject: csky: Add irq_work support Running work in hardware interrupt context for csky. Implement: - arch_irq_work_raise() - arch_irq_work_has_interrupt() Signed-off-by: Guo Ren Cc: Arnd Bergmann --- arch/csky/include/asm/irq_work.h | 11 +++++++++++ arch/csky/kernel/smp.c | 12 ++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 arch/csky/include/asm/irq_work.h diff --git a/arch/csky/include/asm/irq_work.h b/arch/csky/include/asm/irq_work.h new file mode 100644 index 000000000000..33aaf39d6f94 --- /dev/null +++ b/arch/csky/include/asm/irq_work.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ASM_CSKY_IRQ_WORK_H +#define __ASM_CSKY_IRQ_WORK_H + +static inline bool arch_irq_work_has_interrupt(void) +{ + return true; +} +extern void arch_irq_work_raise(void); +#endif /* __ASM_CSKY_IRQ_WORK_H */ diff --git a/arch/csky/kernel/smp.c b/arch/csky/kernel/smp.c index 1945fb29007d..60f2ab1c5865 100644 --- a/arch/csky/kernel/smp.c +++ b/arch/csky/kernel/smp.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,7 @@ enum ipi_message_type { IPI_EMPTY, IPI_RESCHEDULE, IPI_CALL_FUNC, + IPI_IRQ_WORK, IPI_MAX }; @@ -53,6 +55,9 @@ static irqreturn_t handle_ipi(int irq, void *dev) if (ops & (1 << IPI_CALL_FUNC)) generic_smp_call_function_interrupt(); + if (ops & (1 << IPI_IRQ_WORK)) + irq_work_run(); + BUG_ON((ops >> IPI_MAX) != 0); } @@ -108,6 +113,13 @@ void smp_send_reschedule(int cpu) send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE); } +#ifdef CONFIG_IRQ_WORK +void arch_irq_work_raise(void) +{ + send_ipi_message(cpumask_of(smp_processor_id()), IPI_IRQ_WORK); +} +#endif + void __init smp_prepare_boot_cpu(void) { } -- cgit v1.2.3 From e6169c4b4413f97cc36ceebc8dd6d2518f341d0f Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Fri, 31 Jul 2020 00:21:41 +0000 Subject: csky: Add arch_show_interrupts for IPI interrupts Here is the result: cat /proc/interrupts CPU0 CPU1 CPU2 CPU3 15: 1348 1299 952 1076 C-SKY SMP Intc 15 IPI Interrupt 16: 1203 1825 1598 1307 C-SKY SMP Intc 16 csky_mp_timer 43: 292 0 0 0 C-SKY SMP Intc 43 ttyS0 57: 106 0 0 0 C-SKY SMP Intc 57 virtio0 IPI0: 0 0 0 0 Empty interrupts IPI1: 19 41 45 27 Rescheduling interrupts IPI2: 1330 1259 908 1050 Function call interrupts IPI3: 0 0 0 0 Irq work interrupts Signed-off-by: Guo Ren Cc: Arnd Bergmann --- arch/csky/kernel/smp.c | 49 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/arch/csky/kernel/smp.c b/arch/csky/kernel/smp.c index 60f2ab1c5865..e7425e6b0419 100644 --- a/arch/csky/kernel/smp.c +++ b/arch/csky/kernel/smp.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -27,11 +28,6 @@ #include #endif -struct ipi_data_struct { - unsigned long bits ____cacheline_aligned; -}; -static DEFINE_PER_CPU(struct ipi_data_struct, ipi_data); - enum ipi_message_type { IPI_EMPTY, IPI_RESCHEDULE, @@ -40,8 +36,16 @@ enum ipi_message_type { IPI_MAX }; +struct ipi_data_struct { + unsigned long bits ____cacheline_aligned; + unsigned long stats[IPI_MAX] ____cacheline_aligned; +}; +static DEFINE_PER_CPU(struct ipi_data_struct, ipi_data); + static irqreturn_t handle_ipi(int irq, void *dev) { + unsigned long *stats = this_cpu_ptr(&ipi_data)->stats; + while (true) { unsigned long ops; @@ -49,14 +53,20 @@ static irqreturn_t handle_ipi(int irq, void *dev) if (ops == 0) return IRQ_HANDLED; - if (ops & (1 << IPI_RESCHEDULE)) + if (ops & (1 << IPI_RESCHEDULE)) { + stats[IPI_RESCHEDULE]++; scheduler_ipi(); + } - if (ops & (1 << IPI_CALL_FUNC)) + if (ops & (1 << IPI_CALL_FUNC)) { + stats[IPI_CALL_FUNC]++; generic_smp_call_function_interrupt(); + } - if (ops & (1 << IPI_IRQ_WORK)) + if (ops & (1 << IPI_IRQ_WORK)) { + stats[IPI_IRQ_WORK]++; irq_work_run(); + } BUG_ON((ops >> IPI_MAX) != 0); } @@ -88,6 +98,29 @@ send_ipi_message(const struct cpumask *to_whom, enum ipi_message_type operation) send_arch_ipi(to_whom); } +static const char * const ipi_names[] = { + [IPI_EMPTY] = "Empty interrupts", + [IPI_RESCHEDULE] = "Rescheduling interrupts", + [IPI_CALL_FUNC] = "Function call interrupts", + [IPI_IRQ_WORK] = "Irq work interrupts", +}; + +int arch_show_interrupts(struct seq_file *p, int prec) +{ + unsigned int cpu, i; + + for (i = 0; i < IPI_MAX; i++) { + seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i, + prec >= 4 ? " " : ""); + for_each_online_cpu(cpu) + seq_printf(p, "%10lu ", + per_cpu_ptr(&ipi_data, cpu)->stats[i]); + seq_printf(p, " %s\n", ipi_names[i]); + } + + return 0; +} + void arch_send_call_function_ipi_mask(struct cpumask *mask) { send_ipi_message(mask, IPI_CALL_FUNC); -- cgit v1.2.3 From bdcd93ef9afb42a6051e472fa62c693b1f9edbd8 Mon Sep 17 00:00:00 2001 From: Guo Ren Date: Fri, 31 Jul 2020 09:13:51 +0000 Subject: csky: Add context tracking support This patch support context tracking with no hz full. Here is the test result with dynticks-testing (see tick_stop): cat /sys/kernel/debug/tracing/per_cpu/cpu0/trace tracer: nop entries-in-buffer/entries-written: 356/356 #P:1 _-----=> irqs-off / _----=> need-resched | / _---=> hardirq/softirq || / _--=> preempt-depth ||| / delay TASK-PID CPU# |||| TIMESTAMP FUNCTION | | | |||| | | ... sleep-192 [000] d.h. 167.088270: hrtimer_expire_entry: hrtimer=(ptrval) function=tick_sched_timer now=166436355700 sleep-192 [000] d.h. 167.092279: hrtimer_expire_entry: hrtimer=(ptrval) function=tick_sched_timer now=166440365700 -0 [000] d.h2 167.096492: hrtimer_expire_entry: hrtimer=(ptrval) function=tick_sched_timer now=166444578400 -0 [000] d..1 167.097876: tick_stop: success=1 dependency=NONE ^^^^^^^^^ -0 [000] d.h1 168.818206: hrtimer_expire_entry: hrtimer=(ptrval) function=tick_sched_timer now=168166280900 kworker/u2:0-7 [000] .... 168.821760: workqueue_execute_start: work struct (ptrval): function wb_workfn kworker/u2:0-7 [000] d.h1 168.824464: hrtimer_expire_entry: hrtimer=(ptrval) function=tick_sched_timer now=168172547100 kworker/0:1-18 [000] .... 168.825053: workqueue_execute_start: work struct (ptrval): function vmstat_update kworker/0:1-18 [000] .... 168.825238: workqueue_execute_start: work struct (ptrval): function vmstat_shepherd kworker/0:1-18 [000] .... 168.825516: workqueue_execute_start: work struct (ptrval): function neigh_periodic_work -0 [000] d..1 168.826121: tick_stop: success=1 dependency=NONE kworker/u2:0-7 [000] .... 169.377327: workqueue_execute_start: work struct (ptrval): function flush_to_ldisc -0 [000] d..1 169.379832: tick_stop: success=1 dependency=NONE kworker/u2:0-7 [000] .... 169.607935: workqueue_execute_start: work struct (ptrval): function flush_to_ldisc kworker/u2:0-7 [000] d.h1 169.608148: hrtimer_expire_entry: hrtimer=(ptrval) function=tick_sched_timer now=168956235500 -0 [000] d..1 169.608654: tick_stop: success=1 dependency=NONE Signed-off-by: Guo Ren Cc: Greentime Hu Cc: Arnd Bergmann --- arch/csky/Kconfig | 2 ++ arch/csky/kernel/entry.S | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig index ad98b933055e..af238739811e 100644 --- a/arch/csky/Kconfig +++ b/arch/csky/Kconfig @@ -42,6 +42,8 @@ config CSKY select HAVE_ARCH_MMAP_RND_BITS select HAVE_ARCH_SECCOMP_FILTER select HAVE_COPY_THREAD_TLS + select HAVE_CONTEXT_TRACKING + select HAVE_VIRT_CPU_ACCOUNTING_GEN select HAVE_DEBUG_BUGVERBOSE select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE_WITH_REGS diff --git a/arch/csky/kernel/entry.S b/arch/csky/kernel/entry.S index efd2e696e3cd..5a5cabd076e1 100644 --- a/arch/csky/kernel/entry.S +++ b/arch/csky/kernel/entry.S @@ -23,6 +23,24 @@ #endif .endm +.macro context_tracking +#ifdef CONFIG_CONTEXT_TRACKING + mfcr a0, epsr + btsti a0, 31 + bt 1f + jbsr context_tracking_user_exit + ldw a0, (sp, LSAVE_A0) + ldw a1, (sp, LSAVE_A1) + ldw a2, (sp, LSAVE_A2) + ldw a3, (sp, LSAVE_A3) +#if defined(__CSKYABIV1__) + ldw r6, (sp, LSAVE_A4) + ldw r7, (sp, LSAVE_A5) +#endif +1: +#endif +.endm + .macro tlbop_begin name, val0, val1, val2 ENTRY(csky_\name) mtcr a3, ss2 @@ -103,6 +121,7 @@ ENTRY(csky_\name) .endm .macro tlbop_end is_write zero_fp + context_tracking RD_MEH a2 psrset ee, ie mov a0, sp @@ -128,6 +147,7 @@ tlbop_end 1 ENTRY(csky_systemcall) SAVE_ALL TRAP0_SIZE zero_fp + context_tracking psrset ee, ie lrw r9, __NR_syscalls @@ -237,6 +257,9 @@ ret_from_exception: and r10, r9 cmpnei r10, 0 bt exit_work +#ifdef CONFIG_CONTEXT_TRACKING + jbsr context_tracking_user_enter +#endif 1: #ifdef CONFIG_PREEMPTION mov r9, sp @@ -277,6 +300,7 @@ work_resched: ENTRY(csky_trap) SAVE_ALL 0 zero_fp + context_tracking psrset ee mov a0, sp /* Push Stack pointer arg */ jbsr trap_c /* Call C-level trap handler */ @@ -311,6 +335,7 @@ ENTRY(csky_get_tls) ENTRY(csky_irq) SAVE_ALL 0 zero_fp + context_tracking psrset ee #ifdef CONFIG_TRACE_IRQFLAGS -- cgit v1.2.3