diff options
| -rw-r--r-- | arch/mn10300/kernel/Makefile | 2 | ||||
| -rw-r--r-- | arch/mn10300/kernel/entry.S | 7 | ||||
| -rw-r--r-- | arch/mn10300/kernel/internal.h | 6 | ||||
| -rw-r--r-- | arch/mn10300/kernel/kthread.S | 31 | ||||
| -rw-r--r-- | arch/mn10300/kernel/process.c | 52 |
5 files changed, 27 insertions, 71 deletions
diff --git a/arch/mn10300/kernel/Makefile b/arch/mn10300/kernel/Makefile index d06749173d63..142c12906682 100644 --- a/arch/mn10300/kernel/Makefile +++ b/arch/mn10300/kernel/Makefile | |||
| @@ -7,7 +7,7 @@ fpu-obj-y := fpu-nofpu.o fpu-nofpu-low.o | |||
| 7 | fpu-obj-$(CONFIG_FPU) := fpu.o fpu-low.o | 7 | fpu-obj-$(CONFIG_FPU) := fpu.o fpu-low.o |
| 8 | 8 | ||
| 9 | obj-y := process.o signal.o entry.o traps.o irq.o \ | 9 | obj-y := process.o signal.o entry.o traps.o irq.o \ |
| 10 | ptrace.o setup.o time.o sys_mn10300.o io.o kthread.o \ | 10 | ptrace.o setup.o time.o sys_mn10300.o io.o \ |
| 11 | switch_to.o mn10300_ksyms.o kernel_execve.o $(fpu-obj-y) \ | 11 | switch_to.o mn10300_ksyms.o kernel_execve.o $(fpu-obj-y) \ |
| 12 | csrc-mn10300.o cevt-mn10300.o | 12 | csrc-mn10300.o cevt-mn10300.o |
| 13 | 13 | ||
diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S index 8e11f9f48999..000f144230a5 100644 --- a/arch/mn10300/kernel/entry.S +++ b/arch/mn10300/kernel/entry.S | |||
| @@ -55,6 +55,13 @@ ENTRY(ret_from_fork) | |||
| 55 | mov d0,(REG_D0,fp) | 55 | mov d0,(REG_D0,fp) |
| 56 | jmp syscall_exit | 56 | jmp syscall_exit |
| 57 | 57 | ||
| 58 | ENTRY(ret_from_kernel_thread) | ||
| 59 | call schedule_tail[],0 | ||
| 60 | mov (REG_D0,fp),d0 | ||
| 61 | mov (REG_A0,fp),a0 | ||
| 62 | calls (a0) | ||
| 63 | jmp sys_exit | ||
| 64 | |||
| 58 | ############################################################################### | 65 | ############################################################################### |
| 59 | # | 66 | # |
| 60 | # system call handler | 67 | # system call handler |
diff --git a/arch/mn10300/kernel/internal.h b/arch/mn10300/kernel/internal.h index 2df440105a80..561785581f6c 100644 --- a/arch/mn10300/kernel/internal.h +++ b/arch/mn10300/kernel/internal.h | |||
| @@ -15,14 +15,10 @@ struct clocksource; | |||
| 15 | struct clock_event_device; | 15 | struct clock_event_device; |
| 16 | 16 | ||
| 17 | /* | 17 | /* |
| 18 | * kthread.S | ||
| 19 | */ | ||
| 20 | extern int kernel_thread_helper(int); | ||
| 21 | |||
| 22 | /* | ||
| 23 | * entry.S | 18 | * entry.S |
| 24 | */ | 19 | */ |
| 25 | extern void ret_from_fork(struct task_struct *) __attribute__((noreturn)); | 20 | extern void ret_from_fork(struct task_struct *) __attribute__((noreturn)); |
| 21 | extern void ret_from_kernel_thread(struct task_struct *) __attribute__((noreturn)); | ||
| 26 | 22 | ||
| 27 | /* | 23 | /* |
| 28 | * smp-low.S | 24 | * smp-low.S |
diff --git a/arch/mn10300/kernel/kthread.S b/arch/mn10300/kernel/kthread.S deleted file mode 100644 index b5ae467ac5ec..000000000000 --- a/arch/mn10300/kernel/kthread.S +++ /dev/null | |||
| @@ -1,31 +0,0 @@ | |||
| 1 | /* MN10300 Kernel thread trampoline function | ||
| 2 | * | ||
| 3 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. | ||
| 4 | * Written by Mark Salter (msalter@redhat.com) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public Licence | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the Licence, or (at your option) any later version. | ||
| 10 | */ | ||
| 11 | .text | ||
| 12 | |||
| 13 | ############################################################################### | ||
| 14 | # | ||
| 15 | # kernel_thread_helper - trampoline for kernel_thread() | ||
| 16 | # | ||
| 17 | # On entry: | ||
| 18 | # A2 = address of function to call | ||
| 19 | # D2 = function argument | ||
| 20 | # | ||
| 21 | ############################################################################### | ||
| 22 | .globl kernel_thread_helper | ||
| 23 | .type kernel_thread_helper,@function | ||
| 24 | kernel_thread_helper: | ||
| 25 | mov do_exit,d1 | ||
| 26 | mov d1,(sp) | ||
| 27 | mov d1,mdr | ||
| 28 | mov d2,d0 | ||
| 29 | jmp (a2) | ||
| 30 | |||
| 31 | .size kernel_thread_helper,.-kernel_thread_helper | ||
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c index 7dab0cd36466..be87fbee4da5 100644 --- a/arch/mn10300/kernel/process.c +++ b/arch/mn10300/kernel/process.c | |||
| @@ -166,13 +166,11 @@ void show_regs(struct pt_regs *regs) | |||
| 166 | */ | 166 | */ |
| 167 | int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | 167 | int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) |
| 168 | { | 168 | { |
| 169 | struct pt_regs regs; | 169 | struct pt_regs regs = { |
| 170 | .a0 = (unsigned long) fn; | ||
| 171 | .d0 = (unsigned long) arg; | ||
| 172 | }; | ||
| 170 | 173 | ||
| 171 | memset(®s, 0, sizeof(regs)); | ||
| 172 | |||
| 173 | regs.a2 = (unsigned long) fn; | ||
| 174 | regs.d2 = (unsigned long) arg; | ||
| 175 | regs.pc = (unsigned long) kernel_thread_helper; | ||
| 176 | local_save_flags(regs.epsw); | 174 | local_save_flags(regs.epsw); |
| 177 | regs.epsw |= EPSW_IE | EPSW_IM_7; | 175 | regs.epsw |= EPSW_IE | EPSW_IM_7; |
| 178 | 176 | ||
| @@ -180,7 +178,6 @@ int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | |||
| 180 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, | 178 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, |
| 181 | NULL, NULL); | 179 | NULL, NULL); |
| 182 | } | 180 | } |
| 183 | EXPORT_SYMBOL(kernel_thread); | ||
| 184 | 181 | ||
| 185 | /* | 182 | /* |
| 186 | * free current thread data structures etc.. | 183 | * free current thread data structures etc.. |
| @@ -227,49 +224,36 @@ int copy_thread(unsigned long clone_flags, | |||
| 227 | struct task_struct *p, struct pt_regs *kregs) | 224 | struct task_struct *p, struct pt_regs *kregs) |
| 228 | { | 225 | { |
| 229 | struct thread_info *ti = task_thread_info(p); | 226 | struct thread_info *ti = task_thread_info(p); |
| 230 | struct pt_regs *c_uregs, *c_kregs, *uregs; | 227 | struct pt_regs *c_regs; |
| 231 | unsigned long c_ksp; | 228 | unsigned long c_ksp; |
| 232 | 229 | ||
| 233 | uregs = current->thread.uregs; | ||
| 234 | |||
| 235 | c_ksp = (unsigned long) task_stack_page(p) + THREAD_SIZE; | 230 | c_ksp = (unsigned long) task_stack_page(p) + THREAD_SIZE; |
| 236 | 231 | ||
| 237 | /* allocate the userspace exception frame and set it up */ | 232 | /* allocate the userspace exception frame and set it up */ |
| 238 | c_ksp -= sizeof(struct pt_regs); | 233 | c_ksp -= sizeof(struct pt_regs); |
| 239 | c_uregs = (struct pt_regs *) c_ksp; | 234 | c_regs = (struct pt_regs *) c_ksp; |
| 240 | 235 | ||
| 241 | p->thread.uregs = c_uregs; | 236 | p->thread.uregs = c_regs; |
| 242 | *c_uregs = *uregs; | 237 | *c_regs = *kregs; |
| 243 | c_uregs->sp = c_usp; | 238 | c_regs->sp = c_usp; |
| 244 | c_uregs->epsw &= ~EPSW_FE; /* my FPU */ | 239 | c_regs->epsw &= ~EPSW_FE; /* my FPU */ |
| 245 | 240 | ||
| 246 | c_ksp -= 12; /* allocate function call ABI slack */ | 241 | c_ksp -= 12; /* allocate function call ABI slack */ |
| 247 | 242 | ||
| 248 | /* the new TLS pointer is passed in as arg #5 to sys_clone() */ | 243 | /* the new TLS pointer is passed in as arg #5 to sys_clone() */ |
| 249 | if (clone_flags & CLONE_SETTLS) | 244 | if (clone_flags & CLONE_SETTLS) |
| 250 | c_uregs->e2 = current_frame()->d3; | 245 | c_regs->e2 = current_frame()->d3; |
| 251 | |||
| 252 | /* set up the return kernel frame if called from kernel_thread() */ | ||
| 253 | c_kregs = c_uregs; | ||
| 254 | if (kregs != uregs) { | ||
| 255 | c_ksp -= sizeof(struct pt_regs); | ||
| 256 | c_kregs = (struct pt_regs *) c_ksp; | ||
| 257 | *c_kregs = *kregs; | ||
| 258 | c_kregs->sp = c_usp; | ||
| 259 | c_kregs->next = c_uregs; | ||
| 260 | #ifdef CONFIG_MN10300_CURRENT_IN_E2 | ||
| 261 | c_kregs->e2 = (unsigned long) p; /* current */ | ||
| 262 | #endif | ||
| 263 | 246 | ||
| 264 | c_ksp -= 12; /* allocate function call ABI slack */ | 247 | if (unlikely(!user_mode(kregs))) |
| 265 | } | 248 | p->thread.pc = (unsigned long) ret_from_kernel_thread; |
| 249 | else | ||
| 250 | p->thread.pc = (unsigned long) ret_from_fork; | ||
| 266 | 251 | ||
| 267 | /* set up things up so the scheduler can start the new task */ | 252 | /* set up things up so the scheduler can start the new task */ |
| 268 | ti->frame = c_kregs; | 253 | ti->frame = c_regs; |
| 269 | p->thread.a3 = (unsigned long) c_kregs; | 254 | p->thread.a3 = (unsigned long) c_regs; |
| 270 | p->thread.sp = c_ksp; | 255 | p->thread.sp = c_ksp; |
| 271 | p->thread.pc = (unsigned long) ret_from_fork; | 256 | p->thread.wchan = p->thread.pc; |
| 272 | p->thread.wchan = (unsigned long) ret_from_fork; | ||
| 273 | p->thread.usp = c_usp; | 257 | p->thread.usp = c_usp; |
| 274 | 258 | ||
| 275 | return 0; | 259 | return 0; |
