diff options
-rw-r--r-- | arch/x86_64/kernel/process.c | 47 | ||||
-rw-r--r-- | include/asm-x86_64/msr.h | 2 |
2 files changed, 28 insertions, 21 deletions
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index b5a89c0bdf59..bc44c92ca198 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c | |||
@@ -148,7 +148,8 @@ void cpu_idle_wait(void) | |||
148 | do { | 148 | do { |
149 | ssleep(1); | 149 | ssleep(1); |
150 | for_each_online_cpu(cpu) { | 150 | for_each_online_cpu(cpu) { |
151 | if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu)) | 151 | if (cpu_isset(cpu, map) && |
152 | !per_cpu(cpu_idle_state, cpu)) | ||
152 | cpu_clear(cpu, map); | 153 | cpu_clear(cpu, map); |
153 | } | 154 | } |
154 | cpus_and(map, map, cpu_online_map); | 155 | cpus_and(map, map, cpu_online_map); |
@@ -278,7 +279,8 @@ void __show_regs(struct pt_regs * regs) | |||
278 | system_utsname.version); | 279 | system_utsname.version); |
279 | printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip); | 280 | printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip); |
280 | printk_address(regs->rip); | 281 | printk_address(regs->rip); |
281 | printk("\nRSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->rsp, regs->eflags); | 282 | printk("\nRSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->rsp, |
283 | regs->eflags); | ||
282 | printk("RAX: %016lx RBX: %016lx RCX: %016lx\n", | 284 | printk("RAX: %016lx RBX: %016lx RCX: %016lx\n", |
283 | regs->rax, regs->rbx, regs->rcx); | 285 | regs->rax, regs->rbx, regs->rcx); |
284 | printk("RDX: %016lx RSI: %016lx RDI: %016lx\n", | 286 | printk("RDX: %016lx RSI: %016lx RDI: %016lx\n", |
@@ -430,15 +432,14 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp, | |||
430 | struct pt_regs * childregs; | 432 | struct pt_regs * childregs; |
431 | struct task_struct *me = current; | 433 | struct task_struct *me = current; |
432 | 434 | ||
433 | childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; | 435 | childregs = ((struct pt_regs *) |
434 | 436 | (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; | |
435 | *childregs = *regs; | 437 | *childregs = *regs; |
436 | 438 | ||
437 | childregs->rax = 0; | 439 | childregs->rax = 0; |
438 | childregs->rsp = rsp; | 440 | childregs->rsp = rsp; |
439 | if (rsp == ~0UL) { | 441 | if (rsp == ~0UL) |
440 | childregs->rsp = (unsigned long)childregs; | 442 | childregs->rsp = (unsigned long)childregs; |
441 | } | ||
442 | 443 | ||
443 | p->thread.rsp = (unsigned long) childregs; | 444 | p->thread.rsp = (unsigned long) childregs; |
444 | p->thread.rsp0 = (unsigned long) (childregs+1); | 445 | p->thread.rsp0 = (unsigned long) (childregs+1); |
@@ -460,7 +461,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp, | |||
460 | p->thread.io_bitmap_max = 0; | 461 | p->thread.io_bitmap_max = 0; |
461 | return -ENOMEM; | 462 | return -ENOMEM; |
462 | } | 463 | } |
463 | memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr, IO_BITMAP_BYTES); | 464 | memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr, |
465 | IO_BITMAP_BYTES); | ||
464 | } | 466 | } |
465 | 467 | ||
466 | /* | 468 | /* |
@@ -497,7 +499,8 @@ out: | |||
497 | * - fold all the options into a flag word and test it with a single test. | 499 | * - fold all the options into a flag word and test it with a single test. |
498 | * - could test fs/gs bitsliced | 500 | * - could test fs/gs bitsliced |
499 | */ | 501 | */ |
500 | struct task_struct *__switch_to(struct task_struct *prev_p, struct task_struct *next_p) | 502 | struct task_struct * |
503 | __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | ||
501 | { | 504 | { |
502 | struct thread_struct *prev = &prev_p->thread, | 505 | struct thread_struct *prev = &prev_p->thread, |
503 | *next = &next_p->thread; | 506 | *next = &next_p->thread; |
@@ -568,7 +571,8 @@ struct task_struct *__switch_to(struct task_struct *prev_p, struct task_struct * | |||
568 | prev->userrsp = read_pda(oldrsp); | 571 | prev->userrsp = read_pda(oldrsp); |
569 | write_pda(oldrsp, next->userrsp); | 572 | write_pda(oldrsp, next->userrsp); |
570 | write_pda(pcurrent, next_p); | 573 | write_pda(pcurrent, next_p); |
571 | write_pda(kernelstack, (unsigned long)next_p->thread_info + THREAD_SIZE - PDA_STACKOFFSET); | 574 | write_pda(kernelstack, |
575 | (unsigned long)next_p->thread_info + THREAD_SIZE - PDA_STACKOFFSET); | ||
572 | 576 | ||
573 | /* | 577 | /* |
574 | * Now maybe reload the debug registers | 578 | * Now maybe reload the debug registers |
@@ -649,7 +653,9 @@ asmlinkage long sys_fork(struct pt_regs *regs) | |||
649 | return do_fork(SIGCHLD, regs->rsp, regs, 0, NULL, NULL); | 653 | return do_fork(SIGCHLD, regs->rsp, regs, 0, NULL, NULL); |
650 | } | 654 | } |
651 | 655 | ||
652 | asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, void __user *parent_tid, void __user *child_tid, struct pt_regs *regs) | 656 | asmlinkage long |
657 | sys_clone(unsigned long clone_flags, unsigned long newsp, | ||
658 | void __user *parent_tid, void __user *child_tid, struct pt_regs *regs) | ||
653 | { | 659 | { |
654 | if (!newsp) | 660 | if (!newsp) |
655 | newsp = regs->rsp; | 661 | newsp = regs->rsp; |
@@ -685,7 +691,8 @@ unsigned long get_wchan(struct task_struct *p) | |||
685 | return 0; | 691 | return 0; |
686 | fp = *(u64 *)(p->thread.rsp); | 692 | fp = *(u64 *)(p->thread.rsp); |
687 | do { | 693 | do { |
688 | if (fp < (unsigned long)stack || fp > (unsigned long)stack+THREAD_SIZE) | 694 | if (fp < (unsigned long)stack || |
695 | fp > (unsigned long)stack+THREAD_SIZE) | ||
689 | return 0; | 696 | return 0; |
690 | rip = *(u64 *)(fp+8); | 697 | rip = *(u64 *)(fp+8); |
691 | if (!in_sched_functions(rip)) | 698 | if (!in_sched_functions(rip)) |
@@ -720,8 +727,8 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) | |||
720 | task->thread.gsindex = 0; | 727 | task->thread.gsindex = 0; |
721 | task->thread.gs = addr; | 728 | task->thread.gs = addr; |
722 | if (doit) { | 729 | if (doit) { |
723 | load_gs_index(0); | 730 | load_gs_index(0); |
724 | ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr); | 731 | ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr); |
725 | } | 732 | } |
726 | } | 733 | } |
727 | put_cpu(); | 734 | put_cpu(); |
@@ -738,7 +745,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) | |||
738 | set_32bit_tls(task, FS_TLS, addr); | 745 | set_32bit_tls(task, FS_TLS, addr); |
739 | if (doit) { | 746 | if (doit) { |
740 | load_TLS(&task->thread, cpu); | 747 | load_TLS(&task->thread, cpu); |
741 | asm volatile("movl %0,%%fs" :: "r" (FS_TLS_SEL)); | 748 | asm volatile("movl %0,%%fs" :: "r"(FS_TLS_SEL)); |
742 | } | 749 | } |
743 | task->thread.fsindex = FS_TLS_SEL; | 750 | task->thread.fsindex = FS_TLS_SEL; |
744 | task->thread.fs = 0; | 751 | task->thread.fs = 0; |
@@ -748,8 +755,8 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) | |||
748 | if (doit) { | 755 | if (doit) { |
749 | /* set the selector to 0 to not confuse | 756 | /* set the selector to 0 to not confuse |
750 | __switch_to */ | 757 | __switch_to */ |
751 | asm volatile("movl %0,%%fs" :: "r" (0)); | 758 | asm volatile("movl %0,%%fs" :: "r" (0)); |
752 | ret = checking_wrmsrl(MSR_FS_BASE, addr); | 759 | ret = checking_wrmsrl(MSR_FS_BASE, addr); |
753 | } | 760 | } |
754 | } | 761 | } |
755 | put_cpu(); | 762 | put_cpu(); |
@@ -758,9 +765,9 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) | |||
758 | unsigned long base; | 765 | unsigned long base; |
759 | if (task->thread.fsindex == FS_TLS_SEL) | 766 | if (task->thread.fsindex == FS_TLS_SEL) |
760 | base = read_32bit_tls(task, FS_TLS); | 767 | base = read_32bit_tls(task, FS_TLS); |
761 | else if (doit) { | 768 | else if (doit) |
762 | rdmsrl(MSR_FS_BASE, base); | 769 | rdmsrl(MSR_FS_BASE, base); |
763 | } else | 770 | else |
764 | base = task->thread.fs; | 771 | base = task->thread.fs; |
765 | ret = put_user(base, (unsigned long __user *)addr); | 772 | ret = put_user(base, (unsigned long __user *)addr); |
766 | break; | 773 | break; |
@@ -769,9 +776,9 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) | |||
769 | unsigned long base; | 776 | unsigned long base; |
770 | if (task->thread.gsindex == GS_TLS_SEL) | 777 | if (task->thread.gsindex == GS_TLS_SEL) |
771 | base = read_32bit_tls(task, GS_TLS); | 778 | base = read_32bit_tls(task, GS_TLS); |
772 | else if (doit) { | 779 | else if (doit) |
773 | rdmsrl(MSR_KERNEL_GS_BASE, base); | 780 | rdmsrl(MSR_KERNEL_GS_BASE, base); |
774 | } else | 781 | else |
775 | base = task->thread.gs; | 782 | base = task->thread.gs; |
776 | ret = put_user(base, (unsigned long __user *)addr); | 783 | ret = put_user(base, (unsigned long __user *)addr); |
777 | break; | 784 | break; |
diff --git a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h index 5a7fe3c6c3d8..24dc39651bc4 100644 --- a/include/asm-x86_64/msr.h +++ b/include/asm-x86_64/msr.h | |||
@@ -19,7 +19,7 @@ | |||
19 | : "=a" (a__), "=d" (b__) \ | 19 | : "=a" (a__), "=d" (b__) \ |
20 | : "c" (msr)); \ | 20 | : "c" (msr)); \ |
21 | val = a__ | (b__<<32); \ | 21 | val = a__ | (b__<<32); \ |
22 | } while(0); | 22 | } while(0) |
23 | 23 | ||
24 | #define wrmsr(msr,val1,val2) \ | 24 | #define wrmsr(msr,val1,val2) \ |
25 | __asm__ __volatile__("wrmsr" \ | 25 | __asm__ __volatile__("wrmsr" \ |