aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/process.c')
-rw-r--r--arch/x86/kernel/process.c88
1 files changed, 74 insertions, 14 deletions
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 7a7bd4e3ec49..c9b3522b6b46 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -103,8 +103,8 @@ void show_regs_common(void)
103 if (!product) 103 if (!product)
104 product = ""; 104 product = "";
105 105
106 printk("\n"); 106 printk(KERN_CONT "\n");
107 printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s %s/%s\n", 107 printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s %s/%s\n",
108 current->pid, current->comm, print_tainted(), 108 current->pid, current->comm, print_tainted(),
109 init_utsname()->release, 109 init_utsname()->release,
110 (int)strcspn(init_utsname()->version, " "), 110 (int)strcspn(init_utsname()->version, " "),
@@ -115,18 +115,6 @@ void flush_thread(void)
115{ 115{
116 struct task_struct *tsk = current; 116 struct task_struct *tsk = current;
117 117
118#ifdef CONFIG_X86_64
119 if (test_tsk_thread_flag(tsk, TIF_ABI_PENDING)) {
120 clear_tsk_thread_flag(tsk, TIF_ABI_PENDING);
121 if (test_tsk_thread_flag(tsk, TIF_IA32)) {
122 clear_tsk_thread_flag(tsk, TIF_IA32);
123 } else {
124 set_tsk_thread_flag(tsk, TIF_IA32);
125 current_thread_info()->status |= TS_COMPAT;
126 }
127 }
128#endif
129
130 flush_ptrace_hw_breakpoint(tsk); 118 flush_ptrace_hw_breakpoint(tsk);
131 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); 119 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
132 /* 120 /*
@@ -255,6 +243,78 @@ int sys_vfork(struct pt_regs *regs)
255 NULL, NULL); 243 NULL, NULL);
256} 244}
257 245
246long
247sys_clone(unsigned long clone_flags, unsigned long newsp,
248 void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
249{
250 if (!newsp)
251 newsp = regs->sp;
252 return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
253}
254
255/*
256 * This gets run with %si containing the
257 * function to call, and %di containing
258 * the "args".
259 */
260extern void kernel_thread_helper(void);
261
262/*
263 * Create a kernel thread
264 */
265int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
266{
267 struct pt_regs regs;
268
269 memset(&regs, 0, sizeof(regs));
270
271 regs.si = (unsigned long) fn;
272 regs.di = (unsigned long) arg;
273
274#ifdef CONFIG_X86_32
275 regs.ds = __USER_DS;
276 regs.es = __USER_DS;
277 regs.fs = __KERNEL_PERCPU;
278 regs.gs = __KERNEL_STACK_CANARY;
279#else
280 regs.ss = __KERNEL_DS;
281#endif
282
283 regs.orig_ax = -1;
284 regs.ip = (unsigned long) kernel_thread_helper;
285 regs.cs = __KERNEL_CS | get_kernel_rpl();
286 regs.flags = X86_EFLAGS_IF | 0x2;
287
288 /* Ok, create the new process.. */
289 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
290}
291EXPORT_SYMBOL(kernel_thread);
292
293/*
294 * sys_execve() executes a new program.
295 */
296long sys_execve(char __user *name, char __user * __user *argv,
297 char __user * __user *envp, struct pt_regs *regs)
298{
299 long error;
300 char *filename;
301
302 filename = getname(name);
303 error = PTR_ERR(filename);
304 if (IS_ERR(filename))
305 return error;
306 error = do_execve(filename, argv, envp, regs);
307
308#ifdef CONFIG_X86_32
309 if (error == 0) {
310 /* Make sure we don't return using sysenter.. */
311 set_thread_flag(TIF_IRET);
312 }
313#endif
314
315 putname(filename);
316 return error;
317}
258 318
259/* 319/*
260 * Idle related variables and functions 320 * Idle related variables and functions