Loading arch/avr32/Kconfig +2 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ config AVR32 select GENERIC_CLOCKEVENTS select HAVE_MOD_ARCH_SPECIFIC select MODULES_USE_ELF_RELA select GENERIC_KERNEL_THREAD select GENERIC_KERNEL_EXECVE help AVR32 is a high-performance 32-bit RISC microprocessor core, designed for cost-sensitive embedded applications, with particular Loading arch/avr32/include/asm/processor.h +0 −3 Original line number Diff line number Diff line Loading @@ -142,9 +142,6 @@ struct task_struct; /* Free all resources held by a thread */ extern void release_thread(struct task_struct *); /* Create a kernel thread without removing it from tasklists */ extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); /* Return saved PC of a blocked thread */ #define thread_saved_pc(tsk) ((tsk)->thread.cpu_context.pc) Loading arch/avr32/kernel/Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ extra-y := head.o vmlinux.lds obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o obj-y += syscall_table.o syscall-stubs.o irq.o obj-y += setup.o traps.o ocd.o ptrace.o obj-y += signal.o sys_avr32.o process.o time.o obj-y += signal.o process.o time.o obj-y += switch_to.o cpu.o obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o obj-$(CONFIG_KPROBES) += kprobes.o Loading arch/avr32/kernel/entry-avr32b.S +8 −6 Original line number Diff line number Diff line Loading @@ -251,13 +251,15 @@ syscall_badsys: .global ret_from_fork ret_from_fork: call schedule_tail mov r12, 0 rjmp syscall_return /* check for syscall tracing */ get_thread_info r0 ld.w r1, r0[TI_flags] andl r1, _TIF_ALLWORK_MASK, COH brne syscall_exit_work rjmp syscall_exit_cont .global ret_from_kernel_thread ret_from_kernel_thread: call schedule_tail mov r12, r0 mov lr, r2 /* syscall_return */ mov pc, r1 syscall_trace_enter: pushm r8-r12 Loading arch/avr32/kernel/process.c +17 −50 Original line number Diff line number Diff line Loading @@ -68,44 +68,6 @@ void machine_restart(char *cmd) while (1) ; } /* * PC is actually discarded when returning from a system call -- the * return address must be stored in LR. This function will make sure * LR points to do_exit before starting the thread. * * Also, when returning from fork(), r12 is 0, so we must copy the * argument as well. * * r0 : The argument to the main thread function * r1 : The address of do_exit * r2 : The address of the main thread function */ asmlinkage extern void kernel_thread_helper(void); __asm__(" .type kernel_thread_helper, @function\n" "kernel_thread_helper:\n" " mov r12, r0\n" " mov lr, r2\n" " mov pc, r1\n" " .size kernel_thread_helper, . - kernel_thread_helper"); int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) { struct pt_regs regs; memset(®s, 0, sizeof(regs)); regs.r0 = (unsigned long)arg; regs.r1 = (unsigned long)fn; regs.r2 = (unsigned long)do_exit; regs.lr = (unsigned long)kernel_thread_helper; regs.pc = (unsigned long)kernel_thread_helper; regs.sr = MODE_SUPERVISOR; return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); } EXPORT_SYMBOL(kernel_thread); /* * Free current thread data structures etc */ Loading Loading @@ -332,26 +294,31 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) } asmlinkage void ret_from_fork(void); asmlinkage void ret_from_kernel_thread(void); asmlinkage void syscall_return(void); int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long unused, unsigned long arg, struct task_struct *p, struct pt_regs *regs) { struct pt_regs *childregs; childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long)task_stack_page(p))) - 1; struct pt_regs *childregs = task_pt_regs(p); if (unlikely(!regs)) { memset(childregs, 0, sizeof(struct pt_regs)); p->thread.cpu_context.r0 = arg; p->thread.cpu_context.r1 = usp; /* fn */ p->thread.cpu_context.r2 = syscall_return; p->thread.cpu_context.pc = (unsigned long)ret_from_kernel_thread; childregs->sr = MODE_SUPERVISOR; } else { *childregs = *regs; if (user_mode(regs)) childregs->sp = usp; else childregs->sp = (unsigned long)task_stack_page(p) + THREAD_SIZE; childregs->r12 = 0; /* Set return value for child */ p->thread.cpu_context.pc = (unsigned long)ret_from_fork; } p->thread.cpu_context.sr = MODE_SUPERVISOR | SR_GM; p->thread.cpu_context.ksp = (unsigned long)childregs; p->thread.cpu_context.pc = (unsigned long)ret_from_fork; clear_tsk_thread_flag(p, TIF_DEBUG); if ((clone_flags & CLONE_PTRACE) && test_thread_flag(TIF_DEBUG)) Loading Loading
arch/avr32/Kconfig +2 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ config AVR32 select GENERIC_CLOCKEVENTS select HAVE_MOD_ARCH_SPECIFIC select MODULES_USE_ELF_RELA select GENERIC_KERNEL_THREAD select GENERIC_KERNEL_EXECVE help AVR32 is a high-performance 32-bit RISC microprocessor core, designed for cost-sensitive embedded applications, with particular Loading
arch/avr32/include/asm/processor.h +0 −3 Original line number Diff line number Diff line Loading @@ -142,9 +142,6 @@ struct task_struct; /* Free all resources held by a thread */ extern void release_thread(struct task_struct *); /* Create a kernel thread without removing it from tasklists */ extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); /* Return saved PC of a blocked thread */ #define thread_saved_pc(tsk) ((tsk)->thread.cpu_context.pc) Loading
arch/avr32/kernel/Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ extra-y := head.o vmlinux.lds obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o obj-y += syscall_table.o syscall-stubs.o irq.o obj-y += setup.o traps.o ocd.o ptrace.o obj-y += signal.o sys_avr32.o process.o time.o obj-y += signal.o process.o time.o obj-y += switch_to.o cpu.o obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o obj-$(CONFIG_KPROBES) += kprobes.o Loading
arch/avr32/kernel/entry-avr32b.S +8 −6 Original line number Diff line number Diff line Loading @@ -251,13 +251,15 @@ syscall_badsys: .global ret_from_fork ret_from_fork: call schedule_tail mov r12, 0 rjmp syscall_return /* check for syscall tracing */ get_thread_info r0 ld.w r1, r0[TI_flags] andl r1, _TIF_ALLWORK_MASK, COH brne syscall_exit_work rjmp syscall_exit_cont .global ret_from_kernel_thread ret_from_kernel_thread: call schedule_tail mov r12, r0 mov lr, r2 /* syscall_return */ mov pc, r1 syscall_trace_enter: pushm r8-r12 Loading
arch/avr32/kernel/process.c +17 −50 Original line number Diff line number Diff line Loading @@ -68,44 +68,6 @@ void machine_restart(char *cmd) while (1) ; } /* * PC is actually discarded when returning from a system call -- the * return address must be stored in LR. This function will make sure * LR points to do_exit before starting the thread. * * Also, when returning from fork(), r12 is 0, so we must copy the * argument as well. * * r0 : The argument to the main thread function * r1 : The address of do_exit * r2 : The address of the main thread function */ asmlinkage extern void kernel_thread_helper(void); __asm__(" .type kernel_thread_helper, @function\n" "kernel_thread_helper:\n" " mov r12, r0\n" " mov lr, r2\n" " mov pc, r1\n" " .size kernel_thread_helper, . - kernel_thread_helper"); int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) { struct pt_regs regs; memset(®s, 0, sizeof(regs)); regs.r0 = (unsigned long)arg; regs.r1 = (unsigned long)fn; regs.r2 = (unsigned long)do_exit; regs.lr = (unsigned long)kernel_thread_helper; regs.pc = (unsigned long)kernel_thread_helper; regs.sr = MODE_SUPERVISOR; return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); } EXPORT_SYMBOL(kernel_thread); /* * Free current thread data structures etc */ Loading Loading @@ -332,26 +294,31 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) } asmlinkage void ret_from_fork(void); asmlinkage void ret_from_kernel_thread(void); asmlinkage void syscall_return(void); int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long unused, unsigned long arg, struct task_struct *p, struct pt_regs *regs) { struct pt_regs *childregs; childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long)task_stack_page(p))) - 1; struct pt_regs *childregs = task_pt_regs(p); if (unlikely(!regs)) { memset(childregs, 0, sizeof(struct pt_regs)); p->thread.cpu_context.r0 = arg; p->thread.cpu_context.r1 = usp; /* fn */ p->thread.cpu_context.r2 = syscall_return; p->thread.cpu_context.pc = (unsigned long)ret_from_kernel_thread; childregs->sr = MODE_SUPERVISOR; } else { *childregs = *regs; if (user_mode(regs)) childregs->sp = usp; else childregs->sp = (unsigned long)task_stack_page(p) + THREAD_SIZE; childregs->r12 = 0; /* Set return value for child */ p->thread.cpu_context.pc = (unsigned long)ret_from_fork; } p->thread.cpu_context.sr = MODE_SUPERVISOR | SR_GM; p->thread.cpu_context.ksp = (unsigned long)childregs; p->thread.cpu_context.pc = (unsigned long)ret_from_fork; clear_tsk_thread_flag(p, TIF_DEBUG); if ((clone_flags & CLONE_PTRACE) && test_thread_flag(TIF_DEBUG)) Loading