diff options
Diffstat (limited to 'arch/unicore32')
-rw-r--r-- | arch/unicore32/Kconfig | 7 | ||||
-rw-r--r-- | arch/unicore32/include/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/unicore32/include/asm/bug.h | 5 | ||||
-rw-r--r-- | arch/unicore32/include/asm/cmpxchg.h | 2 | ||||
-rw-r--r-- | arch/unicore32/include/asm/kvm_para.h | 1 | ||||
-rw-r--r-- | arch/unicore32/include/asm/processor.h | 5 | ||||
-rw-r--r-- | arch/unicore32/include/asm/ptrace.h | 76 | ||||
-rw-r--r-- | arch/unicore32/include/uapi/asm/Kbuild | 7 | ||||
-rw-r--r-- | arch/unicore32/include/uapi/asm/byteorder.h (renamed from arch/unicore32/include/asm/byteorder.h) | 0 | ||||
-rw-r--r-- | arch/unicore32/include/uapi/asm/ptrace.h | 90 | ||||
-rw-r--r-- | arch/unicore32/include/uapi/asm/sigcontext.h (renamed from arch/unicore32/include/asm/sigcontext.h) | 0 | ||||
-rw-r--r-- | arch/unicore32/include/uapi/asm/unistd.h (renamed from arch/unicore32/include/asm/unistd.h) | 1 | ||||
-rw-r--r-- | arch/unicore32/kernel/entry.S | 20 | ||||
-rw-r--r-- | arch/unicore32/kernel/process.c | 58 | ||||
-rw-r--r-- | arch/unicore32/kernel/setup.h | 6 | ||||
-rw-r--r-- | arch/unicore32/kernel/sys.c | 63 | ||||
-rw-r--r-- | arch/unicore32/mm/fault.c | 37 |
17 files changed, 160 insertions, 219 deletions
diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index e5c5473e69ce..c4fbb21e802b 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig | |||
@@ -16,6 +16,8 @@ config UNICORE32 | |||
16 | select ARCH_WANT_FRAME_POINTERS | 16 | select ARCH_WANT_FRAME_POINTERS |
17 | select GENERIC_IOMAP | 17 | select GENERIC_IOMAP |
18 | select MODULES_USE_ELF_REL | 18 | select MODULES_USE_ELF_REL |
19 | select GENERIC_KERNEL_THREAD | ||
20 | select GENERIC_KERNEL_EXECVE | ||
19 | help | 21 | help |
20 | UniCore-32 is 32-bit Instruction Set Architecture, | 22 | UniCore-32 is 32-bit Instruction Set Architecture, |
21 | including a series of low-power-consumption RISC chip | 23 | including a series of low-power-consumption RISC chip |
@@ -64,6 +66,9 @@ config GENERIC_CALIBRATE_DELAY | |||
64 | config ARCH_MAY_HAVE_PC_FDC | 66 | config ARCH_MAY_HAVE_PC_FDC |
65 | bool | 67 | bool |
66 | 68 | ||
69 | config ZONE_DMA | ||
70 | def_bool y | ||
71 | |||
67 | config NEED_DMA_MAP_STATE | 72 | config NEED_DMA_MAP_STATE |
68 | def_bool y | 73 | def_bool y |
69 | 74 | ||
@@ -216,7 +221,7 @@ config PUV3_GPIO | |||
216 | bool | 221 | bool |
217 | depends on !ARCH_FPGA | 222 | depends on !ARCH_FPGA |
218 | select GENERIC_GPIO | 223 | select GENERIC_GPIO |
219 | select GPIO_SYSFS if EXPERIMENTAL | 224 | select GPIO_SYSFS |
220 | default y | 225 | default y |
221 | 226 | ||
222 | if PUV3_NB0916 | 227 | if PUV3_NB0916 |
diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild index 7be503e45695..89d8b6c4e39a 100644 --- a/arch/unicore32/include/asm/Kbuild +++ b/arch/unicore32/include/asm/Kbuild | |||
@@ -1,4 +1,3 @@ | |||
1 | include include/asm-generic/Kbuild.asm | ||
2 | 1 | ||
3 | generic-y += atomic.h | 2 | generic-y += atomic.h |
4 | generic-y += auxvec.h | 3 | generic-y += auxvec.h |
diff --git a/arch/unicore32/include/asm/bug.h b/arch/unicore32/include/asm/bug.h index b1ff8cadb086..93a56f3e2344 100644 --- a/arch/unicore32/include/asm/bug.h +++ b/arch/unicore32/include/asm/bug.h | |||
@@ -19,9 +19,4 @@ extern void die(const char *msg, struct pt_regs *regs, int err); | |||
19 | extern void uc32_notify_die(const char *str, struct pt_regs *regs, | 19 | extern void uc32_notify_die(const char *str, struct pt_regs *regs, |
20 | struct siginfo *info, unsigned long err, unsigned long trap); | 20 | struct siginfo *info, unsigned long err, unsigned long trap); |
21 | 21 | ||
22 | extern asmlinkage void __backtrace(void); | ||
23 | extern asmlinkage void c_backtrace(unsigned long fp, int pmode); | ||
24 | |||
25 | extern void __show_regs(struct pt_regs *); | ||
26 | |||
27 | #endif /* __UNICORE_BUG_H__ */ | 22 | #endif /* __UNICORE_BUG_H__ */ |
diff --git a/arch/unicore32/include/asm/cmpxchg.h b/arch/unicore32/include/asm/cmpxchg.h index df4d5acfd19f..8e797ad4fa24 100644 --- a/arch/unicore32/include/asm/cmpxchg.h +++ b/arch/unicore32/include/asm/cmpxchg.h | |||
@@ -35,7 +35,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, | |||
35 | : "memory", "cc"); | 35 | : "memory", "cc"); |
36 | break; | 36 | break; |
37 | default: | 37 | default: |
38 | ret = __xchg_bad_pointer(); | 38 | __xchg_bad_pointer(); |
39 | } | 39 | } |
40 | 40 | ||
41 | return ret; | 41 | return ret; |
diff --git a/arch/unicore32/include/asm/kvm_para.h b/arch/unicore32/include/asm/kvm_para.h deleted file mode 100644 index 14fab8f0b957..000000000000 --- a/arch/unicore32/include/asm/kvm_para.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include <asm-generic/kvm_para.h> | ||
diff --git a/arch/unicore32/include/asm/processor.h b/arch/unicore32/include/asm/processor.h index 14382cb09657..4eaa42167667 100644 --- a/arch/unicore32/include/asm/processor.h +++ b/arch/unicore32/include/asm/processor.h | |||
@@ -72,11 +72,6 @@ unsigned long get_wchan(struct task_struct *p); | |||
72 | 72 | ||
73 | #define cpu_relax() barrier() | 73 | #define cpu_relax() barrier() |
74 | 74 | ||
75 | /* | ||
76 | * Create a new kernel thread | ||
77 | */ | ||
78 | extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); | ||
79 | |||
80 | #define task_pt_regs(p) \ | 75 | #define task_pt_regs(p) \ |
81 | ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) | 76 | ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) |
82 | 77 | ||
diff --git a/arch/unicore32/include/asm/ptrace.h b/arch/unicore32/include/asm/ptrace.h index b9caf9b0997b..726749dab52f 100644 --- a/arch/unicore32/include/asm/ptrace.h +++ b/arch/unicore32/include/asm/ptrace.h | |||
@@ -12,80 +12,10 @@ | |||
12 | #ifndef __UNICORE_PTRACE_H__ | 12 | #ifndef __UNICORE_PTRACE_H__ |
13 | #define __UNICORE_PTRACE_H__ | 13 | #define __UNICORE_PTRACE_H__ |
14 | 14 | ||
15 | #define PTRACE_GET_THREAD_AREA 22 | 15 | #include <uapi/asm/ptrace.h> |
16 | |||
17 | /* | ||
18 | * PSR bits | ||
19 | */ | ||
20 | #define USER_MODE 0x00000010 | ||
21 | #define REAL_MODE 0x00000011 | ||
22 | #define INTR_MODE 0x00000012 | ||
23 | #define PRIV_MODE 0x00000013 | ||
24 | #define ABRT_MODE 0x00000017 | ||
25 | #define EXTN_MODE 0x0000001b | ||
26 | #define SUSR_MODE 0x0000001f | ||
27 | #define MODE_MASK 0x0000001f | ||
28 | #define PSR_R_BIT 0x00000040 | ||
29 | #define PSR_I_BIT 0x00000080 | ||
30 | #define PSR_V_BIT 0x10000000 | ||
31 | #define PSR_C_BIT 0x20000000 | ||
32 | #define PSR_Z_BIT 0x40000000 | ||
33 | #define PSR_S_BIT 0x80000000 | ||
34 | |||
35 | /* | ||
36 | * Groups of PSR bits | ||
37 | */ | ||
38 | #define PSR_f 0xff000000 /* Flags */ | ||
39 | #define PSR_c 0x000000ff /* Control */ | ||
40 | 16 | ||
41 | #ifndef __ASSEMBLY__ | 17 | #ifndef __ASSEMBLY__ |
42 | 18 | ||
43 | /* | ||
44 | * This struct defines the way the registers are stored on the | ||
45 | * stack during a system call. Note that sizeof(struct pt_regs) | ||
46 | * has to be a multiple of 8. | ||
47 | */ | ||
48 | struct pt_regs { | ||
49 | unsigned long uregs[34]; | ||
50 | }; | ||
51 | |||
52 | #define UCreg_asr uregs[32] | ||
53 | #define UCreg_pc uregs[31] | ||
54 | #define UCreg_lr uregs[30] | ||
55 | #define UCreg_sp uregs[29] | ||
56 | #define UCreg_ip uregs[28] | ||
57 | #define UCreg_fp uregs[27] | ||
58 | #define UCreg_26 uregs[26] | ||
59 | #define UCreg_25 uregs[25] | ||
60 | #define UCreg_24 uregs[24] | ||
61 | #define UCreg_23 uregs[23] | ||
62 | #define UCreg_22 uregs[22] | ||
63 | #define UCreg_21 uregs[21] | ||
64 | #define UCreg_20 uregs[20] | ||
65 | #define UCreg_19 uregs[19] | ||
66 | #define UCreg_18 uregs[18] | ||
67 | #define UCreg_17 uregs[17] | ||
68 | #define UCreg_16 uregs[16] | ||
69 | #define UCreg_15 uregs[15] | ||
70 | #define UCreg_14 uregs[14] | ||
71 | #define UCreg_13 uregs[13] | ||
72 | #define UCreg_12 uregs[12] | ||
73 | #define UCreg_11 uregs[11] | ||
74 | #define UCreg_10 uregs[10] | ||
75 | #define UCreg_09 uregs[9] | ||
76 | #define UCreg_08 uregs[8] | ||
77 | #define UCreg_07 uregs[7] | ||
78 | #define UCreg_06 uregs[6] | ||
79 | #define UCreg_05 uregs[5] | ||
80 | #define UCreg_04 uregs[4] | ||
81 | #define UCreg_03 uregs[3] | ||
82 | #define UCreg_02 uregs[2] | ||
83 | #define UCreg_01 uregs[1] | ||
84 | #define UCreg_00 uregs[0] | ||
85 | #define UCreg_ORIG_00 uregs[33] | ||
86 | |||
87 | #ifdef __KERNEL__ | ||
88 | |||
89 | #define user_mode(regs) \ | 19 | #define user_mode(regs) \ |
90 | (processor_mode(regs) == USER_MODE) | 20 | (processor_mode(regs) == USER_MODE) |
91 | 21 | ||
@@ -125,9 +55,5 @@ static inline int valid_user_regs(struct pt_regs *regs) | |||
125 | 55 | ||
126 | #define instruction_pointer(regs) ((regs)->UCreg_pc) | 56 | #define instruction_pointer(regs) ((regs)->UCreg_pc) |
127 | 57 | ||
128 | #endif /* __KERNEL__ */ | ||
129 | |||
130 | #endif /* __ASSEMBLY__ */ | 58 | #endif /* __ASSEMBLY__ */ |
131 | |||
132 | #endif | 59 | #endif |
133 | |||
diff --git a/arch/unicore32/include/uapi/asm/Kbuild b/arch/unicore32/include/uapi/asm/Kbuild index baebb3da1d44..0514d7ad6855 100644 --- a/arch/unicore32/include/uapi/asm/Kbuild +++ b/arch/unicore32/include/uapi/asm/Kbuild | |||
@@ -1,3 +1,10 @@ | |||
1 | # UAPI Header export list | 1 | # UAPI Header export list |
2 | include include/uapi/asm-generic/Kbuild.asm | 2 | include include/uapi/asm-generic/Kbuild.asm |
3 | 3 | ||
4 | header-y += byteorder.h | ||
5 | header-y += kvm_para.h | ||
6 | header-y += ptrace.h | ||
7 | header-y += sigcontext.h | ||
8 | header-y += unistd.h | ||
9 | |||
10 | generic-y += kvm_para.h | ||
diff --git a/arch/unicore32/include/asm/byteorder.h b/arch/unicore32/include/uapi/asm/byteorder.h index ebe1b3fef3e3..ebe1b3fef3e3 100644 --- a/arch/unicore32/include/asm/byteorder.h +++ b/arch/unicore32/include/uapi/asm/byteorder.h | |||
diff --git a/arch/unicore32/include/uapi/asm/ptrace.h b/arch/unicore32/include/uapi/asm/ptrace.h new file mode 100644 index 000000000000..187aa2e98a53 --- /dev/null +++ b/arch/unicore32/include/uapi/asm/ptrace.h | |||
@@ -0,0 +1,90 @@ | |||
1 | /* | ||
2 | * linux/arch/unicore32/include/asm/ptrace.h | ||
3 | * | ||
4 | * Code specific to PKUnity SoC and UniCore ISA | ||
5 | * | ||
6 | * Copyright (C) 2001-2010 GUAN Xue-tao | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | #ifndef _UAPI__UNICORE_PTRACE_H__ | ||
13 | #define _UAPI__UNICORE_PTRACE_H__ | ||
14 | |||
15 | #define PTRACE_GET_THREAD_AREA 22 | ||
16 | |||
17 | /* | ||
18 | * PSR bits | ||
19 | */ | ||
20 | #define USER_MODE 0x00000010 | ||
21 | #define REAL_MODE 0x00000011 | ||
22 | #define INTR_MODE 0x00000012 | ||
23 | #define PRIV_MODE 0x00000013 | ||
24 | #define ABRT_MODE 0x00000017 | ||
25 | #define EXTN_MODE 0x0000001b | ||
26 | #define SUSR_MODE 0x0000001f | ||
27 | #define MODE_MASK 0x0000001f | ||
28 | #define PSR_R_BIT 0x00000040 | ||
29 | #define PSR_I_BIT 0x00000080 | ||
30 | #define PSR_V_BIT 0x10000000 | ||
31 | #define PSR_C_BIT 0x20000000 | ||
32 | #define PSR_Z_BIT 0x40000000 | ||
33 | #define PSR_S_BIT 0x80000000 | ||
34 | |||
35 | /* | ||
36 | * Groups of PSR bits | ||
37 | */ | ||
38 | #define PSR_f 0xff000000 /* Flags */ | ||
39 | #define PSR_c 0x000000ff /* Control */ | ||
40 | |||
41 | #ifndef __ASSEMBLY__ | ||
42 | |||
43 | /* | ||
44 | * This struct defines the way the registers are stored on the | ||
45 | * stack during a system call. Note that sizeof(struct pt_regs) | ||
46 | * has to be a multiple of 8. | ||
47 | */ | ||
48 | struct pt_regs { | ||
49 | unsigned long uregs[34]; | ||
50 | }; | ||
51 | |||
52 | #define UCreg_asr uregs[32] | ||
53 | #define UCreg_pc uregs[31] | ||
54 | #define UCreg_lr uregs[30] | ||
55 | #define UCreg_sp uregs[29] | ||
56 | #define UCreg_ip uregs[28] | ||
57 | #define UCreg_fp uregs[27] | ||
58 | #define UCreg_26 uregs[26] | ||
59 | #define UCreg_25 uregs[25] | ||
60 | #define UCreg_24 uregs[24] | ||
61 | #define UCreg_23 uregs[23] | ||
62 | #define UCreg_22 uregs[22] | ||
63 | #define UCreg_21 uregs[21] | ||
64 | #define UCreg_20 uregs[20] | ||
65 | #define UCreg_19 uregs[19] | ||
66 | #define UCreg_18 uregs[18] | ||
67 | #define UCreg_17 uregs[17] | ||
68 | #define UCreg_16 uregs[16] | ||
69 | #define UCreg_15 uregs[15] | ||
70 | #define UCreg_14 uregs[14] | ||
71 | #define UCreg_13 uregs[13] | ||
72 | #define UCreg_12 uregs[12] | ||
73 | #define UCreg_11 uregs[11] | ||
74 | #define UCreg_10 uregs[10] | ||
75 | #define UCreg_09 uregs[9] | ||
76 | #define UCreg_08 uregs[8] | ||
77 | #define UCreg_07 uregs[7] | ||
78 | #define UCreg_06 uregs[6] | ||
79 | #define UCreg_05 uregs[5] | ||
80 | #define UCreg_04 uregs[4] | ||
81 | #define UCreg_03 uregs[3] | ||
82 | #define UCreg_02 uregs[2] | ||
83 | #define UCreg_01 uregs[1] | ||
84 | #define UCreg_00 uregs[0] | ||
85 | #define UCreg_ORIG_00 uregs[33] | ||
86 | |||
87 | |||
88 | #endif /* __ASSEMBLY__ */ | ||
89 | |||
90 | #endif /* _UAPI__UNICORE_PTRACE_H__ */ | ||
diff --git a/arch/unicore32/include/asm/sigcontext.h b/arch/unicore32/include/uapi/asm/sigcontext.h index 6a2d7671c052..6a2d7671c052 100644 --- a/arch/unicore32/include/asm/sigcontext.h +++ b/arch/unicore32/include/uapi/asm/sigcontext.h | |||
diff --git a/arch/unicore32/include/asm/unistd.h b/arch/unicore32/include/uapi/asm/unistd.h index 2abcf61c615d..d18a3be89b38 100644 --- a/arch/unicore32/include/asm/unistd.h +++ b/arch/unicore32/include/uapi/asm/unistd.h | |||
@@ -12,3 +12,4 @@ | |||
12 | 12 | ||
13 | /* Use the standard ABI for syscalls. */ | 13 | /* Use the standard ABI for syscalls. */ |
14 | #include <asm-generic/unistd.h> | 14 | #include <asm-generic/unistd.h> |
15 | #define __ARCH_WANT_SYS_EXECVE | ||
diff --git a/arch/unicore32/kernel/entry.S b/arch/unicore32/kernel/entry.S index dcb87ab19ddd..7049350c790f 100644 --- a/arch/unicore32/kernel/entry.S +++ b/arch/unicore32/kernel/entry.S | |||
@@ -573,17 +573,16 @@ ENDPROC(ret_to_user) | |||
573 | */ | 573 | */ |
574 | ENTRY(ret_from_fork) | 574 | ENTRY(ret_from_fork) |
575 | b.l schedule_tail | 575 | b.l schedule_tail |
576 | get_thread_info tsk | ||
577 | ldw r1, [tsk+], #TI_FLAGS @ check for syscall tracing | ||
578 | mov why, #1 | ||
579 | cand.a r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? | ||
580 | beq ret_slow_syscall | ||
581 | mov r1, sp | ||
582 | mov r0, #1 @ trace exit [IP = 1] | ||
583 | b.l syscall_trace | ||
584 | b ret_slow_syscall | 576 | b ret_slow_syscall |
585 | ENDPROC(ret_from_fork) | 577 | ENDPROC(ret_from_fork) |
586 | 578 | ||
579 | ENTRY(ret_from_kernel_thread) | ||
580 | b.l schedule_tail | ||
581 | mov r0, r5 | ||
582 | adr lr, ret_slow_syscall | ||
583 | mov pc, r4 | ||
584 | ENDPROC(ret_from_kernel_thread) | ||
585 | |||
587 | /*============================================================================= | 586 | /*============================================================================= |
588 | * SWI handler | 587 | * SWI handler |
589 | *----------------------------------------------------------------------------- | 588 | *----------------------------------------------------------------------------- |
@@ -669,11 +668,6 @@ __cr_alignment: | |||
669 | #endif | 668 | #endif |
670 | .ltorg | 669 | .ltorg |
671 | 670 | ||
672 | ENTRY(sys_execve) | ||
673 | add r3, sp, #S_OFF | ||
674 | b __sys_execve | ||
675 | ENDPROC(sys_execve) | ||
676 | |||
677 | ENTRY(sys_clone) | 671 | ENTRY(sys_clone) |
678 | add ip, sp, #S_OFF | 672 | add ip, sp, #S_OFF |
679 | stw ip, [sp+], #4 | 673 | stw ip, [sp+], #4 |
diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c index b008586dad75..a8fe265ce2c0 100644 --- a/arch/unicore32/kernel/process.c +++ b/arch/unicore32/kernel/process.c | |||
@@ -258,6 +258,7 @@ void release_thread(struct task_struct *dead_task) | |||
258 | } | 258 | } |
259 | 259 | ||
260 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); | 260 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); |
261 | asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread"); | ||
261 | 262 | ||
262 | int | 263 | int |
263 | copy_thread(unsigned long clone_flags, unsigned long stack_start, | 264 | copy_thread(unsigned long clone_flags, unsigned long stack_start, |
@@ -266,17 +267,22 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start, | |||
266 | struct thread_info *thread = task_thread_info(p); | 267 | struct thread_info *thread = task_thread_info(p); |
267 | struct pt_regs *childregs = task_pt_regs(p); | 268 | struct pt_regs *childregs = task_pt_regs(p); |
268 | 269 | ||
269 | *childregs = *regs; | ||
270 | childregs->UCreg_00 = 0; | ||
271 | childregs->UCreg_sp = stack_start; | ||
272 | |||
273 | memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); | 270 | memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); |
274 | thread->cpu_context.sp = (unsigned long)childregs; | 271 | thread->cpu_context.sp = (unsigned long)childregs; |
275 | thread->cpu_context.pc = (unsigned long)ret_from_fork; | 272 | if (unlikely(!regs)) { |
276 | 273 | thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread; | |
277 | if (clone_flags & CLONE_SETTLS) | 274 | thread->cpu_context.r4 = stack_start; |
278 | childregs->UCreg_16 = regs->UCreg_03; | 275 | thread->cpu_context.r5 = stk_sz; |
276 | memset(childregs, 0, sizeof(struct pt_regs)); | ||
277 | } else { | ||
278 | thread->cpu_context.pc = (unsigned long)ret_from_fork; | ||
279 | *childregs = *regs; | ||
280 | childregs->UCreg_00 = 0; | ||
281 | childregs->UCreg_sp = stack_start; | ||
279 | 282 | ||
283 | if (clone_flags & CLONE_SETTLS) | ||
284 | childregs->UCreg_16 = regs->UCreg_03; | ||
285 | } | ||
280 | return 0; | 286 | return 0; |
281 | } | 287 | } |
282 | 288 | ||
@@ -305,42 +311,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fp) | |||
305 | } | 311 | } |
306 | EXPORT_SYMBOL(dump_fpu); | 312 | EXPORT_SYMBOL(dump_fpu); |
307 | 313 | ||
308 | /* | ||
309 | * Shuffle the argument into the correct register before calling the | ||
310 | * thread function. r1 is the thread argument, r2 is the pointer to | ||
311 | * the thread function, and r3 points to the exit function. | ||
312 | */ | ||
313 | asm(".pushsection .text\n" | ||
314 | " .align\n" | ||
315 | " .type kernel_thread_helper, #function\n" | ||
316 | "kernel_thread_helper:\n" | ||
317 | " mov.a asr, r7\n" | ||
318 | " mov r0, r4\n" | ||
319 | " mov lr, r6\n" | ||
320 | " mov pc, r5\n" | ||
321 | " .size kernel_thread_helper, . - kernel_thread_helper\n" | ||
322 | " .popsection"); | ||
323 | |||
324 | /* | ||
325 | * Create a kernel thread. | ||
326 | */ | ||
327 | pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | ||
328 | { | ||
329 | struct pt_regs regs; | ||
330 | |||
331 | memset(®s, 0, sizeof(regs)); | ||
332 | |||
333 | regs.UCreg_04 = (unsigned long)arg; | ||
334 | regs.UCreg_05 = (unsigned long)fn; | ||
335 | regs.UCreg_06 = (unsigned long)do_exit; | ||
336 | regs.UCreg_07 = PRIV_MODE; | ||
337 | regs.UCreg_pc = (unsigned long)kernel_thread_helper; | ||
338 | regs.UCreg_asr = regs.UCreg_07 | PSR_I_BIT; | ||
339 | |||
340 | return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); | ||
341 | } | ||
342 | EXPORT_SYMBOL(kernel_thread); | ||
343 | |||
344 | unsigned long get_wchan(struct task_struct *p) | 314 | unsigned long get_wchan(struct task_struct *p) |
345 | { | 315 | { |
346 | struct stackframe frame; | 316 | struct stackframe frame; |
diff --git a/arch/unicore32/kernel/setup.h b/arch/unicore32/kernel/setup.h index f23955028a18..30f749da8f73 100644 --- a/arch/unicore32/kernel/setup.h +++ b/arch/unicore32/kernel/setup.h | |||
@@ -30,4 +30,10 @@ extern char __vectors_start[], __vectors_end[]; | |||
30 | extern void kernel_thread_helper(void); | 30 | extern void kernel_thread_helper(void); |
31 | 31 | ||
32 | extern void __init early_signal_init(void); | 32 | extern void __init early_signal_init(void); |
33 | |||
34 | extern asmlinkage void __backtrace(void); | ||
35 | extern asmlinkage void c_backtrace(unsigned long fp, int pmode); | ||
36 | |||
37 | extern void __show_regs(struct pt_regs *); | ||
38 | |||
33 | #endif | 39 | #endif |
diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c index fabdee96110b..9680134b31f0 100644 --- a/arch/unicore32/kernel/sys.c +++ b/arch/unicore32/kernel/sys.c | |||
@@ -42,69 +42,6 @@ asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp, | |||
42 | parent_tid, child_tid); | 42 | parent_tid, child_tid); |
43 | } | 43 | } |
44 | 44 | ||
45 | /* sys_execve() executes a new program. | ||
46 | * This is called indirectly via a small wrapper | ||
47 | */ | ||
48 | asmlinkage long __sys_execve(const char __user *filename, | ||
49 | const char __user *const __user *argv, | ||
50 | const char __user *const __user *envp, | ||
51 | struct pt_regs *regs) | ||
52 | { | ||
53 | int error; | ||
54 | struct filename *fn; | ||
55 | |||
56 | fn = getname(filename); | ||
57 | error = PTR_ERR(fn); | ||
58 | if (IS_ERR(fn)) | ||
59 | goto out; | ||
60 | error = do_execve(fn->name, argv, envp, regs); | ||
61 | putname(fn); | ||
62 | out: | ||
63 | return error; | ||
64 | } | ||
65 | |||
66 | int kernel_execve(const char *filename, | ||
67 | const char *const argv[], | ||
68 | const char *const envp[]) | ||
69 | { | ||
70 | struct pt_regs regs; | ||
71 | int ret; | ||
72 | |||
73 | memset(®s, 0, sizeof(struct pt_regs)); | ||
74 | ret = do_execve(filename, | ||
75 | (const char __user *const __user *)argv, | ||
76 | (const char __user *const __user *)envp, ®s); | ||
77 | if (ret < 0) | ||
78 | goto out; | ||
79 | |||
80 | /* | ||
81 | * Save argc to the register structure for userspace. | ||
82 | */ | ||
83 | regs.UCreg_00 = ret; | ||
84 | |||
85 | /* | ||
86 | * We were successful. We won't be returning to our caller, but | ||
87 | * instead to user space by manipulating the kernel stack. | ||
88 | */ | ||
89 | asm("add r0, %0, %1\n\t" | ||
90 | "mov r1, %2\n\t" | ||
91 | "mov r2, %3\n\t" | ||
92 | "mov r22, #0\n\t" /* not a syscall */ | ||
93 | "mov r23, %0\n\t" /* thread structure */ | ||
94 | "b.l memmove\n\t" /* copy regs to top of stack */ | ||
95 | "mov sp, r0\n\t" /* reposition stack pointer */ | ||
96 | "b ret_to_user" | ||
97 | : | ||
98 | : "r" (current_thread_info()), | ||
99 | "Ir" (THREAD_START_SP - sizeof(regs)), | ||
100 | "r" (®s), | ||
101 | "Ir" (sizeof(regs)) | ||
102 | : "r0", "r1", "r2", "r3", "ip", "lr", "memory"); | ||
103 | |||
104 | out: | ||
105 | return ret; | ||
106 | } | ||
107 | |||
108 | /* Note: used by the compat code even in 64-bit Linux. */ | 45 | /* Note: used by the compat code even in 64-bit Linux. */ |
109 | SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, | 46 | SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, |
110 | unsigned long, prot, unsigned long, flags, | 47 | unsigned long, prot, unsigned long, flags, |
diff --git a/arch/unicore32/mm/fault.c b/arch/unicore32/mm/fault.c index 2eeb9c04cab0..f9b5c10bccee 100644 --- a/arch/unicore32/mm/fault.c +++ b/arch/unicore32/mm/fault.c | |||
@@ -168,7 +168,7 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma) | |||
168 | } | 168 | } |
169 | 169 | ||
170 | static int __do_pf(struct mm_struct *mm, unsigned long addr, unsigned int fsr, | 170 | static int __do_pf(struct mm_struct *mm, unsigned long addr, unsigned int fsr, |
171 | struct task_struct *tsk) | 171 | unsigned int flags, struct task_struct *tsk) |
172 | { | 172 | { |
173 | struct vm_area_struct *vma; | 173 | struct vm_area_struct *vma; |
174 | int fault; | 174 | int fault; |
@@ -194,14 +194,7 @@ good_area: | |||
194 | * If for any reason at all we couldn't handle the fault, make | 194 | * If for any reason at all we couldn't handle the fault, make |
195 | * sure we exit gracefully rather than endlessly redo the fault. | 195 | * sure we exit gracefully rather than endlessly redo the fault. |
196 | */ | 196 | */ |
197 | fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, | 197 | fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, flags); |
198 | (!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0); | ||
199 | if (unlikely(fault & VM_FAULT_ERROR)) | ||
200 | return fault; | ||
201 | if (fault & VM_FAULT_MAJOR) | ||
202 | tsk->maj_flt++; | ||
203 | else | ||
204 | tsk->min_flt++; | ||
205 | return fault; | 198 | return fault; |
206 | 199 | ||
207 | check_stack: | 200 | check_stack: |
@@ -216,6 +209,8 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
216 | struct task_struct *tsk; | 209 | struct task_struct *tsk; |
217 | struct mm_struct *mm; | 210 | struct mm_struct *mm; |
218 | int fault, sig, code; | 211 | int fault, sig, code; |
212 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | | ||
213 | ((!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0); | ||
219 | 214 | ||
220 | tsk = current; | 215 | tsk = current; |
221 | mm = tsk->mm; | 216 | mm = tsk->mm; |
@@ -236,6 +231,7 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
236 | if (!user_mode(regs) | 231 | if (!user_mode(regs) |
237 | && !search_exception_tables(regs->UCreg_pc)) | 232 | && !search_exception_tables(regs->UCreg_pc)) |
238 | goto no_context; | 233 | goto no_context; |
234 | retry: | ||
239 | down_read(&mm->mmap_sem); | 235 | down_read(&mm->mmap_sem); |
240 | } else { | 236 | } else { |
241 | /* | 237 | /* |
@@ -251,7 +247,28 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
251 | #endif | 247 | #endif |
252 | } | 248 | } |
253 | 249 | ||
254 | fault = __do_pf(mm, addr, fsr, tsk); | 250 | fault = __do_pf(mm, addr, fsr, flags, tsk); |
251 | |||
252 | /* If we need to retry but a fatal signal is pending, handle the | ||
253 | * signal first. We do not need to release the mmap_sem because | ||
254 | * it would already be released in __lock_page_or_retry in | ||
255 | * mm/filemap.c. */ | ||
256 | if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) | ||
257 | return 0; | ||
258 | |||
259 | if (!(fault & VM_FAULT_ERROR) && (flags & FAULT_FLAG_ALLOW_RETRY)) { | ||
260 | if (fault & VM_FAULT_MAJOR) | ||
261 | tsk->maj_flt++; | ||
262 | else | ||
263 | tsk->min_flt++; | ||
264 | if (fault & VM_FAULT_RETRY) { | ||
265 | /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk | ||
266 | * of starvation. */ | ||
267 | flags &= ~FAULT_FLAG_ALLOW_RETRY; | ||
268 | goto retry; | ||
269 | } | ||
270 | } | ||
271 | |||
255 | up_read(&mm->mmap_sem); | 272 | up_read(&mm->mmap_sem); |
256 | 273 | ||
257 | /* | 274 | /* |