aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/tile/kernel/process.c')
-rw-r--r--arch/tile/kernel/process.c50
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 */
305void grant_dma_mpls(void) 306void 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 */
312void restrict_dma_mpls(void) 318void 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
531long _sys_fork(struct pt_regs *regs) 542SYSCALL_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
536long _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
546long _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 */
555long _sys_execve(const char __user *path, 555SYSCALL_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
573long _compat_sys_execve(const char __user *path, 574long 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;