diff options
36 files changed, 1555 insertions, 222 deletions
diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig index 37bed8aadf95..398113c845f5 100644 --- a/arch/csky/Kconfig +++ b/arch/csky/Kconfig @@ -28,10 +28,13 @@ config CSKY select GENERIC_SCHED_CLOCK select GENERIC_SMP_IDLE_THREAD select HAVE_ARCH_TRACEHOOK + select HAVE_FUNCTION_TRACER + select HAVE_FUNCTION_GRAPH_TRACER select HAVE_GENERIC_DMA_COHERENT select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZO select HAVE_KERNEL_LZMA + select HAVE_PERF_EVENTS select HAVE_C_RECORDMCOUNT select HAVE_DMA_API_DEBUG select HAVE_DMA_CONTIGUOUS @@ -40,7 +43,7 @@ config CSKY select OF select OF_EARLY_FLATTREE select OF_RESERVED_MEM - select PERF_USE_VMALLOC + select PERF_USE_VMALLOC if CPU_CK610 select RTC_LIB select TIMER_OF select USB_ARCH_HAS_EHCI @@ -93,6 +96,9 @@ config MMU config RWSEM_GENERIC_SPINLOCK def_bool y +config STACKTRACE_SUPPORT + def_bool y + config TIME_LOW_RES def_bool y @@ -145,6 +151,19 @@ config CPU_CK860 endchoice choice + prompt "C-SKY PMU type" + depends on PERF_EVENTS + depends on CPU_CK807 || CPU_CK810 || CPU_CK860 + +config CPU_PMU_NONE + bool "None" + +config CSKY_PMU_V1 + bool "Performance Monitoring Unit Ver.1" + +endchoice + +choice prompt "Power Manager Instruction (wait/doze/stop)" default CPU_PM_NONE @@ -197,6 +216,15 @@ config RAM_BASE hex "DRAM start addr (the same with memory-section in dts)" default 0x0 +config HOTPLUG_CPU + bool "Support for hot-pluggable CPUs" + select GENERIC_IRQ_MIGRATION + depends on SMP + help + Say Y here to allow turning CPUs off and on. CPUs can be + controlled through /sys/devices/system/cpu/cpu1/hotplug/target. + + Say N if you want to disable CPU hotplug. endmenu source "kernel/Kconfig.hz" diff --git a/arch/csky/Makefile b/arch/csky/Makefile index c639fc167895..3607a6e8f66c 100644 --- a/arch/csky/Makefile +++ b/arch/csky/Makefile @@ -47,6 +47,10 @@ ifeq ($(CSKYABI),abiv2) KBUILD_CFLAGS += -mno-stack-size endif +ifdef CONFIG_STACKTRACE +KBUILD_CFLAGS += -mbacktrace +endif + abidirs := $(patsubst %,arch/csky/%/,$(CSKYABI)) KBUILD_CFLAGS += $(patsubst %,-I$(srctree)/%inc,$(abidirs)) diff --git a/arch/csky/abiv1/inc/abi/pgtable-bits.h b/arch/csky/abiv1/inc/abi/pgtable-bits.h index 455075b5db0d..d605445aad9a 100644 --- a/arch/csky/abiv1/inc/abi/pgtable-bits.h +++ b/arch/csky/abiv1/inc/abi/pgtable-bits.h @@ -26,6 +26,7 @@ #define _PAGE_CACHE (3<<9) #define _PAGE_UNCACHE (2<<9) +#define _PAGE_SO _PAGE_UNCACHE #define _CACHE_MASK (7<<9) diff --git a/arch/csky/abiv1/inc/abi/switch_context.h b/arch/csky/abiv1/inc/abi/switch_context.h new file mode 100644 index 000000000000..17c82686498e --- /dev/null +++ b/arch/csky/abiv1/inc/abi/switch_context.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ABI_CSKY_PTRACE_H +#define __ABI_CSKY_PTRACE_H + +struct switch_stack { + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long r11; + unsigned long r12; + unsigned long r13; + unsigned long r14; + unsigned long r15; +}; +#endif /* __ABI_CSKY_PTRACE_H */ diff --git a/arch/csky/abiv2/Makefile b/arch/csky/abiv2/Makefile index 069ca7276b99..b1d44f6fbcbd 100644 --- a/arch/csky/abiv2/Makefile +++ b/arch/csky/abiv2/Makefile @@ -8,3 +8,4 @@ obj-y += strcmp.o obj-y += strcpy.o obj-y += strlen.o obj-y += strksyms.o +obj-$(CONFIG_FUNCTION_TRACER) += mcount.o diff --git a/arch/csky/abiv2/inc/abi/entry.h b/arch/csky/abiv2/inc/abi/entry.h index acd05214d4e3..edc5cc04c4de 100644 --- a/arch/csky/abiv2/inc/abi/entry.h +++ b/arch/csky/abiv2/inc/abi/entry.h @@ -57,6 +57,8 @@ stw lr, (sp, 60) mflo lr stw lr, (sp, 64) + mfcr lr, cr14 + stw lr, (sp, 68) #endif subi sp, 80 .endm @@ -77,6 +79,8 @@ mthi a0 ldw a0, (sp, 144) mtlo a0 + ldw a0, (sp, 148) + mtcr a0, cr14 #endif ldw a0, (sp, 24) @@ -93,9 +97,9 @@ .endm .macro SAVE_SWITCH_STACK - subi sp, 64 + subi sp, 64 stm r4-r11, (sp) - stw r15, (sp, 32) + stw lr, (sp, 32) stw r16, (sp, 36) stw r17, (sp, 40) stw r26, (sp, 44) @@ -103,11 +107,29 @@ stw r28, (sp, 52) stw r29, (sp, 56) stw r30, (sp, 60) +#ifdef CONFIG_CPU_HAS_HILO + subi sp, 16 + mfhi lr + stw lr, (sp, 0) + mflo lr + stw lr, (sp, 4) + mfcr lr, cr14 + stw lr, (sp, 8) +#endif .endm .macro RESTORE_SWITCH_STACK +#ifdef CONFIG_CPU_HAS_HILO + ldw lr, (sp, 0) + mthi lr + ldw lr, (sp, 4) + mtlo lr + ldw lr, (sp, 8) + mtcr lr, cr14 + addi sp, 16 +#endif ldm r4-r11, (sp) - ldw r15, (sp, 32) + ldw lr, (sp, 32) ldw r16, (sp, 36) ldw r17, (sp, 40) ldw r26, (sp, 44) diff --git a/arch/csky/abiv2/inc/abi/pgtable-bits.h b/arch/csky/abiv2/inc/abi/pgtable-bits.h index b20ae19702e3..137f7932c83b 100644 --- a/arch/csky/abiv2/inc/abi/pgtable-bits.h +++ b/arch/csky/abiv2/inc/abi/pgtable-bits.h @@ -32,6 +32,6 @@ #define _CACHE_MASK _PAGE_CACHE #define _CACHE_CACHED (_PAGE_VALID | _PAGE_CACHE | _PAGE_BUF) -#define _CACHE_UNCACHED (_PAGE_VALID | _PAGE_SO) +#define _CACHE_UNCACHED (_PAGE_VALID) #endif /* __ASM_CSKY_PGTABLE_BITS_H */ diff --git a/arch/csky/abiv2/inc/abi/switch_context.h b/arch/csky/abiv2/inc/abi/switch_context.h new file mode 100644 index 000000000000..73a81245a3b3 --- /dev/null +++ b/arch/csky/abiv2/inc/abi/switch_context.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ABI_CSKY_PTRACE_H +#define __ABI_CSKY_PTRACE_H + +struct switch_stack { +#ifdef CONFIG_CPU_HAS_HILO + unsigned long rhi; + unsigned long rlo; + unsigned long cr14; + unsigned long pad; +#endif + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long r11; + + unsigned long r15; + unsigned long r16; + unsigned long r17; + unsigned long r26; + unsigned long r27; + unsigned long r28; + unsigned long r29; + unsigned long r30; +}; +#endif /* __ABI_CSKY_PTRACE_H */ diff --git a/arch/csky/abiv2/mcount.S b/arch/csky/abiv2/mcount.S new file mode 100644 index 000000000000..c633379956f5 --- /dev/null +++ b/arch/csky/abiv2/mcount.S @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include <linux/linkage.h> +#include <asm/ftrace.h> + +/* + * csky-gcc with -pg will put the following asm after prologue: + * push r15 + * jsri _mcount + * + * stack layout after mcount_enter in _mcount(): + * + * current sp => 0:+-------+ + * | a0-a3 | -> must save all argument regs + * +16:+-------+ + * | lr | -> _mcount lr (instrumente function's pc) + * +20:+-------+ + * | fp=r8 | -> instrumented function fp + * +24:+-------+ + * | plr | -> instrumented function lr (parent's pc) + * +-------+ + */ + +.macro mcount_enter + subi sp, 24 + stw a0, (sp, 0) + stw a1, (sp, 4) + stw a2, (sp, 8) + stw a3, (sp, 12) + stw lr, (sp, 16) + stw r8, (sp, 20) +.endm + +.macro mcount_exit + ldw a0, (sp, 0) + ldw a1, (sp, 4) + ldw a2, (sp, 8) + ldw a3, (sp, 12) + ldw t1, (sp, 16) + ldw r8, (sp, 20) + ldw lr, (sp, 24) + addi sp, 28 + jmp t1 +.endm + +.macro save_return_regs + subi sp, 16 + stw a0, (sp, 0) + stw a1, (sp, 4) + stw a2, (sp, 8) + stw a3, (sp, 12) +.endm + +.macro restore_return_regs + mov lr, a0 + ldw a0, (sp, 0) + ldw a1, (sp, 4) + ldw a2, (sp, 8) + ldw a3, (sp, 12) + addi sp, 16 +.endm + +ENTRY(ftrace_stub) + jmp lr +END(ftrace_stub) + +ENTRY(_mcount) + mcount_enter + + /* r26 is link register, only used with jsri translation */ + lrw r26, ftrace_trace_function + ldw r26, (r26, 0) + lrw a1, ftrace_stub + cmpne r26, a1 + bf skip_ftrace + + mov a0, lr + subi a0, MCOUNT_INSN_SIZE + ldw a1, (sp, 24) + + jsr r26 + +#ifndef CONFIG_FUNCTION_GRAPH_TRACER +skip_ftrace: + mcount_exit +#else +skip_ftrace: + lrw a0, ftrace_graph_return + ldw a0, (a0, 0) + lrw a1, ftrace_stub + cmpne a0, a1 + bt ftrace_graph_caller + + lrw a0, ftrace_graph_entry + ldw a0, (a0, 0) + lrw a1, ftrace_graph_entry_stub + cmpne a0, a1 + bt ftrace_graph_caller + + mcount_exit +#endif +END(_mcount) + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +ENTRY(ftrace_graph_caller) + mov a0, sp + addi a0, 24 + ldw a1, (sp, 16) + subi a1, MCOUNT_INSN_SIZE + mov a2, r8 + lrw r26, prepare_ftrace_return + jsr r26 + mcount_exit +END(ftrace_graph_caller) + +ENTRY(return_to_handler) + save_return_regs + mov a0, r8 + jsri ftrace_return_to_handler + restore_return_regs + jmp lr +END(return_to_handler) +#endif diff --git a/arch/csky/abiv2/memcpy.S b/arch/csky/abiv2/memcpy.S index 987fec60ab97..145bf3a9360e 100644 --- a/arch/csky/abiv2/memcpy.S +++ b/arch/csky/abiv2/memcpy.S @@ -27,13 +27,7 @@ ENTRY(memcpy) LABLE_ALIGN .L_len_larger_16bytes: -#if defined(__CSKY_VDSPV2__) - vldx.8 vr0, (r1), r19 - PRE_BNEZAD (r18) - addi r1, 16 - vstx.8 vr0, (r0), r19 - addi r0, 16 -#elif defined(__CK860__) +#if defined(__CK860__) ldw r3, (r1, 0) stw r3, (r0, 0) ldw r3, (r1, 4) diff --git a/arch/csky/include/asm/elf.h b/arch/csky/include/asm/elf.h index 773b133ca297..e1ec558278bc 100644 --- a/arch/csky/include/asm/elf.h +++ b/arch/csky/include/asm/elf.h @@ -7,7 +7,8 @@ #include <asm/ptrace.h> #include <abi/regdef.h> -#define ELF_ARCH 252 +#define ELF_ARCH EM_CSKY +#define EM_CSKY_OLD 39 /* CSKY Relocations */ #define R_CSKY_NONE 0 @@ -31,14 +32,20 @@ typedef unsigned long elf_greg_t; typedef struct user_fp elf_fpregset_t; -#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t)) +/* + * In gdb/bfd elf32-csky.c, csky_elf_grok_prstatus() use fixed size of + * elf_prstatus. It's 148 for abiv1 and 220 for abiv2, the size is enough + * for coredump and no need full sizeof(struct pt_regs). + */ +#define ELF_NGREG ((sizeof(struct pt_regs) / sizeof(elf_greg_t)) - 2) typedef elf_greg_t elf_gregset_t[ELF_NGREG]; /* * This is used to ensure we don't load something for the wrong architecture. */ -#define elf_check_arch(x) ((x)->e_machine == ELF_ARCH) +#define elf_check_arch(x) (((x)->e_machine == ELF_ARCH) || \ + ((x)->e_machine == EM_CSKY_OLD)) /* * These are used to set parameters in the core dumps. diff --git a/arch/csky/include/asm/ftrace.h b/arch/csky/include/asm/ftrace.h new file mode 100644 index 000000000000..7547c45312a8 --- /dev/null +++ b/arch/csky/include/asm/ftrace.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_FTRACE_H +#define __ASM_CSKY_FTRACE_H + +#define MCOUNT_INSN_SIZE 4 + +#define HAVE_FUNCTION_GRAPH_FP_TEST + +#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR + +#endif /* __ASM_CSKY_FTRACE_H */ diff --git a/arch/csky/include/asm/perf_event.h b/arch/csky/include/asm/perf_event.h new file mode 100644 index 000000000000..ea8193122294 --- /dev/null +++ b/arch/csky/include/asm/perf_event.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#ifndef __ASM_CSKY_PERF_EVENT_H +#define __ASM_CSKY_PERF_EVENT_H + +#endif /* __ASM_PERF_EVENT_ELF_H */ diff --git a/arch/csky/include/asm/processor.h b/arch/csky/include/asm/processor.h index b1748659b2e9..8f454810514f 100644 --- a/arch/csky/include/asm/processor.h +++ b/arch/csky/include/asm/processor.h @@ -11,19 +11,13 @@ #include <asm/cache.h> #include <abi/reg_ops.h> #include <abi/regdef.h> +#include <abi/switch_context.h> #ifdef CONFIG_CPU_HAS_FPU #include <abi/fpu.h> #endif struct cpuinfo_csky { - unsigned long udelay_val; unsigned long asid_cache; - /* - * Capability and feature descriptor structure for CSKY CPU - */ - unsigned long options; - unsigned int processor_id[4]; - unsigned int fpu_id; } __aligned(SMP_CACHE_BYTES); extern struct cpuinfo_csky cpu_data[]; @@ -49,13 +43,6 @@ extern struct cpuinfo_csky cpu_data[]; struct thread_struct { unsigned long ksp; /* kernel stack pointer */ unsigned long sr; /* saved status register */ - unsigned long esp0; /* points to SR of stack frame */ - unsigned long hi; - unsigned long lo; - - /* Other stuff associated with the thread. */ - unsigned long address; /* Last user fault */ - unsigned long error_code; /* FPU regs */ struct user_fp __aligned(16) user_fp; diff --git a/arch/csky/include/asm/smp.h b/arch/csky/include/asm/smp.h index 4a929c4d6437..668b79ce29ea 100644 --- a/arch/csky/include/asm/smp.h +++ b/arch/csky/include/asm/smp.h @@ -21,6 +21,10 @@ void __init set_send_ipi(void (*func)(const struct cpumask *mask), int irq); #define raw_smp_processor_id() (current_thread_info()->cpu) +int __cpu_disable(void); + +void __cpu_die(unsigned int cpu); + #endif /* CONFIG_SMP */ #endif /* __ASM_CSKY_SMP_H */ diff --git a/arch/csky/include/asm/syscall.h b/arch/csky/include/asm/syscall.h index 926a64a8b4ee..d637445737b7 100644 --- a/arch/csky/include/asm/syscall.h +++ b/arch/csky/include/asm/syscall.h @@ -6,6 +6,7 @@ #include <linux/sched.h> #include <linux/err.h> #include <abi/regdef.h> +#include <uapi/linux/audit.h> static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs) @@ -68,4 +69,10 @@ syscall_set_arguments(struct task_struct *task, struct pt_regs *regs, memcpy(®s->a1 + i * sizeof(regs->a1), args, n * sizeof(regs->a0)); } +static inline int +syscall_get_arch(void) +{ + return AUDIT_ARCH_CSKY; +} + #endif /* __ASM_SYSCALL_H */ diff --git a/arch/csky/include/asm/thread_info.h b/arch/csky/include/asm/thread_info.h index a2c69a7836f7..0e9d035d712b 100644 --- a/arch/csky/include/asm/thread_info.h +++ b/arch/csky/include/asm/thread_info.h @@ -10,6 +10,7 @@ #include <asm/types.h> #include <asm/page.h> #include <asm/processor.h> +#include <abi/switch_context.h> struct thread_info { struct task_struct *task; @@ -36,6 +37,9 @@ struct thread_info { #define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT) +#define thread_saved_fp(tsk) \ + ((unsigned long)(((struct switch_stack *)(tsk->thread.ksp))->r8)) + static inline struct thread_info *current_thread_info(void) { unsigned long sp; diff --git a/arch/csky/include/uapi/asm/Kbuild b/arch/csky/include/uapi/asm/Kbuild index e02fd44e6447..7449fdeb973d 100644 --- a/arch/csky/include/uapi/asm/Kbuild +++ b/arch/csky/include/uapi/asm/Kbuild @@ -1,7 +1,5 @@ include include/uapi/asm-generic/Kbuild.asm -header-y += cachectl.h - generic-y += auxvec.h generic-y += param.h generic-y += bpf_perf_event.h diff --git a/arch/csky/include/uapi/asm/ptrace.h b/arch/csky/include/uapi/asm/ptrace.h index f10d02c8b09e..a4eaa8ddf0b1 100644 --- a/arch/csky/include/uapi/asm/ptrace.h +++ b/arch/csky/include/uapi/asm/ptrace.h @@ -36,7 +36,7 @@ struct pt_regs { unsigned long rhi; unsigned long rlo; - unsigned long pad; /* reserved */ + unsigned long dcsr; #endif }; @@ -48,43 +48,6 @@ struct user_fp { unsigned long reserved; }; -/* - * Switch stack for switch_to after push pt_regs. - * - * ABI_CSKYV2: r4 ~ r11, r15 ~ r17, r26 ~ r30; - * ABI_CSKYV1: r8 ~ r14, r15; - */ -struct switch_stack { -#if defined(__CSKYABIV2__) - unsigned long r4; - unsigned long r5; - unsigned long r6; - unsigned long r7; - unsigned long r8; - unsigned long r9; - unsigned long r10; - unsigned long r11; -#else - unsigned long r8; - unsigned long r9; - unsigned long r10; - unsigned long r11; - unsigned long r12; - unsigned long r13; - unsigned long r14; -#endif - unsigned long r15; -#if defined(__CSKYABIV2__) - unsigned long r16; - unsigned long r17; - unsigned long r26; - unsigned long r27; - unsigned long r28; - unsigned long r29; - unsigned long r30; -#endif -}; - #ifdef __KERNEL__ #define PS_S 0x80000000 /* Supervisor Mode */ diff --git a/arch/csky/kernel/Makefile b/arch/csky/kernel/Makefile index 4422de756cde..484e6d3a3647 100644 --- a/arch/csky/kernel/Makefile +++ b/arch/csky/kernel/Makefile @@ -6,3 +6,10 @@ obj-y += process.o cpu-probe.o ptrace.o dumpstack.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o +obj-$(CONFIG_STACKTRACE) += stacktrace.o +obj-$(CONFIG_CSKY_PMU_V1) += perf_event.o + +ifdef CONFIG_FUNCTION_TRACER +CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE) +endif diff --git a/arch/csky/kernel/asm-offsets.c b/arch/csky/kernel/asm-offsets.c index 8d3ed811321f..9b48b1b1a61b 100644 --- a/arch/csky/kernel/asm-offsets.c +++ b/arch/csky/kernel/asm-offsets.c @@ -20,12 +20,9 @@ int main(void) /* offsets into the thread struct */ DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); DEFINE(THREAD_SR, offsetof(struct thread_struct, sr)); - DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0)); DEFINE(THREAD_FESR, offsetof(struct thread_struct, user_fp.fesr)); DEFINE(THREAD_FCR, offsetof(struct thread_struct, user_fp.fcr)); DEFINE(THREAD_FPREG, offsetof(struct thread_struct, user_fp.vr)); - DEFINE(THREAD_DSPHI, offsetof(struct thread_struct, hi)); - DEFINE(THREAD_DSPLO, offsetof(struct thread_struct, lo)); /* offsets into the thread_info struct */ DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags)); diff --git a/arch/csky/kernel/dumpstack.c b/arch/csky/kernel/dumpstack.c index a9a03ac57ec5..659253e9989c 100644 --- a/arch/csky/kernel/dumpstack.c +++ b/arch/csky/kernel/dumpstack.c @@ -7,60 +7,39 @@ int kstack_depth_to_print = 48; void show_trace(unsigned long *stack) { - unsigned long *endstack; + unsigned long *stack_end; + unsigned long *stack_start; + unsigned long *fp; unsigned long addr; - int i; - pr_info("Call Trace:\n"); - addr = (unsigned long)stack + THREAD_SIZE - 1; - endstack = (unsigned long *)(addr & -THREAD_SIZE); - i = 0; - while (stack + 1 <= endstack) { - addr = *stack++; - /* - * If the address is either in the text segment of the - * kernel, or in the region which contains vmalloc'ed - * memory, it *may* be the address of a calling - * routine; if so, print it so that someone tracing - * down the cause of the crash will be able to figure - * out the call path that was taken. - */ - if (__kernel_text_address(addr)) { -#ifndef CONFIG_KALLSYMS - if (i % 5 == 0) - pr_cont("\n "); + addr = (unsigned long) stack & THREAD_MASK; + stack_start = (unsigned long *) addr; + stack_end = (unsigned long *) (addr + THREAD_SIZE); + + fp = stack; + pr_info("\nCall Trace:"); + + while (fp > stack_start && fp < stack_end) { +#ifdef CONFIG_STACKTRACE + addr = fp[1]; + fp = (unsigned long *) fp[0]; +#else + addr = *fp++; #endif - pr_cont(" [<%08lx>] %pS\n", addr, (void *)addr); - i++; - } + if (__kernel_text_address(addr)) + pr_cont("\n[<%08lx>] %pS", addr, (void *)addr); } pr_cont("\n"); } void show_stack(struct task_struct *task, unsigned long *stack) { - unsigned long *p; - unsigned long *endstack; - int i; - if (!stack) { if (task) - stack = (unsigned long *)task->thread.esp0; + stack = (unsigned long *)thread_saved_fp(task); else stack = (unsigned long *)&stack; } - endstack = (unsigned long *) - (((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE); - pr_info("Stack from %08lx:", (unsigned long)stack); - p = stack; - for (i = 0; i < kstack_depth_to_print; i++) { - if (p + 1 > endstack) - break; - if (i % 8 == 0) - pr_cont("\n "); - pr_cont(" %08lx", *p++); - } - pr_cont("\n"); show_trace(stack); } diff --git a/arch/csky/kernel/entry.S b/arch/csky/kernel/entry.S index 79f92b8606c8..5137ed9062bd 100644 --- a/arch/csky/kernel/entry.S +++ b/arch/csky/kernel/entry.S @@ -122,16 +122,6 @@ ENTRY(csky_systemcall) psrset ee, ie - /* Stack frame for syscall, origin call set_esp0 */ - mov r12, sp - - bmaski r11, 13 - andn r12, r11 - bgeni r11, 9 - addi r11, 32 - addu r12, r11 - st sp, (r12, 0) - lrw r11, __NR_syscalls cmphs syscallid, r11 /* Check nr of syscall */ bt ret_from_exception @@ -183,18 +173,10 @@ ENTRY(csky_systemcall) #endif stw a0, (sp, LSAVE_A0) /* Save return value */ - movi a0, 1 /* leave system call */ - mov a1, sp /* sp = pt_regs pointer */ - jbsr syscall_trace - -syscall_exit_work: - ld syscallid, (sp, LSAVE_PSR) - btsti syscallid, 31 - bt 2f - - jmpi resume_userspace - -2: RESTORE_ALL + movi a0, 1 /* leave system call */ + mov a1, sp /* right now, sp --> pt_regs */ + jbsr syscall_trace + br ret_from_exception ENTRY(ret_from_kernel_thread) jbsr schedule_tail @@ -238,8 +220,6 @@ resume_userspace: 1: RESTORE_ALL exit_work: - mov a0, sp /* Stack address is arg[0] */ - jbsr set_esp0 /* Call C level */ btsti r8, TIF_NEED_RESCHED bt work_resched /* If thread_info->flag is empty, RESTORE_ALL */ @@ -354,34 +334,12 @@ ENTRY(__switch_to) stw sp, (a3, THREAD_KSP) -#ifdef CONFIG_CPU_HAS_HILO - lrw r10, THREAD_DSPHI - add r10, a3 - mfhi r6 - mflo r7 - stw r6, (r10, 0) /* THREAD_DSPHI */ - stw r7, (r10, 4) /* THREAD_DSPLO */ - mfcr r6, cr14 - stw r6, (r10, 8) /* THREAD_DSPCSR */ -#endif - /* Set up next process to run */ lrw a3, TASK_THREAD addu a3, a1 ldw sp, (a3, THREAD_KSP) /* Set next kernel sp */ -#ifdef CONFIG_CPU_HAS_HILO - lrw r10, THREAD_DSPHI - add r10, a3 - ldw r6, (r10, 8) /* THREAD_DSPCSR */ - mtcr r6, cr14 - ldw r6, (r10, 0) /* THREAD_DSPHI */ - ldw r7, (r10, 4) /* THREAD_DSPLO */ - mthi r6 - mtlo r7 -#endif - ldw a2, (a3, THREAD_SR) /* Set next PSR */ mtcr a2, psr diff --git a/arch/csky/kernel/ftrace.c b/arch/csky/kernel/ftrace.c new file mode 100644 index 000000000000..274c431f1810 --- /dev/null +++ b/arch/csky/kernel/ftrace.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include <linux/ftrace.h> +#include <linux/uaccess.h> + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, + unsigned long frame_pointer) +{ + unsigned long return_hooker = (unsigned long)&return_to_handler; + unsigned long old; + + if (unlikely(atomic_read(¤t->tracing_graph_pause))) + return; + + old = *parent; + + if (!function_graph_enter(old, self_addr, + *(unsigned long *)frame_pointer, parent)) { + /* + * For csky-gcc function has sub-call: + * subi sp, sp, 8 + * stw r8, (sp, 0) + * mov r8, sp + * st.w r15, (sp, 0x4) + * push r15 + * jl _mcount + * We only need set *parent for resume + * + * For csky-gcc function has no sub-call: + * subi sp, sp, 4 + * stw r8, (sp, 0) + * mov r8, sp + * push r15 + * jl _mcount + * We need set *parent and *(frame_pointer + 4) for resume, + * because lr is resumed twice. + */ + *parent = return_hooker; + frame_pointer += 4; + if (*(unsigned long *)frame_pointer == old) + *(unsigned long *)frame_pointer = return_hooker; + } +} +#endif + +/* _mcount is defined in abi's mcount.S */ +extern void _mcount(void); +EXPORT_SYMBOL(_mcount); diff --git a/arch/csky/kernel/perf_event.c b/arch/csky/kernel/perf_event.c new file mode 100644 index 000000000000..376c972f5f37 --- /dev/null +++ b/arch/csky/kernel/perf_event.c @@ -0,0 +1,1031 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include <linux/errno.h> |