aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/nds32/Kconfig4
-rw-r--r--arch/nds32/Makefile4
-rw-r--r--arch/nds32/include/asm/elf.h4
-rw-r--r--arch/nds32/include/asm/ftrace.h46
-rw-r--r--arch/nds32/include/asm/nds32.h1
-rw-r--r--arch/nds32/include/asm/uaccess.h229
-rw-r--r--arch/nds32/kernel/Makefile6
-rw-r--r--arch/nds32/kernel/atl2c.c3
-rw-r--r--arch/nds32/kernel/ex-entry.S2
-rw-r--r--arch/nds32/kernel/ex-exit.S4
-rw-r--r--arch/nds32/kernel/ftrace.c309
-rw-r--r--arch/nds32/kernel/module.c4
-rw-r--r--arch/nds32/kernel/stacktrace.c6
-rw-r--r--arch/nds32/kernel/traps.c42
-rw-r--r--arch/nds32/kernel/vmlinux.lds.S12
-rwxr-xr-xscripts/recordmcount.pl3
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
6comma = , 6comma = ,
7 7
8ifdef CONFIG_FUNCTION_TRACER
9arch-y += -malways-save-lp -mno-relax
10endif
11
8KBUILD_CFLAGS += $(call cc-option, -mno-sched-prolog-epilog) 12KBUILD_CFLAGS += $(call cc-option, -mno-sched-prolog-epilog)
9KBUILD_CFLAGS += -mcmodel=large 13KBUILD_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
16extern 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
34extern void _ftrace_caller(unsigned long parent_ip);
35static inline unsigned long ftrace_call_adjust(unsigned long addr)
36{
37 return addr;
38}
39struct 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
21extern void __init early_trap_init(void); 22extern void __init early_trap_init(void);
22static inline void GIE_ENABLE(void) 23static 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 {
38extern int fixup_exception(struct pt_regs *regs); 38extern 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) \
101do { \