14
14
#include <linux/init.h>
15
15
#include <linux/kernel.h>
16
16
#include <linux/errno.h>
17
+ #include <linux/entry-common.h>
17
18
#include <linux/sched.h>
18
19
#include <linux/sched/debug.h>
19
20
#include <linux/sched/task.h>
33
34
#include <linux/prctl.h>
34
35
#include <linux/nmi.h>
35
36
37
+ #include <asm/asm-prototypes.h>
36
38
#include <asm/asm.h>
37
39
#include <asm/bootinfo.h>
38
40
#include <asm/cpu.h>
47
49
#include <asm/pgtable.h>
48
50
#include <asm/processor.h>
49
51
#include <asm/reg.h>
52
+ #include <asm/switch_to.h>
50
53
#include <asm/unwind.h>
51
54
#include <asm/vdso.h>
52
55
@@ -63,8 +66,9 @@ EXPORT_SYMBOL(__stack_chk_guard);
63
66
unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE ;
64
67
EXPORT_SYMBOL (boot_option_idle_override );
65
68
66
- asmlinkage void ret_from_fork (void );
67
- asmlinkage void ret_from_kernel_thread (void );
69
+ asmlinkage void restore_and_ret (void );
70
+ asmlinkage void ret_from_fork_asm (void );
71
+ asmlinkage void ret_from_kernel_thread_asm (void );
68
72
69
73
void start_thread (struct pt_regs * regs , unsigned long pc , unsigned long sp )
70
74
{
@@ -138,6 +142,23 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
138
142
return 0 ;
139
143
}
140
144
145
+ asmlinkage void noinstr __no_stack_protector ret_from_fork (struct task_struct * prev ,
146
+ struct pt_regs * regs )
147
+ {
148
+ schedule_tail (prev );
149
+ syscall_exit_to_user_mode (regs );
150
+ }
151
+
152
+ asmlinkage void noinstr __no_stack_protector ret_from_kernel_thread (struct task_struct * prev ,
153
+ struct pt_regs * regs ,
154
+ int (* fn )(void * ),
155
+ void * fn_arg )
156
+ {
157
+ schedule_tail (prev );
158
+ fn (fn_arg );
159
+ syscall_exit_to_user_mode (regs );
160
+ }
161
+
141
162
/*
142
163
* Copy architecture-specific thread state
143
164
*/
@@ -165,8 +186,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
165
186
p -> thread .reg03 = childksp ;
166
187
p -> thread .reg23 = (unsigned long )args -> fn ;
167
188
p -> thread .reg24 = (unsigned long )args -> fn_arg ;
168
- p -> thread .reg01 = (unsigned long )ret_from_kernel_thread ;
169
- p -> thread .sched_ra = (unsigned long )ret_from_kernel_thread ;
189
+ p -> thread .reg01 = (unsigned long )ret_from_kernel_thread_asm ;
190
+ p -> thread .sched_ra = (unsigned long )ret_from_kernel_thread_asm ;
170
191
memset (childregs , 0 , sizeof (struct pt_regs ));
171
192
childregs -> csr_euen = p -> thread .csr_euen ;
172
193
childregs -> csr_crmd = p -> thread .csr_crmd ;
@@ -182,8 +203,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
182
203
childregs -> regs [3 ] = usp ;
183
204
184
205
p -> thread .reg03 = (unsigned long ) childregs ;
185
- p -> thread .reg01 = (unsigned long ) ret_from_fork ;
186
- p -> thread .sched_ra = (unsigned long ) ret_from_fork ;
206
+ p -> thread .reg01 = (unsigned long ) ret_from_fork_asm ;
207
+ p -> thread .sched_ra = (unsigned long ) ret_from_fork_asm ;
187
208
188
209
/*
189
210
* New tasks lose permission to use the fpu. This accelerates context
0 commit comments