Blame view

arch/um/kernel/process.c 9.49 KB
995473aec   Jeff Dike   [PATCH] uml: file...
1
  /*
ba180fd43   Jeff Dike   uml: style fixes ...
2
   * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3
4
5
   * Copyright 2003 PathScale, Inc.
   * Licensed under the GPL
   */
c5d4bb171   Jeff Dike   uml: style fixes ...
6
7
8
  #include <linux/stddef.h>
  #include <linux/err.h>
  #include <linux/hardirq.h>
c5d4bb171   Jeff Dike   uml: style fixes ...
9
  #include <linux/mm.h>
6613c5e86   Alexey Dobriyan   uml: convert to s...
10
  #include <linux/module.h>
c5d4bb171   Jeff Dike   uml: style fixes ...
11
12
13
14
  #include <linux/personality.h>
  #include <linux/proc_fs.h>
  #include <linux/ptrace.h>
  #include <linux/random.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
15
  #include <linux/slab.h>
c5d4bb171   Jeff Dike   uml: style fixes ...
16
  #include <linux/sched.h>
6613c5e86   Alexey Dobriyan   uml: convert to s...
17
  #include <linux/seq_file.h>
c5d4bb171   Jeff Dike   uml: style fixes ...
18
19
20
21
  #include <linux/tick.h>
  #include <linux/threads.h>
  #include <asm/current.h>
  #include <asm/pgtable.h>
445c5786c   Al Viro   um: kill shared/t...
22
  #include <asm/mmu_context.h>
c5d4bb171   Jeff Dike   uml: style fixes ...
23
  #include <asm/uaccess.h>
4ff83ce11   Jeff Dike   uml: create as-la...
24
  #include "as-layout.h"
ba180fd43   Jeff Dike   uml: style fixes ...
25
  #include "kern_util.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
  #include "os.h"
77bf44003   Jeff Dike   uml: remove code ...
27
  #include "skas.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28

ba180fd43   Jeff Dike   uml: style fixes ...
29
30
  /*
   * This is a per-cpu array.  A processor only modifies its entry and it only
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
33
34
   * cares about its entry, so it's OK if another processor is modifying its
   * entry.
   */
  struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
2dc5802a2   Karol Swietlicki   uml: remove dupli...
35
  static inline int external_pid(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
  {
77bf44003   Jeff Dike   uml: remove code ...
37
  	/* FIXME: Need to look up userspace_pid by cpu */
ba180fd43   Jeff Dike   uml: style fixes ...
38
  	return userspace_pid[0];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
40
41
42
43
  }
  
  int pid_to_processor_id(int pid)
  {
  	int i;
c5d4bb171   Jeff Dike   uml: style fixes ...
44
  	for (i = 0; i < ncpus; i++) {
ba180fd43   Jeff Dike   uml: style fixes ...
45
  		if (cpu_tasks[i].pid == pid)
6e21aec3f   Jeff Dike   uml: tidy process.c
46
  			return i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
47
  	}
6e21aec3f   Jeff Dike   uml: tidy process.c
48
  	return -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
50
51
52
53
54
55
56
57
58
  }
  
  void free_stack(unsigned long stack, int order)
  {
  	free_pages(stack, order);
  }
  
  unsigned long alloc_stack(int order, int atomic)
  {
  	unsigned long page;
53f9fc93f   Al Viro   [PATCH] gfp_t: re...
59
  	gfp_t flags = GFP_KERNEL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60

46db4a42d   Paolo 'Blaisorblade' Giarrusso   [PATCH] uml: Fix ...
61
62
  	if (atomic)
  		flags = GFP_ATOMIC;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
  	page = __get_free_pages(flags, order);
5c8aaceab   Jeff Dike   uml: stop special...
64

6e21aec3f   Jeff Dike   uml: tidy process.c
65
  	return page;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
67
68
69
70
71
72
73
  }
  
  int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
  {
  	int pid;
  
  	current->thread.request.u.thread.proc = fn;
  	current->thread.request.u.thread.arg = arg;
e0877f07e   Jeff Dike   [PATCH] uml: fork...
74
75
  	pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0,
  		      &current->thread.regs, 0, NULL, NULL);
6e21aec3f   Jeff Dike   uml: tidy process.c
76
  	return pid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
  }
73395a000   Al Viro   um: distribute ex...
78
  EXPORT_SYMBOL(kernel_thread);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79

6e21aec3f   Jeff Dike   uml: tidy process.c
80
  static inline void set_current(struct task_struct *task)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81
  {
ca9bc0bb2   Al Viro   [PATCH] uml: task...
82
  	cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task)
2dc5802a2   Karol Swietlicki   uml: remove dupli...
83
  		{ external_pid(), task });
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
  }
291248fd6   Karol Swietlicki   uml: remove unuse...
85
  extern void arch_switch_to(struct task_struct *to);
77bf44003   Jeff Dike   uml: remove code ...
86

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87
88
  void *_switch_to(void *prev, void *next, void *last)
  {
995473aec   Jeff Dike   [PATCH] uml: file...
89
  	struct task_struct *from = prev;
291248fd6   Karol Swietlicki   uml: remove unuse...
90
  	struct task_struct *to = next;
f6e34c6af   Jeff Dike   [PATCH] uml: _swi...
91

995473aec   Jeff Dike   [PATCH] uml: file...
92
93
  	to->thread.prev_sched = from;
  	set_current(to);
f6e34c6af   Jeff Dike   [PATCH] uml: _swi...
94

3eddddcf2   Jeff Dike   [PATCH] uml: brea...
95
  	do {
6aa802ce6   Jeff Dike   uml: throw out CH...
96
  		current->thread.saved_task = NULL;
77bf44003   Jeff Dike   uml: remove code ...
97

c5d4bb171   Jeff Dike   uml: style fixes ...
98
99
  		switch_threads(&from->thread.switch_buf,
  			       &to->thread.switch_buf);
77bf44003   Jeff Dike   uml: remove code ...
100

291248fd6   Karol Swietlicki   uml: remove unuse...
101
  		arch_switch_to(current);
77bf44003   Jeff Dike   uml: remove code ...
102

ba180fd43   Jeff Dike   uml: style fixes ...
103
  		if (current->thread.saved_task)
3eddddcf2   Jeff Dike   [PATCH] uml: brea...
104
  			show_regs(&(current->thread.regs));
c5d4bb171   Jeff Dike   uml: style fixes ...
105
106
  		to = current->thread.saved_task;
  		from = current;
291248fd6   Karol Swietlicki   uml: remove unuse...
107
  	} while (current->thread.saved_task);
f6e34c6af   Jeff Dike   [PATCH] uml: _swi...
108

6e21aec3f   Jeff Dike   uml: tidy process.c
109
  	return current->thread.prev_sched;
f6e34c6af   Jeff Dike   [PATCH] uml: _swi...
110

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
112
113
114
  }
  
  void interrupt_end(void)
  {
ba180fd43   Jeff Dike   uml: style fixes ...
115
  	if (need_resched())
6e21aec3f   Jeff Dike   uml: tidy process.c
116
  		schedule();
ba180fd43   Jeff Dike   uml: style fixes ...
117
  	if (test_tsk_thread_flag(current, TIF_SIGPENDING))
6e21aec3f   Jeff Dike   uml: tidy process.c
118
  		do_signal();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
  void exit_thread(void)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
122
  }
995473aec   Jeff Dike   [PATCH] uml: file...
123

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
125
  void *get_current(void)
  {
6e21aec3f   Jeff Dike   uml: tidy process.c
126
  	return current;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
  }
ba180fd43   Jeff Dike   uml: style fixes ...
128
129
  /*
   * This is called magically, by its address being stuffed in a jmp_buf
77bf44003   Jeff Dike   uml: remove code ...
130
131
132
133
134
135
   * and being longjmp-d to.
   */
  void new_thread_handler(void)
  {
  	int (*fn)(void *), n;
  	void *arg;
ba180fd43   Jeff Dike   uml: style fixes ...
136
  	if (current->thread.prev_sched != NULL)
77bf44003   Jeff Dike   uml: remove code ...
137
138
139
140
141
  		schedule_tail(current->thread.prev_sched);
  	current->thread.prev_sched = NULL;
  
  	fn = current->thread.request.u.thread.proc;
  	arg = current->thread.request.u.thread.arg;
ba180fd43   Jeff Dike   uml: style fixes ...
142
143
  	/*
  	 * The return value is 1 if the kernel thread execs a process,
77bf44003   Jeff Dike   uml: remove code ...
144
145
146
  	 * 0 if it just exits
  	 */
  	n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
ba180fd43   Jeff Dike   uml: style fixes ...
147
  	if (n == 1) {
77bf44003   Jeff Dike   uml: remove code ...
148
149
150
151
152
153
154
155
156
157
158
  		/* Handle any immediate reschedules or signals */
  		interrupt_end();
  		userspace(&current->thread.regs.regs);
  	}
  	else do_exit(0);
  }
  
  /* Called magically, see new_thread_handler above */
  void fork_handler(void)
  {
  	force_flush_all();
77bf44003   Jeff Dike   uml: remove code ...
159
160
  
  	schedule_tail(current->thread.prev_sched);
ba180fd43   Jeff Dike   uml: style fixes ...
161
162
  	/*
  	 * XXX: if interrupt_end() calls schedule, this call to
77bf44003   Jeff Dike   uml: remove code ...
163
  	 * arch_switch_to isn't needed. We could want to apply this to
ba180fd43   Jeff Dike   uml: style fixes ...
164
165
  	 * improve performance. -bb
  	 */
291248fd6   Karol Swietlicki   uml: remove unuse...
166
  	arch_switch_to(current);
77bf44003   Jeff Dike   uml: remove code ...
167
168
169
170
171
172
173
174
  
  	current->thread.prev_sched = NULL;
  
  	/* Handle any immediate reschedules or signals */
  	interrupt_end();
  
  	userspace(&current->thread.regs.regs);
  }
6f2c55b84   Alexey Dobriyan   Simplify copy_thr...
175
  int copy_thread(unsigned long clone_flags, unsigned long sp,
995473aec   Jeff Dike   [PATCH] uml: file...
176
  		unsigned long stack_top, struct task_struct * p,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177
178
  		struct pt_regs *regs)
  {
77bf44003   Jeff Dike   uml: remove code ...
179
180
  	void (*handler)(void);
  	int ret = 0;
aa6758d48   Paolo 'Blaisorblade' Giarrusso   [PATCH] uml: impl...
181

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
  	p->thread = (struct thread_struct) INIT_THREAD;
aa6758d48   Paolo 'Blaisorblade' Giarrusso   [PATCH] uml: impl...
183

ba180fd43   Jeff Dike   uml: style fixes ...
184
  	if (current->thread.forking) {
77bf44003   Jeff Dike   uml: remove code ...
185
186
  	  	memcpy(&p->thread.regs.regs, &regs->regs,
  		       sizeof(p->thread.regs.regs));
18badddaa   Jeff Dike   uml: rename pt_re...
187
  		REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.gp, 0);
ba180fd43   Jeff Dike   uml: style fixes ...
188
  		if (sp != 0)
18badddaa   Jeff Dike   uml: rename pt_re...
189
  			REGS_SP(p->thread.regs.regs.gp) = sp;
aa6758d48   Paolo 'Blaisorblade' Giarrusso   [PATCH] uml: impl...
190

77bf44003   Jeff Dike   uml: remove code ...
191
  		handler = fork_handler;
aa6758d48   Paolo 'Blaisorblade' Giarrusso   [PATCH] uml: impl...
192

77bf44003   Jeff Dike   uml: remove code ...
193
194
195
  		arch_copy_thread(&current->thread.arch, &p->thread.arch);
  	}
  	else {
fbfe9c847   Ingo van Lil   um: Save FPU regi...
196
  		get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
77bf44003   Jeff Dike   uml: remove code ...
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
  		p->thread.request.u.thread = current->thread.request.u.thread;
  		handler = new_thread_handler;
  	}
  
  	new_thread(task_stack_page(p), &p->thread.switch_buf, handler);
  
  	if (current->thread.forking) {
  		clear_flushed_tls(p);
  
  		/*
  		 * Set a new TLS for the child thread?
  		 */
  		if (clone_flags & CLONE_SETTLS)
  			ret = arch_copy_tls(p);
  	}
aa6758d48   Paolo 'Blaisorblade' Giarrusso   [PATCH] uml: impl...
212

aa6758d48   Paolo 'Blaisorblade' Giarrusso   [PATCH] uml: impl...
213
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214
215
216
217
218
219
220
  }
  
  void initial_thread_cb(void (*proc)(void *), void *arg)
  {
  	int save_kmalloc_ok = kmalloc_ok;
  
  	kmalloc_ok = 0;
6aa802ce6   Jeff Dike   uml: throw out CH...
221
  	initial_thread_cb_skas(proc, arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
222
223
  	kmalloc_ok = save_kmalloc_ok;
  }
995473aec   Jeff Dike   [PATCH] uml: file...
224

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225
226
  void default_idle(void)
  {
b160fb630   Jeff Dike   uml: eliminate in...
227
  	unsigned long long nsecs;
c5d4bb171   Jeff Dike   uml: style fixes ...
228
  	while (1) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229
  		/* endless idle loop with no priority at all */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
231
232
233
234
  
  		/*
  		 * although we are an idle CPU, we do not want to
  		 * get into the scheduler unnecessarily.
  		 */
ba180fd43   Jeff Dike   uml: style fixes ...
235
  		if (need_resched())
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
  			schedule();
995473aec   Jeff Dike   [PATCH] uml: file...
237

1268fbc74   Frederic Weisbecker   nohz: Remove tick...
238
239
  		tick_nohz_idle_enter();
  		rcu_idle_enter();
b160fb630   Jeff Dike   uml: eliminate in...
240
241
  		nsecs = disable_timer();
  		idle_sleep(nsecs);
1268fbc74   Frederic Weisbecker   nohz: Remove tick...
242
243
  		rcu_idle_exit();
  		tick_nohz_idle_exit();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
244
245
246
247
248
  	}
  }
  
  void cpu_idle(void)
  {
a5a678c80   Jeff Dike   uml: current.h cl...
249
  	cpu_tasks[current_thread_info()->cpu].pid = os_getpid();
77bf44003   Jeff Dike   uml: remove code ...
250
  	default_idle();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
251
  }
b63162939   Paolo 'Blaisorblade' Giarrusso   [PATCH] uml: avoi...
252
253
254
  int __cant_sleep(void) {
  	return in_atomic() || irqs_disabled() || in_interrupt();
  	/* Is in_interrupt() really needed? */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
255
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256
257
258
259
260
  int user_context(unsigned long sp)
  {
  	unsigned long stack;
  
  	stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
a5a678c80   Jeff Dike   uml: current.h cl...
261
  	return stack != (unsigned long) current_thread_info();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
263
264
265
266
267
268
269
270
271
272
  extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
  
  void do_uml_exitcalls(void)
  {
  	exitcall_t *call;
  
  	call = &__uml_exitcall_end;
  	while (--call >= &__uml_exitcall_begin)
  		(*call)();
  }
c0a9290ec   WANG Cong   uml: const and ot...
273
  char *uml_strdup(const char *string)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
274
  {
dfe52244e   Robert Love   [PATCH] kstrdup: ...
275
  	return kstrdup(string, GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
276
  }
73395a000   Al Viro   um: distribute ex...
277
  EXPORT_SYMBOL(uml_strdup);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
278

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279
280
  int copy_to_user_proc(void __user *to, void *from, int size)
  {
6e21aec3f   Jeff Dike   uml: tidy process.c
281
  	return copy_to_user(to, from, size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
283
284
285
  }
  
  int copy_from_user_proc(void *to, void __user *from, int size)
  {
6e21aec3f   Jeff Dike   uml: tidy process.c
286
  	return copy_from_user(to, from, size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
287
288
289
290
  }
  
  int clear_user_proc(void __user *buf, int size)
  {
6e21aec3f   Jeff Dike   uml: tidy process.c
291
  	return clear_user(buf, size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292
293
294
295
  }
  
  int strlen_user_proc(char __user *str)
  {
6e21aec3f   Jeff Dike   uml: tidy process.c
296
  	return strlen_user(str);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
297
298
299
300
301
  }
  
  int smp_sigio_handler(void)
  {
  #ifdef CONFIG_SMP
a5a678c80   Jeff Dike   uml: current.h cl...
302
  	int cpu = current_thread_info()->cpu;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
  	IPI_handler(cpu);
ba180fd43   Jeff Dike   uml: style fixes ...
304
  	if (cpu != 0)
6e21aec3f   Jeff Dike   uml: tidy process.c
305
  		return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
306
  #endif
6e21aec3f   Jeff Dike   uml: tidy process.c
307
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
308
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
310
  int cpu(void)
  {
a5a678c80   Jeff Dike   uml: current.h cl...
311
  	return current_thread_info()->cpu;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
  }
  
  static atomic_t using_sysemu = ATOMIC_INIT(0);
  int sysemu_supported;
  
  void set_using_sysemu(int value)
  {
  	if (value > sysemu_supported)
  		return;
  	atomic_set(&using_sysemu, value);
  }
  
  int get_using_sysemu(void)
  {
  	return atomic_read(&using_sysemu);
  }
6613c5e86   Alexey Dobriyan   uml: convert to s...
328
  static int sysemu_proc_show(struct seq_file *m, void *v)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
329
  {
6613c5e86   Alexey Dobriyan   uml: convert to s...
330
331
332
333
  	seq_printf(m, "%d
  ", get_using_sysemu());
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
334

6613c5e86   Alexey Dobriyan   uml: convert to s...
335
336
337
  static int sysemu_proc_open(struct inode *inode, struct file *file)
  {
  	return single_open(file, sysemu_proc_show, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
338
  }
6613c5e86   Alexey Dobriyan   uml: convert to s...
339
340
  static ssize_t sysemu_proc_write(struct file *file, const char __user *buf,
  				 size_t count, loff_t *pos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
341
342
343
344
345
346
347
348
  {
  	char tmp[2];
  
  	if (copy_from_user(tmp, buf, 1))
  		return -EFAULT;
  
  	if (tmp[0] >= '0' && tmp[0] <= '2')
  		set_using_sysemu(tmp[0] - '0');
ba180fd43   Jeff Dike   uml: style fixes ...
349
350
  	/* We use the first char, but pretend to write everything */
  	return count;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
351
  }
6613c5e86   Alexey Dobriyan   uml: convert to s...
352
353
354
355
356
357
358
359
  static const struct file_operations sysemu_proc_fops = {
  	.owner		= THIS_MODULE,
  	.open		= sysemu_proc_open,
  	.read		= seq_read,
  	.llseek		= seq_lseek,
  	.release	= single_release,
  	.write		= sysemu_proc_write,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
360
361
362
363
364
  int __init make_proc_sysemu(void)
  {
  	struct proc_dir_entry *ent;
  	if (!sysemu_supported)
  		return 0;
6613c5e86   Alexey Dobriyan   uml: convert to s...
365
  	ent = proc_create("sysemu", 0600, NULL, &sysemu_proc_fops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
366
367
368
  
  	if (ent == NULL)
  	{
30f417c65   Christophe Lucas   [PATCH] uml: Clea...
369
370
  		printk(KERN_WARNING "Failed to register /proc/sysemu
  ");
6e21aec3f   Jeff Dike   uml: tidy process.c
371
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
372
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373
374
375
376
377
378
379
380
  	return 0;
  }
  
  late_initcall(make_proc_sysemu);
  
  int singlestepping(void * t)
  {
  	struct task_struct *task = t ? t : current;
c5d4bb171   Jeff Dike   uml: style fixes ...
381
  	if (!(task->ptrace & PT_DTRACE))
ba180fd43   Jeff Dike   uml: style fixes ...
382
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
384
  
  	if (task->thread.singlestep_syscall)
ba180fd43   Jeff Dike   uml: style fixes ...
385
  		return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
386
387
388
  
  	return 2;
  }
b8bd0220c   Bodo Stroesser   [PATCH] uml: S390...
389
390
391
392
393
394
395
396
  /*
   * Only x86 and x86_64 have an arch_align_stack().
   * All other arches have "#define arch_align_stack(x) (x)"
   * in their asm/system.h
   * As this is included in UML from asm-um/system-generic.h,
   * we can use it to behave as the subarch does.
   */
  #ifndef arch_align_stack
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
398
  unsigned long arch_align_stack(unsigned long sp)
  {
8f80e9466   Jeff Dike   [PATCH] uml: Fix ...
399
  	if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
400
401
402
  		sp -= get_random_int() % 8192;
  	return sp & ~0xf;
  }
b8bd0220c   Bodo Stroesser   [PATCH] uml: S390...
403
  #endif
c11274655   Jeff Dike   uml: implement ge...
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
  
  unsigned long get_wchan(struct task_struct *p)
  {
  	unsigned long stack_page, sp, ip;
  	bool seen_sched = 0;
  
  	if ((p == NULL) || (p == current) || (p->state == TASK_RUNNING))
  		return 0;
  
  	stack_page = (unsigned long) task_stack_page(p);
  	/* Bail if the process has no kernel stack for some reason */
  	if (stack_page == 0)
  		return 0;
  
  	sp = p->thread.switch_buf->JB_SP;
  	/*
  	 * Bail if the stack pointer is below the bottom of the kernel
  	 * stack for some reason
  	 */
  	if (sp < stack_page)
  		return 0;
  
  	while (sp < stack_page + THREAD_SIZE) {
  		ip = *((unsigned long *) sp);
  		if (in_sched_functions(ip))
  			/* Ignore everything until we're above the scheduler */
  			seen_sched = 1;
  		else if (kernel_text_address(ip) && seen_sched)
  			return ip;
  
  		sp += sizeof(unsigned long);
  	}
  
  	return 0;
  }
8192ab42b   Jeff Dike   uml: header untan...
439
440
441
442
443
444
445
  
  int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu)
  {
  	int cpu = current_thread_info()->cpu;
  
  	return save_fp_registers(userspace_pid[cpu], (unsigned long *) fpu);
  }