diff options
Diffstat (limited to 'arch/arc/kernel/process.c')
-rw-r--r-- | arch/arc/kernel/process.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c index 4674541eba3f..8ce6e7235915 100644 --- a/arch/arc/kernel/process.c +++ b/arch/arc/kernel/process.c | |||
@@ -241,6 +241,26 @@ int copy_thread(unsigned long clone_flags, | |||
241 | task_thread_info(current)->thr_ptr; | 241 | task_thread_info(current)->thr_ptr; |
242 | } | 242 | } |
243 | 243 | ||
244 | |||
245 | /* | ||
246 | * setup usermode thread pointer #1: | ||
247 | * when child is picked by scheduler, __switch_to() uses @c_callee to | ||
248 | * populate usermode callee regs: this works (despite being in a kernel | ||
249 | * function) since special return path for child @ret_from_fork() | ||
250 | * ensures those regs are not clobbered all the way to RTIE to usermode | ||
251 | */ | ||
252 | c_callee->r25 = task_thread_info(p)->thr_ptr; | ||
253 | |||
254 | #ifdef CONFIG_ARC_CURR_IN_REG | ||
255 | /* | ||
256 | * setup usermode thread pointer #2: | ||
257 | * however for this special use of r25 in kernel, __switch_to() sets | ||
258 | * r25 for kernel needs and only in the final return path is usermode | ||
259 | * r25 setup, from pt_regs->user_r25. So set that up as well | ||
260 | */ | ||
261 | c_regs->user_r25 = c_callee->r25; | ||
262 | #endif | ||
263 | |||
244 | return 0; | 264 | return 0; |
245 | } | 265 | } |
246 | 266 | ||