diff options
| -rw-r--r-- | arch/nds32/Kconfig | 4 | ||||
| -rw-r--r-- | arch/nds32/Makefile | 4 | ||||
| -rw-r--r-- | arch/nds32/include/asm/elf.h | 4 | ||||
| -rw-r--r-- | arch/nds32/include/asm/ftrace.h | 46 | ||||
| -rw-r--r-- | arch/nds32/include/asm/nds32.h | 1 | ||||
| -rw-r--r-- | arch/nds32/include/asm/uaccess.h | 229 | ||||
| -rw-r--r-- | arch/nds32/kernel/Makefile | 6 | ||||
| -rw-r--r-- | arch/nds32/kernel/atl2c.c | 3 | ||||
| -rw-r--r-- | arch/nds32/kernel/ex-entry.S | 2 | ||||
| -rw-r--r-- | arch/nds32/kernel/ex-exit.S | 4 | ||||
| -rw-r--r-- | arch/nds32/kernel/ftrace.c | 309 | ||||
| -rw-r--r-- | arch/nds32/kernel/module.c | 4 | ||||
| -rw-r--r-- | arch/nds32/kernel/stacktrace.c | 6 | ||||
| -rw-r--r-- | arch/nds32/kernel/traps.c | 42 | ||||
| -rw-r--r-- | arch/nds32/kernel/vmlinux.lds.S | 12 | ||||
| -rwxr-xr-x | scripts/recordmcount.pl | 3 |
16 files changed, 527 insertions, 152 deletions
diff --git a/arch/nds32/Kconfig b/arch/nds32/Kconfig index 1d4248fa55e9..7068f341133d 100644 --- a/arch/nds32/Kconfig +++ b/arch/nds32/Kconfig | |||
| @@ -40,6 +40,10 @@ config NDS32 | |||
| 40 | select NO_IOPORT_MAP | 40 | select NO_IOPORT_MAP |
| 41 | select RTC_LIB | 41 | select RTC_LIB |
| 42 | select THREAD_INFO_IN_TASK | 42 | select THREAD_INFO_IN_TASK |
| 43 | select HAVE_FUNCTION_TRACER | ||
| 44 | select HAVE_FUNCTION_GRAPH_TRACER | ||
| 45 | select HAVE_FTRACE_MCOUNT_RECORD | ||
| 46 | select HAVE_DYNAMIC_FTRACE | ||
| 43 | help | 47 | help |
| 44 | Andes(nds32) Linux support. | 48 | Andes(nds32) Linux support. |
| 45 | 49 | ||
diff --git a/arch/nds32/Makefile b/arch/nds32/Makefile index 63f4f173e5f4..3509fac10491 100644 --- a/arch/nds32/Makefile +++ b/arch/nds32/Makefile | |||
| @@ -5,6 +5,10 @@ KBUILD_DEFCONFIG := defconfig | |||
| 5 | 5 | ||
| 6 | comma = , | 6 | comma = , |
| 7 | 7 | ||
| 8 | ifdef CONFIG_FUNCTION_TRACER | ||
| 9 | arch-y += -malways-save-lp -mno-relax | ||
| 10 | endif | ||
| 11 | |||
| 8 | KBUILD_CFLAGS += $(call cc-option, -mno-sched-prolog-epilog) | 12 | KBUILD_CFLAGS += $(call cc-option, -mno-sched-prolog-epilog) |
| 9 | KBUILD_CFLAGS += -mcmodel=large | 13 | KBUILD_CFLAGS += -mcmodel=large |
| 10 | 14 | ||
diff --git a/arch/nds32/include/asm/elf.h b/arch/nds32/include/asm/elf.h index 56c479058802..f5f9cf7e0544 100644 --- a/arch/nds32/include/asm/elf.h +++ b/arch/nds32/include/asm/elf.h | |||
| @@ -121,9 +121,9 @@ struct elf32_hdr; | |||
| 121 | */ | 121 | */ |
| 122 | #define ELF_CLASS ELFCLASS32 | 122 | #define ELF_CLASS ELFCLASS32 |
| 123 | #ifdef __NDS32_EB__ | 123 | #ifdef __NDS32_EB__ |
| 124 | #define ELF_DATA ELFDATA2MSB; | 124 | #define ELF_DATA ELFDATA2MSB |
| 125 | #else | 125 | #else |
| 126 | #define ELF_DATA ELFDATA2LSB; | 126 | #define ELF_DATA ELFDATA2LSB |
| 127 | #endif | 127 | #endif |
| 128 | #define ELF_ARCH EM_NDS32 | 128 | #define ELF_ARCH EM_NDS32 |
| 129 | #define USE_ELF_CORE_DUMP | 129 | #define USE_ELF_CORE_DUMP |
diff --git a/arch/nds32/include/asm/ftrace.h b/arch/nds32/include/asm/ftrace.h new file mode 100644 index 000000000000..2f96cc96aa35 --- /dev/null +++ b/arch/nds32/include/asm/ftrace.h | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | |||
| 3 | #ifndef __ASM_NDS32_FTRACE_H | ||
| 4 | #define __ASM_NDS32_FTRACE_H | ||
| 5 | |||
| 6 | #ifdef CONFIG_FUNCTION_TRACER | ||
| 7 | |||
| 8 | #define HAVE_FUNCTION_GRAPH_FP_TEST | ||
| 9 | |||
| 10 | #define MCOUNT_ADDR ((unsigned long)(_mcount)) | ||
| 11 | /* mcount call is composed of three instructions: | ||
| 12 | * sethi + ori + jral | ||
| 13 | */ | ||
| 14 | #define MCOUNT_INSN_SIZE 12 | ||
| 15 | |||
| 16 | extern void _mcount(unsigned long parent_ip); | ||
| 17 | |||
| 18 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
| 19 | |||
| 20 | #define FTRACE_ADDR ((unsigned long)_ftrace_caller) | ||
| 21 | |||
| 22 | #ifdef __NDS32_EL__ | ||
| 23 | #define INSN_NOP 0x09000040 | ||
| 24 | #define INSN_SIZE(insn) (((insn & 0x00000080) == 0) ? 4 : 2) | ||
| 25 | #define IS_SETHI(insn) ((insn & 0x000000fe) == 0x00000046) | ||
| 26 | #define ENDIAN_CONVERT(insn) be32_to_cpu(insn) | ||
| 27 | #else /* __NDS32_EB__ */ | ||
| 28 | #define INSN_NOP 0x40000009 | ||
| 29 | #define INSN_SIZE(insn) (((insn & 0x80000000) == 0) ? 4 : 2) | ||
| 30 | #define IS_SETHI(insn) ((insn & 0xfe000000) == 0x46000000) | ||
| 31 | #define ENDIAN_CONVERT(insn) (insn) | ||
| 32 | #endif | ||
| 33 | |||
| 34 | extern void _ftrace_caller(unsigned long parent_ip); | ||
| 35 | static inline unsigned long ftrace_call_adjust(unsigned long addr) | ||
| 36 | { | ||
| 37 | return addr; | ||
| 38 | } | ||
| 39 | struct dyn_arch_ftrace { | ||
| 40 | }; | ||
| 41 | |||
| 42 | #endif /* CONFIG_DYNAMIC_FTRACE */ | ||
| 43 | |||
| 44 | #endif /* CONFIG_FUNCTION_TRACER */ | ||
| 45 | |||
| 46 | #endif /* __ASM_NDS32_FTRACE_H */ | ||
diff --git a/arch/nds32/include/asm/nds32.h b/arch/nds32/include/asm/nds32.h index 19b19394a936..68c38151c3e4 100644 --- a/arch/nds32/include/asm/nds32.h +++ b/arch/nds32/include/asm/nds32.h | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #else | 17 | #else |
| 18 | #define FP_OFFSET (-2) | 18 | #define FP_OFFSET (-2) |
| 19 | #endif | 19 | #endif |
| 20 | #define LP_OFFSET (-1) | ||
| 20 | 21 | ||
| 21 | extern void __init early_trap_init(void); | 22 | extern void __init early_trap_init(void); |
| 22 | static inline void GIE_ENABLE(void) | 23 | static inline void GIE_ENABLE(void) |
diff --git a/arch/nds32/include/asm/uaccess.h b/arch/nds32/include/asm/uaccess.h index 18a009f3804d..362a32d9bd16 100644 --- a/arch/nds32/include/asm/uaccess.h +++ b/arch/nds32/include/asm/uaccess.h | |||
| @@ -38,7 +38,7 @@ struct exception_table_entry { | |||
| 38 | extern int fixup_exception(struct pt_regs *regs); | 38 | extern int fixup_exception(struct pt_regs *regs); |
| 39 | 39 | ||
| 40 | #define KERNEL_DS ((mm_segment_t) { ~0UL }) | 40 | #define KERNEL_DS ((mm_segment_t) { ~0UL }) |
| 41 | #define USER_DS ((mm_segment_t) {TASK_SIZE - 1}) | 41 | #define USER_DS ((mm_segment_t) {TASK_SIZE - 1}) |
| 42 | 42 | ||
| 43 | #define get_ds() (KERNEL_DS) | 43 | #define get_ds() (KERNEL_DS) |
| 44 | #define get_fs() (current_thread_info()->addr_limit) | 44 | #define get_fs() (current_thread_info()->addr_limit) |
| @@ -49,11 +49,11 @@ static inline void set_fs(mm_segment_t fs) | |||
| 49 | current_thread_info()->addr_limit = fs; | 49 | current_thread_info()->addr_limit = fs; |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | #define segment_eq(a, b) ((a) == (b)) | 52 | #define segment_eq(a, b) ((a) == (b)) |
| 53 | 53 | ||
| 54 | #define __range_ok(addr, size) (size <= get_fs() && addr <= (get_fs() -size)) | 54 | #define __range_ok(addr, size) (size <= get_fs() && addr <= (get_fs() -size)) |
| 55 | 55 | ||
| 56 | #define access_ok(type, addr, size) \ | 56 | #define access_ok(type, addr, size) \ |
| 57 | __range_ok((unsigned long)addr, (unsigned long)size) | 57 | __range_ok((unsigned long)addr, (unsigned long)size) |
| 58 | /* | 58 | /* |
| 59 | * Single-value transfer routines. They automatically use the right | 59 | * Single-value transfer routines. They automatically use the right |
| @@ -75,70 +75,73 @@ static inline void set_fs(mm_segment_t fs) | |||
| 75 | * versions are void (ie, don't return a value as such). | 75 | * versions are void (ie, don't return a value as such). |
| 76 | */ | 76 | */ |
| 77 | 77 | ||
| 78 | #define get_user(x,p) \ | 78 | #define get_user __get_user \ |
| 79 | ({ \ | 79 | |
| 80 | long __e = -EFAULT; \ | 80 | #define __get_user(x, ptr) \ |
| 81 | if(likely(access_ok(VERIFY_READ, p, sizeof(*p)))) { \ | ||
| 82 | __e = __get_user(x,p); \ | ||
| 83 | } else \ | ||
| 84 | x = 0; \ | ||
| 85 | __e; \ | ||
| 86 | }) | ||
| 87 | #define __get_user(x,ptr) \ | ||
| 88 | ({ \ | 81 | ({ \ |
| 89 | long __gu_err = 0; \ | 82 | long __gu_err = 0; \ |
| 90 | __get_user_err((x),(ptr),__gu_err); \ | 83 | __get_user_check((x), (ptr), __gu_err); \ |
| 91 | __gu_err; \ | 84 | __gu_err; \ |
| 92 | }) | 85 | }) |
| 93 | 86 | ||
| 94 | #define __get_user_error(x,ptr,err) \ | 87 | #define __get_user_error(x, ptr, err) \ |
| 95 | ({ \ | 88 | ({ \ |
| 96 | __get_user_err((x),(ptr),err); \ | 89 | __get_user_check((x), (ptr), (err)); \ |
| 97 | (void) 0; \ | 90 | (void)0; \ |
| 98 | }) | 91 | }) |
| 99 | 92 | ||
| 100 | #define __get_user_err(x,ptr,err) \ | 93 | #define __get_user_check(x, ptr, err) \ |
| 94 | ({ \ | ||
| 95 | const __typeof__(*(ptr)) __user *__p = (ptr); \ | ||
| 96 | might_fault(); \ | ||
| 97 | if (access_ok(VERIFY_READ, __p, sizeof(*__p))) { \ | ||
| 98 | __get_user_err((x), __p, (err)); \ | ||
| 99 | } else { \ | ||
| 100 | (x) = 0; (err) = -EFAULT; \ | ||
| 101 | } \ | ||
| 102 | }) | ||
| 103 | |||
| 104 | #define __get_user_err(x, ptr, err) \ | ||
| 101 | do { \ | ||
