#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>
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;
*/
void cpu_idle(void)
{
- extern void _cpu_idle(void);
int cpu = smp_processor_id();
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;
page = alloc_pages(flags, THREAD_SIZE_ORDER);
if (!page)
- return 0;
+ return NULL;
return (struct thread_info *)page_address(page);
}
{
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) {
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)
p->thread.proc_status = 0;
#endif
+#ifdef CONFIG_HARDWALL
+ /* New thread does not own any networks. */
+ p->thread.hardwall = NULL;
+#endif
/*
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;
}
-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)
{
}
#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.
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;
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);
/*
* 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(const char __user *path,
+ const char __user *const __user *argv,
+ const char __user *const __user *envp, struct pt_regs *regs)
{
- int error;
+ long error;
char *filename;
filename = getname(path);
}
#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);
/* 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);