aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/process_64.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-10-12 06:35:23 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-12 06:37:32 -0400
commit365d46dc9be9b3c833990a06f3994b1987eda578 (patch)
tree9397d1304144a288411f2118707f44ff5e862fa6 /arch/x86/kernel/process_64.c
parent5dc64a3442b98eaa0e3730c35fcf00cf962a93e7 (diff)
parentfd048088306656824958e7783ffcee27e241b361 (diff)
Merge branch 'linus' into x86/xen
Conflicts: arch/x86/kernel/cpu/common.c arch/x86/kernel/process_64.c arch/x86/xen/enlighten.c
Diffstat (limited to 'arch/x86/kernel/process_64.c')
-rw-r--r--arch/x86/kernel/process_64.c168
1 files changed, 96 insertions, 72 deletions
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index ec27afa43d7e..18e63350d7d2 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -37,11 +37,11 @@
37#include <linux/kdebug.h> 37#include <linux/kdebug.h>
38#include <linux/tick.h> 38#include <linux/tick.h>
39#include <linux/prctl.h> 39#include <linux/prctl.h>
40#include <linux/uaccess.h>
41#include <linux/io.h>
40 42
41#include <asm/uaccess.h>
42#include <asm/pgtable.h> 43#include <asm/pgtable.h>
43#include <asm/system.h> 44#include <asm/system.h>
44#include <asm/io.h>
45#include <asm/processor.h> 45#include <asm/processor.h>
46#include <asm/i387.h> 46#include <asm/i387.h>
47#include <asm/mmu_context.h> 47#include <asm/mmu_context.h>
@@ -51,6 +51,7 @@
51#include <asm/proto.h> 51#include <asm/proto.h>
52#include <asm/ia32.h> 52#include <asm/ia32.h>
53#include <asm/idle.h> 53#include <asm/idle.h>
54#include <asm/syscalls.h>
54 55
55asmlinkage extern void ret_from_fork(void); 56asmlinkage extern void ret_from_fork(void);
56 57
@@ -135,7 +136,7 @@ void cpu_idle(void)
135} 136}
136 137
137/* Prints also some state that isn't saved in the pt_regs */ 138/* Prints also some state that isn't saved in the pt_regs */
138void __show_regs(struct pt_regs * regs) 139void __show_regs(struct pt_regs *regs)
139{ 140{
140 unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs; 141 unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs;
141 unsigned long d0, d1, d2, d3, d6, d7; 142 unsigned long d0, d1, d2, d3, d6, d7;
@@ -144,59 +145,61 @@ void __show_regs(struct pt_regs * regs)
144 145
145 printk("\n"); 146 printk("\n");
146 print_modules(); 147 print_modules();
147 printk("Pid: %d, comm: %.20s %s %s %.*s\n", 148 printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s\n",
148 current->pid, current->comm, print_tainted(), 149 current->pid, current->comm, print_tainted(),
149 init_utsname()->release, 150 init_utsname()->release,
150 (int)strcspn(init_utsname()->version, " "), 151 (int)strcspn(init_utsname()->version, " "),
151 init_utsname()->version); 152 init_utsname()->version);
152 printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip); 153 printk(KERN_INFO "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip);
153 printk_address(regs->ip, 1); 154 printk_address(regs->ip, 1);
154 printk("RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->sp, 155 printk(KERN_INFO "RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss,
155 regs->flags); 156 regs->sp, regs->flags);
156 printk("RAX: %016lx RBX: %016lx RCX: %016lx\n", 157 printk(KERN_INFO "RAX: %016lx RBX: %016lx RCX: %016lx\n",
157 regs->ax, regs->bx, regs->cx); 158 regs->ax, regs->bx, regs->cx);
158 printk("RDX: %016lx RSI: %016lx RDI: %016lx\n", 159 printk(KERN_INFO "RDX: %016lx RSI: %016lx RDI: %016lx\n",
159 regs->dx, regs->si, regs->di); 160 regs->dx, regs->si, regs->di);
160 printk("RBP: %016lx R08: %016lx R09: %016lx\n", 161 printk(KERN_INFO "RBP: %016lx R08: %016lx R09: %016lx\n",
161 regs->bp, regs->r8, regs->r9); 162 regs->bp, regs->r8, regs->r9);
162 printk("R10: %016lx R11: %016lx R12: %016lx\n", 163 printk(KERN_INFO "R10: %016lx R11: %016lx R12: %016lx\n",
163 regs->r10, regs->r11, regs->r12); 164 regs->r10, regs->r11, regs->r12);
164 printk("R13: %016lx R14: %016lx R15: %016lx\n", 165 printk(KERN_INFO "R13: %016lx R14: %016lx R15: %016lx\n",
165 regs->r13, regs->r14, regs->r15); 166 regs->r13, regs->r14, regs->r15);
166 167
167 asm("movl %%ds,%0" : "=r" (ds)); 168 asm("movl %%ds,%0" : "=r" (ds));
168 asm("movl %%cs,%0" : "=r" (cs)); 169 asm("movl %%cs,%0" : "=r" (cs));
169 asm("movl %%es,%0" : "=r" (es)); 170 asm("movl %%es,%0" : "=r" (es));
170 asm("movl %%fs,%0" : "=r" (fsindex)); 171 asm("movl %%fs,%0" : "=r" (fsindex));
171 asm("movl %%gs,%0" : "=r" (gsindex)); 172 asm("movl %%gs,%0" : "=r" (gsindex));
172 173
173 rdmsrl(MSR_FS_BASE, fs); 174 rdmsrl(MSR_FS_BASE, fs);
174 rdmsrl(MSR_GS_BASE, gs); 175 rdmsrl(MSR_GS_BASE, gs);
175 rdmsrl(MSR_KERNEL_GS_BASE, shadowgs); 176 rdmsrl(MSR_KERNEL_GS_BASE, shadowgs);
176 177
177 cr0 = read_cr0(); 178 cr0 = read_cr0();
178 cr2 = read_cr2(); 179 cr2 = read_cr2();
179 cr3 = read_cr3(); 180 cr3 = read_cr3();
180 cr4 = read_cr4(); 181 cr4 = read_cr4();
181 182
182 printk("FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n", 183 printk(KERN_INFO "FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n",
183 fs,fsindex,gs,gsindex,shadowgs); 184 fs, fsindex, gs, gsindex, shadowgs);
184 printk("CS: %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds, es, cr0); 185 printk(KERN_INFO "CS: %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds,
185 printk("CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4); 186 es, cr0);
187 printk(KERN_INFO "CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3,
188 cr4);
186 189
187 get_debugreg(d0, 0); 190 get_debugreg(d0, 0);
188 get_debugreg(d1, 1); 191 get_debugreg(d1, 1);
189 get_debugreg(d2, 2); 192 get_debugreg(d2, 2);
190 printk("DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2); 193 printk(KERN_INFO "DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2);
191 get_debugreg(d3, 3); 194 get_debugreg(d3, 3);
192 get_debugreg(d6, 6); 195 get_debugreg(d6, 6);
193 get_debugreg(d7, 7); 196 get_debugreg(d7, 7);
194 printk("DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7); 197 printk(KERN_INFO "DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7);
195} 198}
196 199
197void show_regs(struct pt_regs *regs) 200void show_regs(struct pt_regs *regs)
198{ 201{
199 printk("CPU %d:", smp_processor_id()); 202 printk(KERN_INFO "CPU %d:", smp_processor_id());
200 __show_regs(regs); 203 __show_regs(regs);
201 show_trace(NULL, regs, (void *)(regs + 1), regs->bp); 204 show_trace(NULL, regs, (void *)(regs + 1), regs->bp);
202} 205}
@@ -222,6 +225,14 @@ void exit_thread(void)
222 t->io_bitmap_max = 0; 225 t->io_bitmap_max = 0;
223 put_cpu(); 226 put_cpu();
224 } 227 }
228#ifdef CONFIG_X86_DS
229 /* Free any DS contexts that have not been properly released. */
230 if (unlikely(t->ds_ctx)) {
231 /* we clear debugctl to make sure DS is not used. */
232 update_debugctlmsr(0);
233 ds_free(t->ds_ctx);
234 }
235#endif /* CONFIG_X86_DS */
225} 236}
226 237
227void flush_thread(void) 238void flush_thread(void)
@@ -297,10 +308,10 @@ void prepare_to_copy(struct task_struct *tsk)
297 308
298int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, 309int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
299 unsigned long unused, 310 unsigned long unused,
300 struct task_struct * p, struct pt_regs * regs) 311 struct task_struct *p, struct pt_regs *regs)
301{ 312{
302 int err; 313 int err;
303 struct pt_regs * childregs; 314 struct pt_regs *childregs;
304 struct task_struct *me = current; 315 struct task_struct *me = current;
305 316
306 childregs = ((struct pt_regs *) 317 childregs = ((struct pt_regs *)
@@ -345,10 +356,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
345 if (test_thread_flag(TIF_IA32)) 356 if (test_thread_flag(TIF_IA32))
346 err = do_set_thread_area(p, -1, 357 err = do_set_thread_area(p, -1,
347 (struct user_desc __user *)childregs->si, 0); 358 (struct user_desc __user *)childregs->si, 0);
348 else 359 else
349#endif 360#endif
350 err = do_arch_prctl(p, ARCH_SET_FS, childregs->r8); 361 err = do_arch_prctl(p, ARCH_SET_FS, childregs->r8);
351 if (err) 362 if (err)
352 goto out; 363 goto out;
353 } 364 }
354 err = 0; 365 err = 0;
@@ -455,13 +466,27 @@ static inline void __switch_to_xtra(struct task_struct *prev_p,
455 next = &next_p->thread; 466 next = &next_p->thread;
456 467
457 debugctl = prev->debugctlmsr; 468 debugctl = prev->debugctlmsr;
458 if (next->ds_area_msr != prev->ds_area_msr) { 469
459 /* we clear debugctl to make sure DS 470#ifdef CONFIG_X86_DS
460 * is not in use when we change it */ 471 {
461 debugctl = 0; 472 unsigned long ds_prev = 0, ds_next = 0;
462 update_debugctlmsr(0); 473
463 wrmsrl(MSR_IA32_DS_AREA, next->ds_area_msr); 474 if (prev->ds_ctx)
475 ds_prev = (unsigned long)prev->ds_ctx->ds;
476 if (next->ds_ctx)
477 ds_next = (unsigned long)next->ds_ctx->ds;
478
479 if (ds_next != ds_prev) {
480 /*
481 * We clear debugctl to make sure DS
482 * is not in use when we change it:
483 */
484 debugctl = 0;
485 update_debugctlmsr(0);
486 wrmsrl(MSR_IA32_DS_AREA, ds_next);
487 }
464 } 488 }
489#endif /* CONFIG_X86_DS */
465 490
466 if (next->debugctlmsr != debugctl) 491 if (next->debugctlmsr != debugctl)
467 update_debugctlmsr(next->debugctlmsr); 492 update_debugctlmsr(next->debugctlmsr);
@@ -499,13 +524,13 @@ static inline void __switch_to_xtra(struct task_struct *prev_p,
499 memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); 524 memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
500 } 525 }
501 526
502#ifdef X86_BTS 527#ifdef CONFIG_X86_PTRACE_BTS
503 if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) 528 if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
504 ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); 529 ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
505 530
506 if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) 531 if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
507 ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); 532 ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
508#endif 533#endif /* CONFIG_X86_PTRACE_BTS */
509} 534}
510 535
511/* 536/*
@@ -527,7 +552,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
527 unsigned fsindex, gsindex; 552 unsigned fsindex, gsindex;
528 553
529 /* we're going to use this soon, after a few expensive things */ 554 /* we're going to use this soon, after a few expensive things */
530 if (next_p->fpu_counter>5) 555 if (next_p->fpu_counter > 5)
531 prefetch(next->xstate); 556 prefetch(next->xstate);
532 557
533 /* 558 /*
@@ -535,13 +560,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
535 */ 560 */
536 load_sp0(tss, next); 561 load_sp0(tss, next);
537 562
538 /* 563 /*
539 * Switch DS and ES. 564 * Switch DS and ES.
540 * This won't pick up thread selector changes, but I guess that is ok. 565 * This won't pick up thread selector changes, but I guess that is ok.
541 */ 566 */
542 savesegment(es, prev->es); 567 savesegment(es, prev->es);
543 if (unlikely(next->es | prev->es)) 568 if (unlikely(next->es | prev->es))
544 loadsegment(es, next->es); 569 loadsegment(es, next->es);
545 570
546 savesegment(ds, prev->ds); 571 savesegment(ds, prev->ds);
547 if (unlikely(next->ds | prev->ds)) 572 if (unlikely(next->ds | prev->ds))
@@ -567,7 +592,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
567 */ 592 */
568 arch_leave_lazy_cpu_mode(); 593 arch_leave_lazy_cpu_mode();
569 594
570 /* 595 /*
571 * Switch FS and GS. 596 * Switch FS and GS.
572 * 597 *
573 * Segment register != 0 always requires a reload. Also 598 * Segment register != 0 always requires a reload. Also
@@ -576,13 +601,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
576 */ 601 */
577 if (unlikely(fsindex | next->fsindex | prev->fs)) { 602 if (unlikely(fsindex | next->fsindex | prev->fs)) {
578 loadsegment(fs, next->fsindex); 603 loadsegment(fs, next->fsindex);
579 /* 604 /*
580 * Check if the user used a selector != 0; if yes 605 * Check if the user used a selector != 0; if yes
581 * clear 64bit base, since overloaded base is always 606 * clear 64bit base, since overloaded base is always
582 * mapped to the Null selector 607 * mapped to the Null selector
583 */ 608 */
584 if (fsindex) 609 if (fsindex)
585 prev->fs = 0; 610 prev->fs = 0;
586 } 611 }
587 /* when next process has a 64bit base use it */ 612 /* when next process has a 64bit base use it */
588 if (next->fs) 613 if (next->fs)
@@ -592,7 +617,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
592 if (unlikely(gsindex | next->gsindex | prev->gs)) { 617 if (unlikely(gsindex | next->gsindex | prev->gs)) {
593 load_gs_index(next->gsindex); 618 load_gs_index(next->gsindex);
594 if (gsindex) 619 if (gsindex)
595 prev->gs = 0; 620 prev->gs = 0;
596 } 621 }
597 if (next->gs) 622 if (next->gs)
598 wrmsrl(MSR_KERNEL_GS_BASE, next->gs); 623 wrmsrl(MSR_KERNEL_GS_BASE, next->gs);
@@ -601,12 +626,12 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
601 /* Must be after DS reload */ 626 /* Must be after DS reload */
602 unlazy_fpu(prev_p); 627 unlazy_fpu(prev_p);
603 628
604 /* 629 /*
605 * Switch the PDA and FPU contexts. 630 * Switch the PDA and FPU contexts.
606 */ 631 */
607 prev->usersp = read_pda(oldrsp); 632 prev->usersp = read_pda(oldrsp);
608 write_pda(oldrsp, next->usersp); 633 write_pda(oldrsp, next->usersp);
609 write_pda(pcurrent, next_p); 634 write_pda(pcurrent, next_p);
610 635
611 write_pda(kernelstack, 636 write_pda(kernelstack,
612 (unsigned long)task_stack_page(next_p) + 637 (unsigned long)task_stack_page(next_p) +
@@ -647,7 +672,7 @@ long sys_execve(char __user *name, char __user * __user *argv,
647 char __user * __user *envp, struct pt_regs *regs) 672 char __user * __user *envp, struct pt_regs *regs)
648{ 673{
649 long error; 674 long error;
650 char * filename; 675 char *filename;
651 676
652 filename = getname(name); 677 filename = getname(name);
653 error = PTR_ERR(filename); 678 error = PTR_ERR(filename);
@@ -705,55 +730,55 @@ asmlinkage long sys_vfork(struct pt_regs *regs)
705unsigned long get_wchan(struct task_struct *p) 730unsigned long get_wchan(struct task_struct *p)
706{ 731{
707 unsigned long stack; 732 unsigned long stack;
708 u64 fp,ip; 733 u64 fp, ip;
709 int count = 0; 734 int count = 0;
710 735
711 if (!p || p == current || p->state==TASK_RUNNING) 736 if (!p || p == current || p->state == TASK_RUNNING)
712 return 0; 737 return 0;
713 stack = (unsigned long)task_stack_page(p); 738 stack = (unsigned long)task_stack_page(p);
714 if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE) 739 if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE)
715 return 0; 740 return 0;
716 fp = *(u64 *)(p->thread.sp); 741 fp = *(u64 *)(p->thread.sp);
717 do { 742 do {
718 if (fp < (unsigned long)stack || 743 if (fp < (unsigned long)stack ||
719 fp > (unsigned long)stack+THREAD_SIZE) 744 fp > (unsigned long)stack+THREAD_SIZE)
720 return 0; 745 return 0;
721 ip = *(u64 *)(fp+8); 746 ip = *(u64 *)(fp+8);
722 if (!in_sched_functions(ip)) 747 if (!in_sched_functions(ip))
723 return ip; 748 return ip;
724 fp = *(u64 *)fp; 749 fp = *(u64 *)fp;
725 } while (count++ < 16); 750 } while (count++ < 16);
726 return 0; 751 return 0;
727} 752}
728 753
729long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) 754long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
730{ 755{
731 int ret = 0; 756 int ret = 0;
732 int doit = task == current; 757 int doit = task == current;
733 int cpu; 758 int cpu;
734 759
735 switch (code) { 760 switch (code) {
736 case ARCH_SET_GS: 761 case ARCH_SET_GS:
737 if (addr >= TASK_SIZE_OF(task)) 762 if (addr >= TASK_SIZE_OF(task))
738 return -EPERM; 763 return -EPERM;
739 cpu = get_cpu(); 764 cpu = get_cpu();
740 /* handle small bases via the GDT because that's faster to 765 /* handle small bases via the GDT because that's faster to
741 switch. */ 766 switch. */
742 if (addr <= 0xffffffff) { 767 if (addr <= 0xffffffff) {
743 set_32bit_tls(task, GS_TLS, addr); 768 set_32bit_tls(task, GS_TLS, addr);
744 if (doit) { 769 if (doit) {
745 load_TLS(&task->thread, cpu); 770 load_TLS(&task->thread, cpu);
746 load_gs_index(GS_TLS_SEL); 771 load_gs_index(GS_TLS_SEL);
747 } 772 }
748 task->thread.gsindex = GS_TLS_SEL; 773 task->thread.gsindex = GS_TLS_SEL;
749 task->thread.gs = 0; 774 task->thread.gs = 0;
750 } else { 775 } else {
751 task->thread.gsindex = 0; 776 task->thread.gsindex = 0;
752 task->thread.gs = addr; 777 task->thread.gs = addr;
753 if (doit) { 778 if (doit) {
754 load_gs_index(0); 779 load_gs_index(0);
755 ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr); 780 ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr);
756 } 781 }
757 } 782 }
758 put_cpu(); 783 put_cpu();
759 break; 784 break;
@@ -807,8 +832,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
807 rdmsrl(MSR_KERNEL_GS_BASE, base); 832 rdmsrl(MSR_KERNEL_GS_BASE, base);
808 else 833 else
809 base = task->thread.gs; 834 base = task->thread.gs;
810 } 835 } else
811 else
812 base = task->thread.gs; 836 base = task->thread.gs;
813 ret = put_user(base, (unsigned long __user *)addr); 837 ret = put_user(base, (unsigned long __user *)addr);
814 break; 838 break;