summaryrefslogtreecommitdiffstats
path: root/arch/microblaze/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/microblaze/kernel')
-rw-r--r--arch/microblaze/kernel/entry-nommu.S21
-rw-r--r--arch/microblaze/kernel/entry.S57
-rw-r--r--arch/microblaze/kernel/intc.c5
-rw-r--r--arch/microblaze/kernel/process.c76
-rw-r--r--arch/microblaze/kernel/prom.c4
-rw-r--r--arch/microblaze/kernel/signal.c2
-rw-r--r--arch/microblaze/kernel/sys_microblaze.c53
-rw-r--r--arch/microblaze/kernel/syscall_table.S7
8 files changed, 48 insertions, 177 deletions
diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S
index 75c3ea1f48a..70da83a4967 100644
--- a/arch/microblaze/kernel/entry-nommu.S
+++ b/arch/microblaze/kernel/entry-nommu.S
@@ -465,7 +465,6 @@ ENTRY(_switch_to)
ENTRY(ret_from_fork)
addk r5, r0, r3
- addk r6, r0, r1
brlid r15, schedule_tail
nop
swi r31, r1, PT_R31 /* save r31 in user context. */
@@ -474,6 +473,14 @@ ENTRY(ret_from_fork)
brid ret_to_user
nop
+ENTRY(ret_from_kernel_thread)
+ brlid r15, schedule_tail
+ addk r5, r0, r3
+ brald r15, r20
+ addk r5, r0, r19
+ brid ret_to_user
+ addk r3, r0, r0
+
work_pending:
enable_irq
@@ -551,18 +558,6 @@ no_work_pending:
rtid r14, 0
nop
-sys_vfork:
- brid microblaze_vfork
- addk r5, r1, r0
-
-sys_clone:
- brid microblaze_clone
- addk r7, r1, r0
-
-sys_execve:
- brid microblaze_execve
- addk r8, r1, r0
-
sys_rt_sigreturn_wrapper:
brid sys_rt_sigreturn
addk r5, r1, r0
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 03f7b8ce6b6..c217367dfc7 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -293,24 +293,6 @@ C_ENTRY(_user_exception):
swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */
addi r14, r14, 4 /* return address is 4 byte after call */
- mfs r1, rmsr
- nop
- andi r1, r1, MSR_UMS
- bnei r1, 1f
-
-/* Kernel-mode state save - kernel execve */
- lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/
- tophys(r1,r1);
-
- addik r1, r1, -PT_SIZE; /* Make room on the stack. */
- SAVE_REGS
-
- swi r1, r1, PT_MODE; /* pt_regs -> kernel mode */
- brid 2f;
- nop; /* Fill delay slot */
-
-/* User-mode state save. */
-1:
lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */
tophys(r1,r1);
lwi r1, r1, TS_THREAD_INFO; /* get stack from task_struct */
@@ -460,18 +442,6 @@ TRAP_return: /* Make global symbol for debugging */
nop;
-/* These syscalls need access to the struct pt_regs on the stack, so we
- implement them in assembly (they're basically all wrappers anyway). */
-
-C_ENTRY(sys_fork_wrapper):
- addi r5, r0, SIGCHLD /* Arg 0: flags */
- lwi r6, r1, PT_R1 /* Arg 1: child SP (use parent's) */
- addik r7, r1, 0 /* Arg 2: parent context */
- add r8, r0, r0 /* Arg 3: (unused) */
- add r9, r0, r0; /* Arg 4: (unused) */
- brid do_fork /* Do real work (tail-call) */
- add r10, r0, r0; /* Arg 5: (unused) */
-
/* This the initial entry point for a new child thread, with an appropriate
stack in place that makes it look the the child is in the middle of an
syscall. This function is actually `returned to' from switch_thread
@@ -479,28 +449,19 @@ C_ENTRY(sys_fork_wrapper):
saved context). */
C_ENTRY(ret_from_fork):
bralid r15, schedule_tail; /* ...which is schedule_tail's arg */
- add r3, r5, r0; /* switch_thread returns the prev task */
+ add r5, r3, r0; /* switch_thread returns the prev task */
/* ( in the delay slot ) */
brid ret_from_trap; /* Do normal trap return */
add r3, r0, r0; /* Child's fork call should return 0. */
-C_ENTRY(sys_vfork):
- brid microblaze_vfork /* Do real work (tail-call) */
- addik r5, r1, 0
-
-C_ENTRY(sys_clone):
- bnei r6, 1f; /* See if child SP arg (arg 1) is 0. */
- lwi r6, r1, PT_R1; /* If so, use paret's stack ptr */
-1: addik r7, r1, 0; /* Arg 2: parent context */
- lwi r9, r1, PT_R8; /* parent tid. */
- lwi r10, r1, PT_R9; /* child tid. */
- /* do_fork will pick up TLS from regs->r10. */
- brid do_fork /* Do real work (tail-call) */
- add r8, r0, r0; /* Arg 3: (unused) */
-
-C_ENTRY(sys_execve):
- brid microblaze_execve; /* Do real work (tail-call).*/
- addik r8, r1, 0; /* add user context as 4th arg */
+C_ENTRY(ret_from_kernel_thread):
+ bralid r15, schedule_tail; /* ...which is schedule_tail's arg */
+ add r5, r3, r0; /* switch_thread returns the prev task */
+ /* ( in the delay slot ) */
+ brald r15, r20 /* fn was left in r20 */
+ addk r5, r0, r19 /* ... and argument - in r19 */
+ brid ret_from_trap
+ add r3, r0, r0
C_ENTRY(sys_rt_sigreturn_wrapper):
brid sys_rt_sigreturn /* Do real work */
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
index 6c54d4dcdec..7a1a8d4354f 100644
--- a/arch/microblaze/kernel/intc.c
+++ b/arch/microblaze/kernel/intc.c
@@ -44,7 +44,6 @@ static void intc_enable_or_unmask(struct irq_data *d)
unsigned long mask = 1 << d->hwirq;
pr_debug("enable_or_unmask: %ld\n", d->hwirq);
- out_be32(INTC_BASE + SIE, mask);
/* ack level irqs because they can't be acked during
* ack function since the handle_level_irq function
@@ -52,6 +51,8 @@ static void intc_enable_or_unmask(struct irq_data *d)
*/
if (irqd_is_level_type(d))
out_be32(INTC_BASE + IAR, mask);
+
+ out_be32(INTC_BASE + SIE, mask);
}
static void intc_disable_or_mask(struct irq_data *d)
@@ -98,7 +99,7 @@ unsigned int get_irq(void)
return irq;
}
-int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
+static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
{
u32 intr_mask = (u32)d->host_data;
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index 1944e00f07e..a5b74f729e5 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -13,6 +13,7 @@
#include <linux/pm.h>
#include <linux/tick.h>
#include <linux/bitops.h>
+#include <linux/ptrace.h>
#include <asm/pgalloc.h>
#include <asm/uaccess.h> /* for USER_DS macros */
#include <asm/cacheflush.h>
@@ -119,46 +120,38 @@ void flush_thread(void)
}
int copy_thread(unsigned long clone_flags, unsigned long usp,
- unsigned long unused,
- struct task_struct *p, struct pt_regs *regs)
+ unsigned long arg, struct task_struct *p)
{
struct pt_regs *childregs = task_pt_regs(p);
struct thread_info *ti = task_thread_info(p);
- *childregs = *regs;
- if (user_mode(regs))
+ if (unlikely(p->flags & PF_KTHREAD)) {
+ /* if we're creating a new kernel thread then just zeroing all
+ * the registers. That's OK for a brand new thread.*/
+ memset(childregs, 0, sizeof(struct pt_regs));
+ memset(&ti->cpu_context, 0, sizeof(struct cpu_context));
+ ti->cpu_context.r1 = (unsigned long)childregs;
+ ti->cpu_context.r20 = (unsigned long)usp; /* fn */
+ ti->cpu_context.r19 = (unsigned long)arg;
+ childregs->pt_mode = 1;
+ local_save_flags(childregs->msr);
+#ifdef CONFIG_MMU
+ ti->cpu_context.msr = childregs->msr & ~MSR_IE;
+#endif
+ ti->cpu_context.r15 = (unsigned long)ret_from_kernel_thread - 8;
+ return 0;
+ }
+ *childregs = *current_pt_regs();
+ if (usp)
childregs->r1 = usp;
- else
- childregs->r1 = ((unsigned long) ti) + THREAD_SIZE;
-#ifndef CONFIG_MMU
memset(&ti->cpu_context, 0, sizeof(struct cpu_context));
ti->cpu_context.r1 = (unsigned long)childregs;
+#ifndef CONFIG_MMU
ti->cpu_context.msr = (unsigned long)childregs->msr;
#else
+ childregs->msr |= MSR_UMS;
- /* if creating a kernel thread then update the current reg (we don't
- * want to use the parent's value when restoring by POP_STATE) */
- if (kernel_mode(regs))
- /* save new current on stack to use POP_STATE */
- childregs->CURRENT_TASK = (unsigned long)p;
- /* if returning to user then use the parent's value of this register */
-
- /* if we're creating a new kernel thread then just zeroing all
- * the registers. That's OK for a brand new thread.*/
- /* Pls. note that some of them will be restored in POP_STATE */
- if (kernel_mode(regs))
- memset(&ti->cpu_context, 0, sizeof(struct cpu_context));
- /* if this thread is created for fork/vfork/clone, then we want to
- * restore all the parent's context */
- /* in addition to the registers which will be restored by POP_STATE */
- else {
- ti->cpu_context = *(struct cpu_context *)regs;
- childregs->msr |= MSR_UMS;
- }
-
- /* FIXME STATE_SAVE_PT_OFFSET; */
- ti->cpu_context.r1 = (unsigned long)childregs;
/* we should consider the fact that childregs is a copy of the parent
* regs which were saved immediately after entering the kernel state
* before enabling VM. This MSR will be restored in switch_to and
@@ -169,7 +162,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
* excepting for VM and UMS
* don't touch UMS , CARRY and cache bits
* right now MSR is a copy of parent one */
- childregs->msr |= MSR_BIP;
childregs->msr &= ~MSR_EIP;
childregs->msr |= MSR_IE;
childregs->msr &= ~MSR_VM;
@@ -209,29 +201,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
}
#endif
-static void kernel_thread_helper(int (*fn)(void *), void *arg)
-{
- fn(arg);
- do_exit(-1);
-}
-
-int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-{
- struct pt_regs regs;
-
- memset(&regs, 0, sizeof(regs));
- /* store them in non-volatile registers */
- regs.r5 = (unsigned long)fn;
- regs.r6 = (unsigned long)arg;
- local_save_flags(regs.msr);
- regs.pc = (unsigned long)kernel_thread_helper;
- regs.pt_mode = 1;
-
- return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
- &regs, 0, NULL, NULL);
-}
-EXPORT_SYMBOL_GPL(kernel_thread);
-
unsigned long get_wchan(struct task_struct *p)
{
/* TBD (used by procfs) */
@@ -246,6 +215,7 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp)
regs->pt_mode = 0;
#ifdef CONFIG_MMU
regs->msr |= MSR_UMS;
+ regs->msr &= ~MSR_VM;
#endif
}
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index 4a764ccb9f2..a744e3f1888 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -52,9 +52,9 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
}
#ifdef CONFIG_EARLY_PRINTK
-char *stdout;
+static char *stdout;
-int __init early_init_dt_scan_chosen_serial(unsigned long node,
+static int __init early_init_dt_scan_chosen_serial(unsigned long node,
const char *uname, int depth, void *data)
{
unsigned long l;
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index 3903e3d11f5..ac3d0a0f481 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -354,7 +354,7 @@ static void do_signal(struct pt_regs *regs, int in_syscall)
restore_saved_sigmask();
}
-void do_notify_resume(struct pt_regs *regs, int in_syscall)
+asmlinkage void do_notify_resume(struct pt_regs *regs, int in_syscall)
{
/*
* We want the common case to go fast, which
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c
index 404c0f24bd4..63647c586b4 100644
--- a/arch/microblaze/kernel/sys_microblaze.c
+++ b/arch/microblaze/kernel/sys_microblaze.c
@@ -34,38 +34,6 @@
#include <asm/syscalls.h>
-asmlinkage long microblaze_vfork(struct pt_regs *regs)
-{
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->r1,
- regs, 0, NULL, NULL);
-}
-
-asmlinkage long microblaze_clone(int flags, unsigned long stack,
- struct pt_regs *regs)
-{
- if (!stack)
- stack = regs->r1;
- return do_fork(flags, stack, regs, 0, NULL, NULL);
-}
-
-asmlinkage long microblaze_execve(const char __user *filenamei,
- const char __user *const __user *argv,
- const char __user *const __user *envp,
- struct pt_regs *regs)
-{
- int error;
- struct filename *filename;
-
- filename = getname(filenamei);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- goto out;
- error = do_execve(filename->name, argv, envp, regs);
- putname(filename);
-out:
- return error;
-}
-
asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, off_t pgoff)
@@ -75,24 +43,3 @@ asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT);
}
-
-/*
- * Do a system call from kernel instead of calling sys_execve so we
- * end up with proper pt_regs.
- */
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
-{
- register const char *__a __asm__("r5") = filename;
- register const void *__b __asm__("r6") = argv;
- register const void *__c __asm__("r7") = envp;
- register unsigned long __syscall __asm__("r12") = __NR_execve;
- register unsigned long __ret __asm__("r3");
- __asm__ __volatile__ ("brki r14, 0x8"
- : "=r" (__ret), "=r" (__syscall)
- : "1" (__syscall), "r" (__a), "r" (__b), "r" (__c)
- : "r4", "r8", "r9",
- "r10", "r11", "r14", "cc", "memory");
- return __ret;
-}
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
index 6a2b294ef6d..1cbace29b5e 100644
--- a/arch/microblaze/kernel/syscall_table.S
+++ b/arch/microblaze/kernel/syscall_table.S
@@ -2,11 +2,7 @@ ENTRY(sys_call_table)
.long sys_restart_syscall /* 0 - old "setup()" system call,
* used for restarting */
.long sys_exit
-#ifdef CONFIG_MMU
- .long sys_fork_wrapper
-#else
- .long sys_ni_syscall
-#endif
+ .long sys_fork
.long sys_read
.long sys_write
.long sys_open /* 5 */
@@ -383,3 +379,4 @@ ENTRY(sys_call_table)
.long sys_sendmmsg
.long sys_process_vm_readv
.long sys_process_vm_writev
+ .long sys_kcmp