Skip to content

Commit f9a7e02

Browse files
author
Al Viro
committed
s390: switch to generic kernel_thread()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent 37fe5d4 commit f9a7e02

File tree

3 files changed

+34
-40
lines changed

3 files changed

+34
-40
lines changed

arch/s390/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ config S390
125125
select GENERIC_CLOCKEVENTS
126126
select KTIME_SCALAR if 32BIT
127127
select HAVE_ARCH_SECCOMP_FILTER
128+
select GENERIC_KERNEL_THREAD
128129

129130
config SCHED_OMIT_FRAME_POINTER
130131
def_bool y

arch/s390/include/asm/processor.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@ struct seq_file;
135135

136136
/* Free all resources held by a thread. */
137137
extern void release_thread(struct task_struct *);
138-
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
139138

140139
/*
141140
* Return saved PC of a blocked thread.

arch/s390/kernel/process.c

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -98,25 +98,6 @@ void cpu_idle(void)
9898

9999
extern void __kprobes kernel_thread_starter(void);
100100

101-
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
102-
{
103-
struct pt_regs regs;
104-
105-
memset(&regs, 0, sizeof(regs));
106-
regs.psw.mask = psw_kernel_bits |
107-
PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
108-
regs.psw.addr = (unsigned long) kernel_thread_starter | PSW_ADDR_AMODE;
109-
regs.gprs[9] = (unsigned long) fn;
110-
regs.gprs[10] = (unsigned long) arg;
111-
regs.gprs[11] = (unsigned long) do_exit;
112-
regs.orig_gpr2 = -1;
113-
114-
/* Ok, create the new process.. */
115-
return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
116-
0, &regs, 0, NULL, NULL);
117-
}
118-
EXPORT_SYMBOL(kernel_thread);
119-
120101
/*
121102
* Free current thread data structures etc..
122103
*/
@@ -133,7 +114,7 @@ void release_thread(struct task_struct *dead_task)
133114
}
134115

135116
int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
136-
unsigned long unused,
117+
unsigned long arg,
137118
struct task_struct *p, struct pt_regs *regs)
138119
{
139120
struct thread_info *ti;
@@ -145,20 +126,44 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
145126

146127
frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
147128
p->thread.ksp = (unsigned long) frame;
148-
/* Store access registers to kernel stack of new process. */
149-
frame->childregs = *regs;
150-
frame->childregs.gprs[2] = 0; /* child returns 0 on fork. */
151-
frame->childregs.gprs[15] = new_stackp;
152-
frame->sf.back_chain = 0;
129+
/* Save access registers to new thread structure. */
130+
save_access_regs(&p->thread.acrs[0]);
131+
/* start new process with ar4 pointing to the correct address space */
132+
p->thread.mm_segment = get_fs();
133+
/* Don't copy debug registers */
134+
memset(&p->thread.per_user, 0, sizeof(p->thread.per_user));
135+
memset(&p->thread.per_event, 0, sizeof(p->thread.per_event));
136+
clear_tsk_thread_flag(p, TIF_SINGLE_STEP);
137+
clear_tsk_thread_flag(p, TIF_PER_TRAP);
138+
/* Initialize per thread user and system timer values */
139+
ti = task_thread_info(p);
140+
ti->user_timer = 0;
141+
ti->system_timer = 0;
153142

143+
frame->sf.back_chain = 0;
154144
/* new return point is ret_from_fork */
155145
frame->sf.gprs[8] = (unsigned long) ret_from_fork;
156-
157146
/* fake return stack for resume(), don't go back to schedule */
158147
frame->sf.gprs[9] = (unsigned long) frame;
159148

160-
/* Save access registers to new thread structure. */
161-
save_access_regs(&p->thread.acrs[0]);
149+
/* Store access registers to kernel stack of new process. */
150+
if (unlikely(!regs)) {
151+
/* kernel thread */
152+
memset(&frame->childregs, 0, sizeof(struct pt_regs));
153+
frame->childregs.psw.mask = psw_kernel_bits | PSW_MASK_DAT |
154+
PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
155+
frame->childregs.psw.addr = PSW_ADDR_AMODE |
156+
(unsigned long) kernel_thread_starter;
157+
frame->childregs.gprs[9] = new_stackp; /* function */
158+
frame->childregs.gprs[10] = arg;
159+
frame->childregs.gprs[11] = (unsigned long) do_exit;
160+
frame->childregs.orig_gpr2 = -1;
161+
162+
return 0;
163+
}
164+
frame->childregs = *regs;
165+
frame->childregs.gprs[2] = 0; /* child returns 0 on fork. */
166+
frame->childregs.gprs[15] = new_stackp;
162167

163168
#ifndef CONFIG_64BIT
164169
/*
@@ -184,17 +189,6 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
184189
}
185190
}
186191
#endif /* CONFIG_64BIT */
187-
/* start new process with ar4 pointing to the correct address space */
188-
p->thread.mm_segment = get_fs();
189-
/* Don't copy debug registers */
190-
memset(&p->thread.per_user, 0, sizeof(p->thread.per_user));
191-
memset(&p->thread.per_event, 0, sizeof(p->thread.per_event));
192-
clear_tsk_thread_flag(p, TIF_SINGLE_STEP);
193-
clear_tsk_thread_flag(p, TIF_PER_TRAP);
194-
/* Initialize per thread user and system timer values */
195-
ti = task_thread_info(p);
196-
ti->user_timer = 0;
197-
ti->system_timer = 0;
198192
return 0;
199193
}
200194

0 commit comments

Comments
 (0)