aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/process.c')
-rw-r--r--arch/s390/kernel/process.c73
1 files changed, 35 insertions, 38 deletions
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 5cd38a90e64d..b48e961a38f6 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -1,18 +1,10 @@
1/* 1/*
2 * arch/s390/kernel/process.c 2 * This file handles the architecture dependent parts of process handling.
3 * 3 *
4 * S390 version 4 * Copyright IBM Corp. 1999,2009
5 * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
6 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), 6 * Hartmut Penner <hp@de.ibm.com>,
7 * Hartmut Penner (hp@de.ibm.com), 7 * Denis Joseph Barrow,
8 * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
9 *
10 * Derived from "arch/i386/kernel/process.c"
11 * Copyright (C) 1995, Linus Torvalds
12 */
13
14/*
15 * This file handles the architecture-dependent parts of process handling..
16 */ 8 */
17 9
18#include <linux/compiler.h> 10#include <linux/compiler.h>
@@ -47,6 +39,7 @@
47#include <asm/processor.h> 39#include <asm/processor.h>
48#include <asm/irq.h> 40#include <asm/irq.h>
49#include <asm/timer.h> 41#include <asm/timer.h>
42#include <asm/nmi.h>
50#include "entry.h" 43#include "entry.h"
51 44
52asmlinkage void ret_from_fork(void) asm ("ret_from_fork"); 45asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
@@ -76,7 +69,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
76 return sf->gprs[8]; 69 return sf->gprs[8];
77} 70}
78 71
79extern void s390_handle_mcck(void);
80/* 72/*
81 * The idle loop on a S390... 73 * The idle loop on a S390...
82 */ 74 */
@@ -149,6 +141,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
149 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 141 return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
150 0, &regs, 0, NULL, NULL); 142 0, &regs, 0, NULL, NULL);
151} 143}
144EXPORT_SYMBOL(kernel_thread);
152 145
153/* 146/*
154 * Free current thread data structures etc.. 147 * Free current thread data structures etc..
@@ -168,34 +161,35 @@ void release_thread(struct task_struct *dead_task)
168} 161}
169 162
170int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp, 163int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
171 unsigned long unused, 164 unsigned long unused,
172 struct task_struct * p, struct pt_regs * regs) 165 struct task_struct *p, struct pt_regs *regs)
173{ 166{
174 struct fake_frame 167 struct thread_info *ti;
175 { 168 struct fake_frame
176 struct stack_frame sf; 169 {
177 struct pt_regs childregs; 170 struct stack_frame sf;
178 } *frame; 171 struct pt_regs childregs;
179 172 } *frame;
180 frame = container_of(task_pt_regs(p), struct fake_frame, childregs); 173
181 p->thread.ksp = (unsigned long) frame; 174 frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
175 p->thread.ksp = (unsigned long) frame;
182 /* Store access registers to kernel stack of new process. */ 176 /* Store access registers to kernel stack of new process. */
183 frame->childregs = *regs; 177 frame->childregs = *regs;
184 frame->childregs.gprs[2] = 0; /* child returns 0 on fork. */ 178 frame->childregs.gprs[2] = 0; /* child returns 0 on fork. */
185 frame->childregs.gprs[15] = new_stackp; 179 frame->childregs.gprs[15] = new_stackp;
186 frame->sf.back_chain = 0; 180 frame->sf.back_chain = 0;
187 181
188 /* new return point is ret_from_fork */ 182 /* new return point is ret_from_fork */
189 frame->sf.gprs[8] = (unsigned long) ret_from_fork; 183 frame->sf.gprs[8] = (unsigned long) ret_from_fork;
190 184
191 /* fake return stack for resume(), don't go back to schedule */ 185 /* fake return stack for resume(), don't go back to schedule */
192 frame->sf.gprs[9] = (unsigned long) frame; 186 frame->sf.gprs[9] = (unsigned long) frame;
193 187
194 /* Save access registers to new thread structure. */ 188 /* Save access registers to new thread structure. */
195 save_access_regs(&p->thread.acrs[0]); 189 save_access_regs(&p->thread.acrs[0]);
196 190
197#ifndef CONFIG_64BIT 191#ifndef CONFIG_64BIT
198 /* 192 /*
199 * save fprs to current->thread.fp_regs to merge them with 193 * save fprs to current->thread.fp_regs to merge them with
200 * the emulated registers and then copy the result to the child. 194 * the emulated registers and then copy the result to the child.
201 */ 195 */
@@ -220,10 +214,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
220#endif /* CONFIG_64BIT */ 214#endif /* CONFIG_64BIT */
221 /* start new process with ar4 pointing to the correct address space */ 215 /* start new process with ar4 pointing to the correct address space */
222 p->thread.mm_segment = get_fs(); 216 p->thread.mm_segment = get_fs();
223 /* Don't copy debug registers */ 217 /* Don't copy debug registers */
224 memset(&p->thread.per_info,0,sizeof(p->thread.per_info)); 218 memset(&p->thread.per_info, 0, sizeof(p->thread.per_info));
225 219 /* Initialize per thread user and system timer values */
226 return 0; 220 ti = task_thread_info(p);
221 ti->user_timer = 0;
222 ti->system_timer = 0;
223 return 0;
227} 224}
228 225
229SYSCALL_DEFINE0(fork) 226SYSCALL_DEFINE0(fork)
@@ -311,7 +308,7 @@ out:
311int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs) 308int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs)
312{ 309{
313#ifndef CONFIG_64BIT 310#ifndef CONFIG_64BIT
314 /* 311 /*
315 * save fprs to current->thread.fp_regs to merge them with 312 * save fprs to current->thread.fp_regs to merge them with
316 * the emulated registers and then copy the result to the dump. 313 * the emulated registers and then copy the result to the dump.
317 */ 314 */
@@ -322,6 +319,7 @@ int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs)
322#endif /* CONFIG_64BIT */ 319#endif /* CONFIG_64BIT */
323 return 1; 320 return 1;
324} 321}
322EXPORT_SYMBOL(dump_fpu);
325 323
326unsigned long get_wchan(struct task_struct *p) 324unsigned long get_wchan(struct task_struct *p)
327{ 325{
@@ -346,4 +344,3 @@ unsigned long get_wchan(struct task_struct *p)
346 } 344 }
347 return 0; 345 return 0;
348} 346}
349