diff options
Diffstat (limited to 'arch/tile/kernel/process.c')
-rw-r--r-- | arch/tile/kernel/process.c | 110 |
1 files changed, 67 insertions, 43 deletions
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c index c70ff14a48e4..ed590ad0acdc 100644 --- a/arch/tile/kernel/process.c +++ b/arch/tile/kernel/process.c @@ -24,9 +24,14 @@ #include <linux/compat.h> #include <linux/hardirq.h> #include <linux/syscalls.h> +#include <linux/kernel.h> #include <asm/system.h> #include <asm/stack.h> #include <asm/homecache.h> +#include <asm/syscalls.h> +#ifdef CONFIG_HARDWALL +#include <asm/hardwall.h> +#endif #include <arch/chip.h> #include <arch/abi.h> @@ -43,7 +48,7 @@ static int __init idle_setup(char *str) return -EINVAL; if (!strcmp(str, "poll")) { - printk("using polling idle threads.\n"); + pr_info("using polling idle threads.\n"); no_idle_nap = 1; } else if (!strcmp(str, "halt")) no_idle_nap = 0; @@ -62,7 +67,6 @@ early_param("idle", idle_setup); */ void cpu_idle(void) { - extern void _cpu_idle(void); int cpu = smp_processor_id(); @@ -108,7 +112,7 @@ void cpu_idle(void) struct thread_info *alloc_thread_info(struct task_struct *task) { struct page *page; - int flags = GFP_KERNEL; + gfp_t flags = GFP_KERNEL; #ifdef CONFIG_DEBUG_STACK_USAGE flags |= __GFP_ZERO; @@ -116,7 +120,7 @@ struct thread_info *alloc_thread_info(struct task_struct *task) page = alloc_pages(flags, THREAD_SIZE_ORDER); if (!page) - return 0; + return NULL; return (struct thread_info *)page_address(page); } @@ -129,6 +133,18 @@ void free_thread_info(struct thread_info *info) { struct single_step_state *step_state = info->step_state; +#ifdef CONFIG_HARDWALL + /* + * We free a thread_info from the context of the task that has + * been scheduled next, so the original task is already dead. + * Calling deactivate here just frees up the data structures. + * If the task we're freeing held the last reference to a + * hardwall fd, it would have been released prior to this point + * anyway via exit_files(), and "hardwall" would be NULL by now. + */ + if (info->task->thread.hardwall) + hardwall_deactivate(info->task); +#endif if (step_state) { @@ -154,8 +170,6 @@ void free_thread_info(struct thread_info *info) static void save_arch_state(struct thread_struct *t); -extern void ret_from_fork(void); - int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long stack_size, struct task_struct *p, struct pt_regs *regs) @@ -235,6 +249,10 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, p->thread.proc_status = 0; #endif +#ifdef CONFIG_HARDWALL + /* New thread does not own any networks. */ + p->thread.hardwall = NULL; +#endif /* @@ -257,7 +275,7 @@ struct task_struct *validate_current(void) if (unlikely((unsigned long)tsk < PAGE_OFFSET || (void *)tsk > high_memory || ((unsigned long)tsk & (__alignof__(*tsk) - 1)) != 0)) { - printk("Corrupt 'current' %p (sp %#lx)\n", tsk, stack_pointer); + pr_err("Corrupt 'current' %p (sp %#lx)\n", tsk, stack_pointer); tsk = &corrupt; } return tsk; @@ -447,10 +465,6 @@ void _prepare_arch_switch(struct task_struct *next) } -extern struct task_struct *__switch_to(struct task_struct *prev, - struct task_struct *next, - unsigned long new_system_save_1_0); - struct task_struct *__sched _switch_to(struct task_struct *prev, struct task_struct *next) { @@ -486,6 +500,15 @@ struct task_struct *__sched _switch_to(struct task_struct *prev, } #endif +#ifdef CONFIG_HARDWALL + /* Enable or disable access to the network registers appropriately. */ + if (prev->thread.hardwall != NULL) { + if (next->thread.hardwall == NULL) + restrict_network_mpls(); + } else if (next->thread.hardwall != NULL) { + grant_network_mpls(); + } +#endif /* * Switch kernel SP, PC, and callee-saved registers. @@ -496,14 +519,14 @@ struct task_struct *__sched _switch_to(struct task_struct *prev, return __switch_to(prev, next, next_current_ksp0(next)); } -int _sys_fork(struct pt_regs *regs) +long _sys_fork(struct pt_regs *regs) { return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL); } -int _sys_clone(unsigned long clone_flags, unsigned long newsp, - void __user *parent_tidptr, void __user *child_tidptr, - struct pt_regs *regs) +long _sys_clone(unsigned long clone_flags, unsigned long newsp, + void __user *parent_tidptr, void __user *child_tidptr, + struct pt_regs *regs) { if (!newsp) newsp = regs->sp; @@ -511,7 +534,7 @@ int _sys_clone(unsigned long clone_flags, unsigned long newsp, parent_tidptr, child_tidptr); } -int _sys_vfork(struct pt_regs *regs) +long _sys_vfork(struct pt_regs *regs) { return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, 0, NULL, NULL); @@ -520,10 +543,10 @@ int _sys_vfork(struct pt_regs *regs) /* * sys_execve() executes a new program. */ -int _sys_execve(char __user *path, char __user *__user *argv, - char __user *__user *envp, struct pt_regs *regs) +long _sys_execve(char __user *path, char __user *__user *argv, + char __user *__user *envp, struct pt_regs *regs) { - int error; + long error; char *filename; filename = getname(path); @@ -537,10 +560,10 @@ out: } #ifdef CONFIG_COMPAT -int _compat_sys_execve(char __user *path, compat_uptr_t __user *argv, - compat_uptr_t __user *envp, struct pt_regs *regs) +long _compat_sys_execve(char __user *path, compat_uptr_t __user *argv, + compat_uptr_t __user *envp, struct pt_regs *regs) { - int error; + long error; char *filename; filename = getname(path); @@ -616,31 +639,32 @@ void exit_thread(void) /* Nothing */ } -#ifdef __tilegx__ -# define LINECOUNT 3 -# define EXTRA_NL "\n" -#else -# define LINECOUNT 4 -# define EXTRA_NL "" -#endif - void show_regs(struct pt_regs *regs) { struct task_struct *tsk = validate_current(); - int i, linebreak; - printk("\n"); - printk(" Pid: %d, comm: %20s, CPU: %d\n", + int i; + + pr_err("\n"); + pr_err(" Pid: %d, comm: %20s, CPU: %d\n", tsk->pid, tsk->comm, smp_processor_id()); - for (i = linebreak = 0; i < 53; ++i) { - printk(" r%-2d: "REGFMT, i, regs->regs[i]); - if (++linebreak == LINECOUNT) { - linebreak = 0; - printk("\n"); - } - } - printk(" tp : "REGFMT EXTRA_NL " sp : "REGFMT" lr : "REGFMT"\n", - regs->tp, regs->sp, regs->lr); - printk(" pc : "REGFMT" ex1: %ld faultnum: %ld\n", +#ifdef __tilegx__ + for (i = 0; i < 51; i += 3) + pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT" r%-2d: "REGFMT"\n", + i, regs->regs[i], i+1, regs->regs[i+1], + i+2, regs->regs[i+2]); + pr_err(" r51: "REGFMT" r52: "REGFMT" tp : "REGFMT"\n", + regs->regs[51], regs->regs[52], regs->tp); + pr_err(" sp : "REGFMT" lr : "REGFMT"\n", regs->sp, regs->lr); +#else + for (i = 0; i < 52; i += 3) + pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT + " r%-2d: "REGFMT" r%-2d: "REGFMT"\n", + i, regs->regs[i], i+1, regs->regs[i+1], + i+2, regs->regs[i+2], i+3, regs->regs[i+3]); + pr_err(" r52: "REGFMT" tp : "REGFMT" sp : "REGFMT" lr : "REGFMT"\n", + regs->regs[52], regs->tp, regs->sp, regs->lr); +#endif + pr_err(" pc : "REGFMT" ex1: %ld faultnum: %ld\n", regs->pc, regs->ex1, regs->faultnum); dump_stack_regs(regs); |