diff options
Diffstat (limited to 'arch/x86/kernel/process_64.c')
-rw-r--r-- | arch/x86/kernel/process_64.c | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index eb62cbcaa49..c95c8f4e790 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <asm/idle.h> | 52 | #include <asm/idle.h> |
53 | #include <asm/syscalls.h> | 53 | #include <asm/syscalls.h> |
54 | #include <asm/ds.h> | 54 | #include <asm/ds.h> |
55 | #include <asm/debugreg.h> | ||
55 | 56 | ||
56 | asmlinkage extern void ret_from_fork(void); | 57 | asmlinkage extern void ret_from_fork(void); |
57 | 58 | ||
@@ -226,8 +227,7 @@ void __show_regs(struct pt_regs *regs, int all) | |||
226 | 227 | ||
227 | void show_regs(struct pt_regs *regs) | 228 | void show_regs(struct pt_regs *regs) |
228 | { | 229 | { |
229 | printk(KERN_INFO "CPU %d:", smp_processor_id()); | 230 | show_registers(regs); |
230 | __show_regs(regs, 1); | ||
231 | show_trace(NULL, regs, (void *)(regs + 1), regs->bp); | 231 | show_trace(NULL, regs, (void *)(regs + 1), regs->bp); |
232 | } | 232 | } |
233 | 233 | ||
@@ -297,12 +297,16 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
297 | 297 | ||
298 | p->thread.fs = me->thread.fs; | 298 | p->thread.fs = me->thread.fs; |
299 | p->thread.gs = me->thread.gs; | 299 | p->thread.gs = me->thread.gs; |
300 | p->thread.io_bitmap_ptr = NULL; | ||
300 | 301 | ||
301 | savesegment(gs, p->thread.gsindex); | 302 | savesegment(gs, p->thread.gsindex); |
302 | savesegment(fs, p->thread.fsindex); | 303 | savesegment(fs, p->thread.fsindex); |
303 | savesegment(es, p->thread.es); | 304 | savesegment(es, p->thread.es); |
304 | savesegment(ds, p->thread.ds); | 305 | savesegment(ds, p->thread.ds); |
305 | 306 | ||
307 | err = -ENOMEM; | ||
308 | memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps)); | ||
309 | |||
306 | if (unlikely(test_tsk_thread_flag(me, TIF_IO_BITMAP))) { | 310 | if (unlikely(test_tsk_thread_flag(me, TIF_IO_BITMAP))) { |
307 | p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); | 311 | p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); |
308 | if (!p->thread.io_bitmap_ptr) { | 312 | if (!p->thread.io_bitmap_ptr) { |
@@ -341,29 +345,46 @@ out: | |||
341 | kfree(p->thread.io_bitmap_ptr); | 345 | kfree(p->thread.io_bitmap_ptr); |
342 | p->thread.io_bitmap_max = 0; | 346 | p->thread.io_bitmap_max = 0; |
343 | } | 347 | } |
348 | |||
344 | return err; | 349 | return err; |
345 | } | 350 | } |
346 | 351 | ||
347 | void | 352 | static void |
348 | start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) | 353 | start_thread_common(struct pt_regs *regs, unsigned long new_ip, |
354 | unsigned long new_sp, | ||
355 | unsigned int _cs, unsigned int _ss, unsigned int _ds) | ||
349 | { | 356 | { |
350 | loadsegment(fs, 0); | 357 | loadsegment(fs, 0); |
351 | loadsegment(es, 0); | 358 | loadsegment(es, _ds); |
352 | loadsegment(ds, 0); | 359 | loadsegment(ds, _ds); |
353 | load_gs_index(0); | 360 | load_gs_index(0); |
354 | regs->ip = new_ip; | 361 | regs->ip = new_ip; |
355 | regs->sp = new_sp; | 362 | regs->sp = new_sp; |
356 | percpu_write(old_rsp, new_sp); | 363 | percpu_write(old_rsp, new_sp); |
357 | regs->cs = __USER_CS; | 364 | regs->cs = _cs; |
358 | regs->ss = __USER_DS; | 365 | regs->ss = _ss; |
359 | regs->flags = 0x200; | 366 | regs->flags = X86_EFLAGS_IF; |
360 | set_fs(USER_DS); | 367 | set_fs(USER_DS); |
361 | /* | 368 | /* |
362 | * Free the old FP and other extended state | 369 | * Free the old FP and other extended state |
363 | */ | 370 | */ |
364 | free_thread_xstate(current); | 371 | free_thread_xstate(current); |
365 | } | 372 | } |
366 | EXPORT_SYMBOL_GPL(start_thread); | 373 | |
374 | void | ||
375 | start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) | ||
376 | { | ||
377 | start_thread_common(regs, new_ip, new_sp, | ||
378 | __USER_CS, __USER_DS, 0); | ||
379 | } | ||
380 | |||
381 | #ifdef CONFIG_IA32_EMULATION | ||
382 | void start_thread_ia32(struct pt_regs *regs, u32 new_ip, u32 new_sp) | ||
383 | { | ||
384 | start_thread_common(regs, new_ip, new_sp, | ||
385 | __USER32_CS, __USER32_DS, __USER32_DS); | ||
386 | } | ||
387 | #endif | ||
367 | 388 | ||
368 | /* | 389 | /* |
369 | * switch_to(x,y) should switch tasks from x to y. | 390 | * switch_to(x,y) should switch tasks from x to y. |
@@ -495,6 +516,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | |||
495 | */ | 516 | */ |
496 | if (preload_fpu) | 517 | if (preload_fpu) |
497 | __math_state_restore(); | 518 | __math_state_restore(); |
519 | |||
498 | return prev_p; | 520 | return prev_p; |
499 | } | 521 | } |
500 | 522 | ||