diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-13 03:22:53 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-14 23:06:52 -0400 |
commit | ee1e17c69eb3c843d283eb3fbed1616ed9a122eb (patch) | |
tree | 18c4beae1331663fadec51f914f2ef50ed1be7fb /arch/blackfin | |
parent | ddffeb8c4d0331609ef2581d84de4d763607bd37 (diff) |
blackfin: convert kernel_thread() and kernel_execve() to generic ones
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/blackfin')
-rw-r--r-- | arch/blackfin/Kconfig | 2 | ||||
-rw-r--r-- | arch/blackfin/include/asm/processor.h | 2 | ||||
-rw-r--r-- | arch/blackfin/kernel/entry.S | 22 | ||||
-rw-r--r-- | arch/blackfin/kernel/process.c | 55 | ||||
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 55 |
5 files changed, 27 insertions, 109 deletions
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index b6f3ad5441c5..ab9ff4075f4d 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig | |||
@@ -45,6 +45,8 @@ config BLACKFIN | |||
45 | select ARCH_USES_GETTIMEOFFSET if !GENERIC_CLOCKEVENTS | 45 | select ARCH_USES_GETTIMEOFFSET if !GENERIC_CLOCKEVENTS |
46 | select HAVE_MOD_ARCH_SPECIFIC | 46 | select HAVE_MOD_ARCH_SPECIFIC |
47 | select MODULES_USE_ELF_RELA | 47 | select MODULES_USE_ELF_RELA |
48 | select GENERIC_KERNEL_THREAD | ||
49 | select GENERIC_KERNEL_EXECVE | ||
48 | 50 | ||
49 | config GENERIC_CSUM | 51 | config GENERIC_CSUM |
50 | def_bool y | 52 | def_bool y |
diff --git a/arch/blackfin/include/asm/processor.h b/arch/blackfin/include/asm/processor.h index 4ef7cfe43ceb..d0e72e9475a6 100644 --- a/arch/blackfin/include/asm/processor.h +++ b/arch/blackfin/include/asm/processor.h | |||
@@ -75,8 +75,6 @@ static inline void release_thread(struct task_struct *dead_task) | |||
75 | { | 75 | { |
76 | } | 76 | } |
77 | 77 | ||
78 | extern int kernel_thread(int (*fn) (void *), void *arg, unsigned long flags); | ||
79 | |||
80 | /* | 78 | /* |
81 | * Free current thread data structures etc.. | 79 | * Free current thread data structures etc.. |
82 | */ | 80 | */ |
diff --git a/arch/blackfin/kernel/entry.S b/arch/blackfin/kernel/entry.S index f33792cc1a0d..78f4f637e155 100644 --- a/arch/blackfin/kernel/entry.S +++ b/arch/blackfin/kernel/entry.S | |||
@@ -46,22 +46,16 @@ ENTRY(_ret_from_fork) | |||
46 | SP += -12; | 46 | SP += -12; |
47 | pseudo_long_call _schedule_tail, p5; | 47 | pseudo_long_call _schedule_tail, p5; |
48 | SP += 12; | 48 | SP += 12; |
49 | r0 = [sp + PT_IPEND]; | 49 | p1 = [sp++]; |
50 | cc = bittst(r0,1); | 50 | r0 = [sp++]; |
51 | if cc jump .Lin_kernel; | 51 | cc = p1 == 0; |
52 | if cc jump .Lfork; | ||
53 | sp += -12; | ||
54 | call (p1); | ||
55 | sp += 12; | ||
56 | .Lfork: | ||
52 | RESTORE_CONTEXT | 57 | RESTORE_CONTEXT |
53 | rti; | 58 | rti; |
54 | .Lin_kernel: | ||
55 | bitclr(r0,1); | ||
56 | [sp + PT_IPEND] = r0; | ||
57 | /* do a 'fake' RTI by jumping to [RETI] | ||
58 | * to avoid clearing supervisor mode in child | ||
59 | */ | ||
60 | r0 = [sp + PT_PC]; | ||
61 | [sp + PT_P0] = r0; | ||
62 | |||
63 | RESTORE_ALL_SYS | ||
64 | jump (p0); | ||
65 | ENDPROC(_ret_from_fork) | 59 | ENDPROC(_ret_from_fork) |
66 | 60 | ||
67 | ENTRY(_sys_vfork) | 61 | ENTRY(_sys_vfork) |
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index bb1cc721fcf7..9945b94c63d4 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c | |||
@@ -102,40 +102,6 @@ void cpu_idle(void) | |||
102 | } | 102 | } |
103 | 103 | ||
104 | /* | 104 | /* |
105 | * This gets run with P1 containing the | ||
106 | * function to call, and R1 containing | ||
107 | * the "args". Note P0 is clobbered on the way here. | ||
108 | */ | ||
109 | void kernel_thread_helper(void); | ||
110 | __asm__(".section .text\n" | ||
111 | ".align 4\n" | ||
112 | "_kernel_thread_helper:\n\t" | ||
113 | "\tsp += -12;\n\t" | ||
114 | "\tr0 = r1;\n\t" "\tcall (p1);\n\t" "\tcall _do_exit;\n" ".previous"); | ||
115 | |||
116 | /* | ||
117 | * Create a kernel thread. | ||
118 | */ | ||
119 | pid_t kernel_thread(int (*fn) (void *), void *arg, unsigned long flags) | ||
120 | { | ||
121 | struct pt_regs regs; | ||
122 | |||
123 | memset(®s, 0, sizeof(regs)); | ||
124 | |||
125 | regs.r1 = (unsigned long)arg; | ||
126 | regs.p1 = (unsigned long)fn; | ||
127 | regs.pc = (unsigned long)kernel_thread_helper; | ||
128 | regs.orig_p0 = -1; | ||
129 | /* Set bit 2 to tell ret_from_fork we should be returning to kernel | ||
130 | mode. */ | ||
131 | regs.ipend = 0x8002; | ||
132 | __asm__ __volatile__("%0 = syscfg;":"=da"(regs.syscfg):); | ||
133 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, | ||
134 | NULL); | ||
135 | } | ||
136 | EXPORT_SYMBOL(kernel_thread); | ||
137 | |||
138 | /* | ||
139 | * Do necessary setup to start up a newly executed thread. | 105 | * Do necessary setup to start up a newly executed thread. |
140 | * | 106 | * |
141 | * pass the data segment into user programs if it exists, | 107 | * pass the data segment into user programs if it exists, |
@@ -193,13 +159,26 @@ copy_thread(unsigned long clone_flags, | |||
193 | struct task_struct *p, struct pt_regs *regs) | 159 | struct task_struct *p, struct pt_regs *regs) |
194 | { | 160 | { |
195 | struct pt_regs *childregs; | 161 | struct pt_regs *childregs; |
162 | unsigned long *v; | ||
196 | 163 | ||
197 | childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; | 164 | childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; |
198 | *childregs = *regs; | 165 | v = ((unsigned long *)childregs) - 2; |
199 | childregs->r0 = 0; | 166 | if (unlikely(!regs)) { |
167 | memset(childregs, 0, sizeof(struct pt_regs)); | ||
168 | v[0] = usp; | ||
169 | v[1] = topstk; | ||
170 | childregs->orig_p0 = -1; | ||
171 | childregs->ipend = 0x8000; | ||
172 | __asm__ __volatile__("%0 = syscfg;":"=da"(childregs->syscfg):); | ||
173 | p->thread.usp = 0; | ||
174 | } else { | ||
175 | *childregs = *regs; | ||
176 | childregs->r0 = 0; | ||
177 | p->thread.usp = usp; | ||
178 | v[0] = v[1] = 0; | ||
179 | } | ||
200 | 180 | ||
201 | p->thread.usp = usp; | 181 | p->thread.ksp = (unsigned long)v; |
202 | p->thread.ksp = (unsigned long)childregs; | ||
203 | p->thread.pc = (unsigned long)ret_from_fork; | 182 | p->thread.pc = (unsigned long)ret_from_fork; |
204 | 183 | ||
205 | return 0; | 184 | return 0; |
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 1c3d2c5bb0bb..4a38c68e2dde 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S | |||
@@ -530,61 +530,6 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/ | |||
530 | jump .Lsyscall_really_exit; | 530 | jump .Lsyscall_really_exit; |
531 | ENDPROC(_trap) | 531 | ENDPROC(_trap) |
532 | 532 | ||
533 | ENTRY(_kernel_execve) | ||
534 | link SIZEOF_PTREGS; | ||
535 | p0 = sp; | ||
536 | r3 = SIZEOF_PTREGS / 4; | ||
537 | r4 = 0(x); | ||
538 | .Lclear_regs: | ||
539 | [p0++] = r4; | ||
540 | r3 += -1; | ||
541 | cc = r3 == 0; | ||
542 | if !cc jump .Lclear_regs (bp); | ||
543 | |||
544 | p0 = sp; | ||
545 | sp += -16; | ||
546 | [sp + 12] = p0; | ||
547 | pseudo_long_call _do_execve, p5; | ||
548 | SP += 16; | ||
549 | cc = r0 == 0; | ||
550 | if ! cc jump .Lexecve_failed; | ||
551 | /* Success. Copy our temporary pt_regs to the top of the kernel | ||
552 | * stack and do a normal exception return. | ||
553 | */ | ||
554 | r1 = sp; | ||
555 | r0 = (-KERNEL_STACK_SIZE) (x); | ||
556 | r1 = r1 & r0; | ||
557 | p2 = r1; | ||
558 | p3 = [p2]; | ||
559 | r0 = KERNEL_STACK_SIZE - 4 (z); | ||
560 | p1 = r0; | ||
561 | p1 = p1 + p2; | ||
562 | |||
563 | p0 = fp; | ||
564 | r4 = [p0--]; | ||
565 | r3 = SIZEOF_PTREGS / 4; | ||
566 | .Lcopy_regs: | ||
567 | r4 = [p0--]; | ||
568 | [p1--] = r4; | ||
569 | r3 += -1; | ||
570 | cc = r3 == 0; | ||
571 | if ! cc jump .Lcopy_regs (bp); | ||
572 | |||
573 | r0 = (KERNEL_STACK_SIZE - SIZEOF_PTREGS) (z); | ||
574 | p1 = r0; | ||
575 | p1 = p1 + p2; | ||
576 | sp = p1; | ||
577 | r0 = syscfg; | ||
578 | [SP + PT_SYSCFG] = r0; | ||
579 | [p3 + (TASK_THREAD + THREAD_KSP)] = sp; | ||
580 | |||
581 | RESTORE_CONTEXT; | ||
582 | rti; | ||
583 | .Lexecve_failed: | ||
584 | unlink; | ||
585 | rts; | ||
586 | ENDPROC(_kernel_execve) | ||
587 | |||
588 | ENTRY(_system_call) | 533 | ENTRY(_system_call) |
589 | /* Store IPEND */ | 534 | /* Store IPEND */ |
590 | p2.l = lo(IPEND); | 535 | p2.l = lo(IPEND); |