diff options
Diffstat (limited to 'arch/tile/kernel/process.c')
-rw-r--r-- | arch/tile/kernel/process.c | 50 |
1 files changed, 26 insertions, 24 deletions
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c index 84c29111756c..8430f45daea6 100644 --- a/arch/tile/kernel/process.c +++ b/arch/tile/kernel/process.c | |||
@@ -214,9 +214,10 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
214 | /* | 214 | /* |
215 | * Copy the callee-saved registers from the passed pt_regs struct | 215 | * Copy the callee-saved registers from the passed pt_regs struct |
216 | * into the context-switch callee-saved registers area. | 216 | * into the context-switch callee-saved registers area. |
217 | * We have to restore the callee-saved registers since we may | 217 | * This way when we start the interrupt-return sequence, the |
218 | * be cloning a userspace task with userspace register state, | 218 | * callee-save registers will be correctly in registers, which |
219 | * and we won't be unwinding the same kernel frames to restore them. | 219 | * is how we assume the compiler leaves them as we start doing |
220 | * the normal return-from-interrupt path after calling C code. | ||
220 | * Zero out the C ABI save area to mark the top of the stack. | 221 | * Zero out the C ABI save area to mark the top of the stack. |
221 | */ | 222 | */ |
222 | ksp = (unsigned long) childregs; | 223 | ksp = (unsigned long) childregs; |
@@ -304,15 +305,25 @@ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) | |||
304 | /* Allow user processes to access the DMA SPRs */ | 305 | /* Allow user processes to access the DMA SPRs */ |
305 | void grant_dma_mpls(void) | 306 | void grant_dma_mpls(void) |
306 | { | 307 | { |
308 | #if CONFIG_KERNEL_PL == 2 | ||
309 | __insn_mtspr(SPR_MPL_DMA_CPL_SET_1, 1); | ||
310 | __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_1, 1); | ||
311 | #else | ||
307 | __insn_mtspr(SPR_MPL_DMA_CPL_SET_0, 1); | 312 | __insn_mtspr(SPR_MPL_DMA_CPL_SET_0, 1); |
308 | __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_0, 1); | 313 | __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_0, 1); |
314 | #endif | ||
309 | } | 315 | } |
310 | 316 | ||
311 | /* Forbid user processes from accessing the DMA SPRs */ | 317 | /* Forbid user processes from accessing the DMA SPRs */ |
312 | void restrict_dma_mpls(void) | 318 | void restrict_dma_mpls(void) |
313 | { | 319 | { |
320 | #if CONFIG_KERNEL_PL == 2 | ||
321 | __insn_mtspr(SPR_MPL_DMA_CPL_SET_2, 1); | ||
322 | __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_2, 1); | ||
323 | #else | ||
314 | __insn_mtspr(SPR_MPL_DMA_CPL_SET_1, 1); | 324 | __insn_mtspr(SPR_MPL_DMA_CPL_SET_1, 1); |
315 | __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_1, 1); | 325 | __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_1, 1); |
326 | #endif | ||
316 | } | 327 | } |
317 | 328 | ||
318 | /* Pause the DMA engine, then save off its state registers. */ | 329 | /* Pause the DMA engine, then save off its state registers. */ |
@@ -523,19 +534,14 @@ struct task_struct *__sched _switch_to(struct task_struct *prev, | |||
523 | * Switch kernel SP, PC, and callee-saved registers. | 534 | * Switch kernel SP, PC, and callee-saved registers. |
524 | * In the context of the new task, return the old task pointer | 535 | * In the context of the new task, return the old task pointer |
525 | * (i.e. the task that actually called __switch_to). | 536 | * (i.e. the task that actually called __switch_to). |
526 | * Pass the value to use for SYSTEM_SAVE_1_0 when we reset our sp. | 537 | * Pass the value to use for SYSTEM_SAVE_K_0 when we reset our sp. |
527 | */ | 538 | */ |
528 | return __switch_to(prev, next, next_current_ksp0(next)); | 539 | return __switch_to(prev, next, next_current_ksp0(next)); |
529 | } | 540 | } |
530 | 541 | ||
531 | long _sys_fork(struct pt_regs *regs) | 542 | SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, |
532 | { | 543 | void __user *, parent_tidptr, void __user *, child_tidptr, |
533 | return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL); | 544 | struct pt_regs *, regs) |
534 | } | ||
535 | |||
536 | long _sys_clone(unsigned long clone_flags, unsigned long newsp, | ||
537 | void __user *parent_tidptr, void __user *child_tidptr, | ||
538 | struct pt_regs *regs) | ||
539 | { | 545 | { |
540 | if (!newsp) | 546 | if (!newsp) |
541 | newsp = regs->sp; | 547 | newsp = regs->sp; |
@@ -543,18 +549,13 @@ long _sys_clone(unsigned long clone_flags, unsigned long newsp, | |||
543 | parent_tidptr, child_tidptr); | 549 | parent_tidptr, child_tidptr); |
544 | } | 550 | } |
545 | 551 | ||
546 | long _sys_vfork(struct pt_regs *regs) | ||
547 | { | ||
548 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, | ||
549 | regs, 0, NULL, NULL); | ||
550 | } | ||
551 | |||
552 | /* | 552 | /* |
553 | * sys_execve() executes a new program. | 553 | * sys_execve() executes a new program. |
554 | */ | 554 | */ |
555 | long _sys_execve(const char __user *path, | 555 | SYSCALL_DEFINE4(execve, const char __user *, path, |
556 | const char __user *const __user *argv, | 556 | const char __user *const __user *, argv, |
557 | const char __user *const __user *envp, struct pt_regs *regs) | 557 | const char __user *const __user *, envp, |
558 | struct pt_regs *, regs) | ||
558 | { | 559 | { |
559 | long error; | 560 | long error; |
560 | char *filename; | 561 | char *filename; |
@@ -570,9 +571,10 @@ out: | |||
570 | } | 571 | } |
571 | 572 | ||
572 | #ifdef CONFIG_COMPAT | 573 | #ifdef CONFIG_COMPAT |
573 | long _compat_sys_execve(const char __user *path, | 574 | long compat_sys_execve(const char __user *path, |
574 | const compat_uptr_t __user *argv, | 575 | const compat_uptr_t __user *argv, |
575 | const compat_uptr_t __user *envp, struct pt_regs *regs) | 576 | const compat_uptr_t __user *envp, |
577 | struct pt_regs *regs) | ||
576 | { | 578 | { |
577 | long error; | 579 | long error; |
578 | char *filename; | 580 | char *filename; |