aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/process.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-01-23 01:45:46 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-23 01:45:46 -0500
commit6be325719b3e54624397e413efd4b33a997e55a3 (patch)
tree57f321a56794cab2222e179b16731e0d76a4a68a /arch/x86/kernel/process.c
parent26d92f9276a56d55511a427fb70bd70886af647a (diff)
parent92dcffb916d309aa01778bf8963a6932e4014d07 (diff)
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Diffstat (limited to 'arch/x86/kernel/process.c')
-rw-r--r--arch/x86/kernel/process.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 5e2ba634ea15..02c3ee013ccd 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -10,6 +10,8 @@
10#include <linux/clockchips.h> 10#include <linux/clockchips.h>
11#include <linux/random.h> 11#include <linux/random.h>
12#include <linux/user-return-notifier.h> 12#include <linux/user-return-notifier.h>
13#include <linux/dmi.h>
14#include <linux/utsname.h>
13#include <trace/events/power.h> 15#include <trace/events/power.h>
14#include <linux/hw_breakpoint.h> 16#include <linux/hw_breakpoint.h>
15#include <asm/system.h> 17#include <asm/system.h>
@@ -90,6 +92,25 @@ void exit_thread(void)
90 } 92 }
91} 93}
92 94
95void show_regs_common(void)
96{
97 const char *board, *product;
98
99 board = dmi_get_system_info(DMI_BOARD_NAME);
100 if (!board)
101 board = "";
102 product = dmi_get_system_info(DMI_PRODUCT_NAME);
103 if (!product)
104 product = "";
105
106 printk(KERN_CONT "\n");
107 printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s %s/%s\n",
108 current->pid, current->comm, print_tainted(),
109 init_utsname()->release,
110 (int)strcspn(init_utsname()->version, " "),
111 init_utsname()->version, board, product);
112}
113
93void flush_thread(void) 114void flush_thread(void)
94{ 115{
95 struct task_struct *tsk = current; 116 struct task_struct *tsk = current;
@@ -234,6 +255,78 @@ int sys_vfork(struct pt_regs *regs)
234 NULL, NULL); 255 NULL, NULL);
235} 256}
236 257
258long
259sys_clone(unsigned long clone_flags, unsigned long newsp,
260 void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
261{
262 if (!newsp)
263 newsp = regs->sp;
264 return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
265}
266
267/*
268 * This gets run with %si containing the
269 * function to call, and %di containing
270 * the "args".
271 */
272extern void kernel_thread_helper(void);
273
274/*
275 * Create a kernel thread
276 */
277int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
278{
279 struct pt_regs regs;
280
281 memset(&regs, 0, sizeof(regs));
282
283 regs.si = (unsigned long) fn;
284 regs.di = (unsigned long) arg;
285
286#ifdef CONFIG_X86_32
287 regs.ds = __USER_DS;
288 regs.es = __USER_DS;
289 regs.fs = __KERNEL_PERCPU;
290 regs.gs = __KERNEL_STACK_CANARY;
291#else
292 regs.ss = __KERNEL_DS;
293#endif
294
295 regs.orig_ax = -1;
296 regs.ip = (unsigned long) kernel_thread_helper;
297 regs.cs = __KERNEL_CS | get_kernel_rpl();
298 regs.flags = X86_EFLAGS_IF | 0x2;
299
300 /* Ok, create the new process.. */
301 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
302}
303EXPORT_SYMBOL(kernel_thread);
304
305/*
306 * sys_execve() executes a new program.
307 */
308long sys_execve(char __user *name, char __user * __user *argv,
309 char __user * __user *envp, struct pt_regs *regs)
310{
311 long error;
312 char *filename;
313
314 filename = getname(name);
315 error = PTR_ERR(filename);
316 if (IS_ERR(filename))
317 return error;
318 error = do_execve(filename, argv, envp, regs);
319
320#ifdef CONFIG_X86_32
321 if (error == 0) {
322 /* Make sure we don't return using sysenter.. */
323 set_thread_flag(TIF_IRET);
324 }
325#endif
326
327 putname(filename);
328 return error;
329}
237 330
238/* 331/*
239 * Idle related variables and functions 332 * Idle related variables and functions