diff options
Diffstat (limited to 'arch/x86/kernel/process.c')
-rw-r--r-- | arch/x86/kernel/process.c | 88 |
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 | ||
246 | long | ||
247 | sys_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 | */ | ||
260 | extern void kernel_thread_helper(void); | ||
261 | |||
262 | /* | ||
263 | * Create a kernel thread | ||
264 | */ | ||
265 | int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | ||
266 | { | ||
267 | struct pt_regs regs; | ||
268 | |||
269 | memset(®s, 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, ®s, 0, NULL, NULL); | ||
290 | } | ||
291 | EXPORT_SYMBOL(kernel_thread); | ||
292 | |||
293 | /* | ||
294 | * sys_execve() executes a new program. | ||
295 | */ | ||
296 | long 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 |