Commit 24f41d8d authored by Russell King's avatar Russell King

[ARM] Tidy up context switch save area initialisation for fork

Fix a minor bug where we jump to ret_from_fork with IRQs enabled.
parent ad51ddeb
...@@ -310,9 +310,9 @@ void release_thread(struct task_struct *dead_task) ...@@ -310,9 +310,9 @@ void release_thread(struct task_struct *dead_task)
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, int
unsigned long unused, copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
struct task_struct * p, struct pt_regs * regs) unsigned long unused, struct task_struct *p, struct pt_regs *regs)
{ {
struct pt_regs *childregs; struct pt_regs *childregs;
struct cpu_context_save *save; struct cpu_context_save *save;
...@@ -323,8 +323,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, ...@@ -323,8 +323,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
childregs->ARM_sp = esp; childregs->ARM_sp = esp;
save = ((struct cpu_context_save *)(childregs)) - 1; save = ((struct cpu_context_save *)(childregs)) - 1;
*save = INIT_CSS; memset(save, 0, sizeof(struct cpu_context_save));
save->pc |= (unsigned long)ret_from_fork; init_pc_psr(save, ret_from_fork);
p->thread_info->cpu_context = save; p->thread_info->cpu_context = save;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#define __ASM_PROC_PROCESSOR_H #define __ASM_PROC_PROCESSOR_H
#include <linux/string.h> #include <linux/string.h>
#include <asm/proc/ptrace.h>
#define KERNEL_STACK_SIZE 4096 #define KERNEL_STACK_SIZE 4096
...@@ -35,7 +36,10 @@ struct cpu_context_save { ...@@ -35,7 +36,10 @@ struct cpu_context_save {
unsigned long pc; unsigned long pc;
}; };
#define INIT_CSS (struct cpu_context_save){ 0, 0, 0, 0, 0, 0, 0, 0, SVC26_MODE } static inline void init_pc_psr(struct cpu_context_save *s, void *fn)
{
s->pc = ((unsigned long)fn) | PSR_I_BIT | SVC26_MODE;
}
typedef struct { typedef struct {
void (*put_byte)(void); /* Special calling convention */ void (*put_byte)(void); /* Special calling convention */
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#define __ASM_PROC_PROCESSOR_H #define __ASM_PROC_PROCESSOR_H
#include <asm/proc/domain.h> #include <asm/proc/domain.h>
#include <asm/proc/ptrace.h>
#define KERNEL_STACK_SIZE PAGE_SIZE #define KERNEL_STACK_SIZE PAGE_SIZE
...@@ -35,7 +36,11 @@ struct cpu_context_save { ...@@ -35,7 +36,11 @@ struct cpu_context_save {
unsigned long pc; unsigned long pc;
}; };
#define INIT_CSS (struct cpu_context_save){ SVC_MODE, 0, 0, 0, 0, 0, 0, 0, 0, 0 } static inline void init_pc_psr(struct cpu_context_save *s, void *fn)
{
s->pc = (unsigned long)fn;
s->cpsr = PSR_I_BIT | SVC_MODE;
}
#define INIT_EXTRA_THREAD_INFO \ #define INIT_EXTRA_THREAD_INFO \
cpu_domain: domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \ cpu_domain: domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment