summaryrefslogtreecommitdiffstats
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.c110
1 files changed, 67 insertions, 43 deletions
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c
index c70ff14..ed590ad 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);
OpenPOWER on IntegriCloud