aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-09-21 20:48:32 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-09-30 23:03:03 -0400
commitf9a7e025dfc28783fd2b05812e663251acf4bf21 (patch)
treeb48ea29a01293afa82be905797268b7997852def /arch/s390
parent37fe5d41f6403b0ea84c1586548bf1b03f834af0 (diff)
s390: switch to generic kernel_thread()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/Kconfig1
-rw-r--r--arch/s390/include/asm/processor.h1
-rw-r--r--arch/s390/kernel/process.c72
3 files changed, 34 insertions, 40 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 107610e01a29..57442393bac7 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -125,6 +125,7 @@ config S390
125 select GENERIC_CLOCKEVENTS 125 select GENERIC_CLOCKEVENTS
126 select KTIME_SCALAR if 32BIT 126 select KTIME_SCALAR if 32BIT
127 select HAVE_ARCH_SECCOMP_FILTER 127 select HAVE_ARCH_SECCOMP_FILTER
128 select GENERIC_KERNEL_THREAD
128 129
129config SCHED_OMIT_FRAME_POINTER 130config SCHED_OMIT_FRAME_POINTER
130 def_bool y 131 def_bool y
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index 0bc77619c3a3..da6f5baeee5c 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -135,7 +135,6 @@ struct seq_file;
135 135
136/* Free all resources held by a thread. */ 136/* Free all resources held by a thread. */
137extern void release_thread(struct task_struct *); 137extern void release_thread(struct task_struct *);
138extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
139 138
140/* 139/*
141 * Return saved PC of a blocked thread. 140 * Return saved PC of a blocked thread.
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 2868a364ff94..bab088de4569 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -98,25 +98,6 @@ void cpu_idle(void)
98 98
99extern void __kprobes kernel_thread_starter(void); 99extern void __kprobes kernel_thread_starter(void);
100 100
101int 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}
118EXPORT_SYMBOL(kernel_thread);
119
120/* 101/*
121 * Free current thread data structures etc.. 102 * Free current thread data structures etc..
122 */ 103 */
@@ -133,7 +114,7 @@ void release_thread(struct task_struct *dead_task)
133} 114}
134 115
135int copy_thread(unsigned long clone_flags, unsigned long new_stackp, 116int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
136 unsigned long unused, 117 unsigned long arg,
137 struct task_struct *p, struct pt_regs *regs) 118 struct task_struct *p, struct pt_regs *regs)
138{ 119{
139 struct thread_info *ti; 120 struct thread_info *ti;
@@ -145,20 +126,44 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
145 126
146 frame = container_of(task_pt_regs(p), struct fake_frame, childregs); 127 frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
147 p->thread.ksp = (unsigned long) frame; 128 p->thread.ksp = (unsigned long) frame;
148 /* Store access registers to kernel stack of new process. */ 129 /* Save access registers to new thread structure. */
149 frame->childregs = *regs; 130 save_access_regs(&p->thread.acrs[0]);
150 frame->childregs.gprs[2] = 0; /* child returns 0 on fork. */ 131 /* start new process with ar4 pointing to the correct address space */
151 frame->childregs.gprs[15] = new_stackp; 132 p->thread.mm_segment = get_fs();
152 frame->sf.back_chain = 0; 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;
153 142
143 frame->sf.back_chain = 0;
154 /* new return point is ret_from_fork */ 144 /* new return point is ret_from_fork */
155 frame->sf.gprs[8] = (unsigned long) ret_from_fork; 145 frame->sf.gprs[8] = (unsigned long) ret_from_fork;
156
157 /* fake return stack for resume(), don't go back to schedule */ 146 /* fake return stack for resume(), don't go back to schedule */
158 frame->sf.gprs[9] = (unsigned long) frame; 147 frame->sf.gprs[9] = (unsigned long) frame;
159 148
160 /* Save access registers to new thread structure. */ 149 /* Store access registers to kernel stack of new process. */
161 save_access_regs(&p->thread.acrs[0]); 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;
162 167
163#ifndef CONFIG_64BIT 168#ifndef CONFIG_64BIT
164 /* 169 /*
@@ -184,17 +189,6 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
184 } 189 }
185 } 190 }
186#endif /* CONFIG_64BIT */ 191#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;
198 return 0; 192 return 0;
199} 193}
200 194