aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/kernel/process.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2010-12-30 00:20:30 -0500
committerGrant Likely <grant.likely@secretlab.ca>2010-12-30 00:21:47 -0500
commitd392da5207352f09030e95d9ea335a4225667ec0 (patch)
tree7d6cd1932afcad0a5619a5c504a6d93ca318187c /arch/tile/kernel/process.c
parente39d5ef678045d61812c1401f04fe8edb14d6359 (diff)
parent387c31c7e5c9805b0aef8833d1731a5fe7bdea14 (diff)
Merge v2.6.37-rc8 into powerpc/next
Diffstat (limited to 'arch/tile/kernel/process.c')
-rw-r--r--arch/tile/kernel/process.c81
1 files changed, 51 insertions, 30 deletions
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c
index ed590ad0acdc..e90eb53173b0 100644
--- a/arch/tile/kernel/process.c
+++ b/arch/tile/kernel/process.c
@@ -212,11 +212,19 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
212 childregs->sp = sp; /* override with new user stack pointer */ 212 childregs->sp = sp; /* override with new user stack pointer */
213 213
214 /* 214 /*
215 * If CLONE_SETTLS is set, set "tp" in the new task to "r4",
216 * which is passed in as arg #5 to sys_clone().
217 */
218 if (clone_flags & CLONE_SETTLS)
219 childregs->tp = regs->regs[4];
220
221 /*
215 * Copy the callee-saved registers from the passed pt_regs struct 222 * Copy the callee-saved registers from the passed pt_regs struct
216 * into the context-switch callee-saved registers area. 223 * into the context-switch callee-saved registers area.
217 * We have to restore the callee-saved registers since we may 224 * This way when we start the interrupt-return sequence, the
218 * be cloning a userspace task with userspace register state, 225 * callee-save registers will be correctly in registers, which
219 * and we won't be unwinding the same kernel frames to restore them. 226 * is how we assume the compiler leaves them as we start doing
227 * 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. 228 * Zero out the C ABI save area to mark the top of the stack.
221 */ 229 */
222 ksp = (unsigned long) childregs; 230 ksp = (unsigned long) childregs;
@@ -304,15 +312,25 @@ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
304/* Allow user processes to access the DMA SPRs */ 312/* Allow user processes to access the DMA SPRs */
305void grant_dma_mpls(void) 313void grant_dma_mpls(void)
306{ 314{
315#if CONFIG_KERNEL_PL == 2
316 __insn_mtspr(SPR_MPL_DMA_CPL_SET_1, 1);
317 __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_1, 1);
318#else
307 __insn_mtspr(SPR_MPL_DMA_CPL_SET_0, 1); 319 __insn_mtspr(SPR_MPL_DMA_CPL_SET_0, 1);
308 __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_0, 1); 320 __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_0, 1);
321#endif
309} 322}
310 323
311/* Forbid user processes from accessing the DMA SPRs */ 324/* Forbid user processes from accessing the DMA SPRs */
312void restrict_dma_mpls(void) 325void restrict_dma_mpls(void)
313{ 326{
327#if CONFIG_KERNEL_PL == 2
328 __insn_mtspr(SPR_MPL_DMA_CPL_SET_2, 1);
329 __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_2, 1);
330#else
314 __insn_mtspr(SPR_MPL_DMA_CPL_SET_1, 1); 331 __insn_mtspr(SPR_MPL_DMA_CPL_SET_1, 1);
315 __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_1, 1); 332 __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_1, 1);
333#endif
316} 334}
317 335
318/* Pause the DMA engine, then save off its state registers. */ 336/* Pause the DMA engine, then save off its state registers. */
@@ -408,6 +426,15 @@ static void save_arch_state(struct thread_struct *t)
408#if CHIP_HAS_PROC_STATUS_SPR() 426#if CHIP_HAS_PROC_STATUS_SPR()
409 t->proc_status = __insn_mfspr(SPR_PROC_STATUS); 427 t->proc_status = __insn_mfspr(SPR_PROC_STATUS);
410#endif 428#endif
429#if !CHIP_HAS_FIXED_INTVEC_BASE()
430 t->interrupt_vector_base = __insn_mfspr(SPR_INTERRUPT_VECTOR_BASE_0);
431#endif
432#if CHIP_HAS_TILE_RTF_HWM()
433 t->tile_rtf_hwm = __insn_mfspr(SPR_TILE_RTF_HWM);
434#endif
435#if CHIP_HAS_DSTREAM_PF()
436 t->dstream_pf = __insn_mfspr(SPR_DSTREAM_PF);
437#endif
411} 438}
412 439
413static void restore_arch_state(const struct thread_struct *t) 440static void restore_arch_state(const struct thread_struct *t)
@@ -428,14 +455,14 @@ static void restore_arch_state(const struct thread_struct *t)
428#if CHIP_HAS_PROC_STATUS_SPR() 455#if CHIP_HAS_PROC_STATUS_SPR()
429 __insn_mtspr(SPR_PROC_STATUS, t->proc_status); 456 __insn_mtspr(SPR_PROC_STATUS, t->proc_status);
430#endif 457#endif
458#if !CHIP_HAS_FIXED_INTVEC_BASE()
459 __insn_mtspr(SPR_INTERRUPT_VECTOR_BASE_0, t->interrupt_vector_base);
460#endif
431#if CHIP_HAS_TILE_RTF_HWM() 461#if CHIP_HAS_TILE_RTF_HWM()
432 /* 462 __insn_mtspr(SPR_TILE_RTF_HWM, t->tile_rtf_hwm);
433 * Clear this whenever we switch back to a process in case 463#endif
434 * the previous process was monkeying with it. Even if enabled 464#if CHIP_HAS_DSTREAM_PF()
435 * in CBOX_MSR1 via TILE_RTF_HWM_MIN, it's still just a 465 __insn_mtspr(SPR_DSTREAM_PF, t->dstream_pf);
436 * performance hint, so isn't worth a full save/restore.
437 */
438 __insn_mtspr(SPR_TILE_RTF_HWM, 0);
439#endif 466#endif
440} 467}
441 468
@@ -514,19 +541,15 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
514 * Switch kernel SP, PC, and callee-saved registers. 541 * Switch kernel SP, PC, and callee-saved registers.
515 * In the context of the new task, return the old task pointer 542 * In the context of the new task, return the old task pointer
516 * (i.e. the task that actually called __switch_to). 543 * (i.e. the task that actually called __switch_to).
517 * Pass the value to use for SYSTEM_SAVE_1_0 when we reset our sp. 544 * Pass the value to use for SYSTEM_SAVE_K_0 when we reset our sp.
518 */ 545 */
519 return __switch_to(prev, next, next_current_ksp0(next)); 546 return __switch_to(prev, next, next_current_ksp0(next));
520} 547}
521 548
522long _sys_fork(struct pt_regs *regs) 549/* Note there is an implicit fifth argument if (clone_flags & CLONE_SETTLS). */
523{ 550SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
524 return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL); 551 void __user *, parent_tidptr, void __user *, child_tidptr,
525} 552 struct pt_regs *, regs)
526
527long _sys_clone(unsigned long clone_flags, unsigned long newsp,
528 void __user *parent_tidptr, void __user *child_tidptr,
529 struct pt_regs *regs)
530{ 553{
531 if (!newsp) 554 if (!newsp)
532 newsp = regs->sp; 555 newsp = regs->sp;
@@ -534,17 +557,13 @@ long _sys_clone(unsigned long clone_flags, unsigned long newsp,
534 parent_tidptr, child_tidptr); 557 parent_tidptr, child_tidptr);
535} 558}
536 559
537long _sys_vfork(struct pt_regs *regs)
538{
539 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp,
540 regs, 0, NULL, NULL);
541}
542
543/* 560/*
544 * sys_execve() executes a new program. 561 * sys_execve() executes a new program.
545 */ 562 */
546long _sys_execve(char __user *path, char __user *__user *argv, 563SYSCALL_DEFINE4(execve, const char __user *, path,
547 char __user *__user *envp, struct pt_regs *regs) 564 const char __user *const __user *, argv,
565 const char __user *const __user *, envp,
566 struct pt_regs *, regs)
548{ 567{
549 long error; 568 long error;
550 char *filename; 569 char *filename;
@@ -560,8 +579,10 @@ out:
560} 579}
561 580
562#ifdef CONFIG_COMPAT 581#ifdef CONFIG_COMPAT
563long _compat_sys_execve(char __user *path, compat_uptr_t __user *argv, 582long compat_sys_execve(const char __user *path,
564 compat_uptr_t __user *envp, struct pt_regs *regs) 583 const compat_uptr_t __user *argv,
584 const compat_uptr_t __user *envp,
585 struct pt_regs *regs)
565{ 586{
566 long error; 587 long error;
567 char *filename; 588 char *filename;
@@ -656,7 +677,7 @@ void show_regs(struct pt_regs *regs)
656 regs->regs[51], regs->regs[52], regs->tp); 677 regs->regs[51], regs->regs[52], regs->tp);
657 pr_err(" sp : "REGFMT" lr : "REGFMT"\n", regs->sp, regs->lr); 678 pr_err(" sp : "REGFMT" lr : "REGFMT"\n", regs->sp, regs->lr);
658#else 679#else
659 for (i = 0; i < 52; i += 3) 680 for (i = 0; i < 52; i += 4)
660 pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT 681 pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT
661 " r%-2d: "REGFMT" r%-2d: "REGFMT"\n", 682 " r%-2d: "REGFMT" r%-2d: "REGFMT"\n",
662 i, regs->regs[i], i+1, regs->regs[i+1], 683 i, regs->regs[i], i+1, regs->regs[i+1],