diff options
Diffstat (limited to 'arch/x86/kernel/process_32.c')
| -rw-r--r-- | arch/x86/kernel/process_32.c | 64 |
1 files changed, 52 insertions, 12 deletions
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 3b7a1ddcc0bc..205188db9626 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #include <linux/tick.h> | 37 | #include <linux/tick.h> |
| 38 | #include <linux/percpu.h> | 38 | #include <linux/percpu.h> |
| 39 | #include <linux/prctl.h> | 39 | #include <linux/prctl.h> |
| 40 | #include <linux/dmi.h> | ||
| 40 | 41 | ||
| 41 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
| 42 | #include <asm/pgtable.h> | 43 | #include <asm/pgtable.h> |
| @@ -55,6 +56,9 @@ | |||
| 55 | #include <asm/tlbflush.h> | 56 | #include <asm/tlbflush.h> |
| 56 | #include <asm/cpu.h> | 57 | #include <asm/cpu.h> |
| 57 | #include <asm/kdebug.h> | 58 | #include <asm/kdebug.h> |
| 59 | #include <asm/idle.h> | ||
| 60 | #include <asm/syscalls.h> | ||
| 61 | #include <asm/smp.h> | ||
| 58 | 62 | ||
| 59 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); | 63 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); |
| 60 | 64 | ||
| @@ -88,6 +92,7 @@ static void cpu_exit_clear(void) | |||
| 88 | cpu_clear(cpu, cpu_callin_map); | 92 | cpu_clear(cpu, cpu_callin_map); |
| 89 | 93 | ||
| 90 | numa_remove_cpu(cpu); | 94 | numa_remove_cpu(cpu); |
| 95 | c1e_remove_cpu(cpu); | ||
| 91 | } | 96 | } |
| 92 | 97 | ||
| 93 | /* We don't actually take CPU down, just spin without interrupts. */ | 98 | /* We don't actually take CPU down, just spin without interrupts. */ |
| @@ -159,6 +164,7 @@ void __show_registers(struct pt_regs *regs, int all) | |||
| 159 | unsigned long d0, d1, d2, d3, d6, d7; | 164 | unsigned long d0, d1, d2, d3, d6, d7; |
| 160 | unsigned long sp; | 165 | unsigned long sp; |
| 161 | unsigned short ss, gs; | 166 | unsigned short ss, gs; |
| 167 | const char *board; | ||
| 162 | 168 | ||
| 163 | if (user_mode_vm(regs)) { | 169 | if (user_mode_vm(regs)) { |
| 164 | sp = regs->sp; | 170 | sp = regs->sp; |
| @@ -171,11 +177,15 @@ void __show_registers(struct pt_regs *regs, int all) | |||
| 171 | } | 177 | } |
| 172 | 178 | ||
| 173 | printk("\n"); | 179 | printk("\n"); |
| 174 | printk("Pid: %d, comm: %s %s (%s %.*s)\n", | 180 | |
| 181 | board = dmi_get_system_info(DMI_PRODUCT_NAME); | ||
| 182 | if (!board) | ||
| 183 | board = ""; | ||
| 184 | printk("Pid: %d, comm: %s %s (%s %.*s) %s\n", | ||
| 175 | task_pid_nr(current), current->comm, | 185 | task_pid_nr(current), current->comm, |
| 176 | print_tainted(), init_utsname()->release, | 186 | print_tainted(), init_utsname()->release, |
| 177 | (int)strcspn(init_utsname()->version, " "), | 187 | (int)strcspn(init_utsname()->version, " "), |
| 178 | init_utsname()->version); | 188 | init_utsname()->version, board); |
| 179 | 189 | ||
| 180 | printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n", | 190 | printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n", |
| 181 | (u16)regs->cs, regs->ip, regs->flags, | 191 | (u16)regs->cs, regs->ip, regs->flags, |
| @@ -275,6 +285,14 @@ void exit_thread(void) | |||
| 275 | tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; | 285 | tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; |
| 276 | put_cpu(); | 286 | put_cpu(); |
| 277 | } | 287 | } |
| 288 | #ifdef CONFIG_X86_DS | ||
| 289 | /* Free any DS contexts that have not been properly released. */ | ||
| 290 | if (unlikely(current->thread.ds_ctx)) { | ||
| 291 | /* we clear debugctl to make sure DS is not used. */ | ||
| 292 | update_debugctlmsr(0); | ||
| 293 | ds_free(current->thread.ds_ctx); | ||
| 294 | } | ||
| 295 | #endif /* CONFIG_X86_DS */ | ||
| 278 | } | 296 | } |
| 279 | 297 | ||
| 280 | void flush_thread(void) | 298 | void flush_thread(void) |
| @@ -436,6 +454,35 @@ int set_tsc_mode(unsigned int val) | |||
| 436 | return 0; | 454 | return 0; |
| 437 | } | 455 | } |
| 438 | 456 | ||
| 457 | #ifdef CONFIG_X86_DS | ||
| 458 | static int update_debugctl(struct thread_struct *prev, | ||
| 459 | struct thread_struct *next, unsigned long debugctl) | ||
| 460 | { | ||
| 461 | unsigned long ds_prev = 0; | ||
| 462 | unsigned long ds_next = 0; | ||
| 463 | |||
| 464 | if (prev->ds_ctx) | ||
| 465 | ds_prev = (unsigned long)prev->ds_ctx->ds; | ||
| 466 | if (next->ds_ctx) | ||
| 467 | ds_next = (unsigned long)next->ds_ctx->ds; | ||
| 468 | |||
| 469 | if (ds_next != ds_prev) { | ||
| 470 | /* we clear debugctl to make sure DS | ||
| 471 | * is not in use when we change it */ | ||
| 472 | debugctl = 0; | ||
| 473 | update_debugctlmsr(0); | ||
| 474 | wrmsr(MSR_IA32_DS_AREA, ds_next, 0); | ||
| 475 | } | ||
| 476 | return debugctl; | ||
| 477 | } | ||
| 478 | #else | ||
| 479 | static int update_debugctl(struct thread_struct *prev, | ||
| 480 | struct thread_struct *next, unsigned long debugctl) | ||
| 481 | { | ||
| 482 | return debugctl; | ||
| 483 | } | ||
| 484 | #endif /* CONFIG_X86_DS */ | ||
| 485 | |||
| 439 | static noinline void | 486 | static noinline void |
| 440 | __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | 487 | __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, |
| 441 | struct tss_struct *tss) | 488 | struct tss_struct *tss) |
| @@ -446,14 +493,7 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | |||
| 446 | prev = &prev_p->thread; | 493 | prev = &prev_p->thread; |
| 447 | next = &next_p->thread; | 494 | next = &next_p->thread; |
| 448 | 495 | ||
| 449 | debugctl = prev->debugctlmsr; | 496 | debugctl = update_debugctl(prev, next, prev->debugctlmsr); |
| 450 | if (next->ds_area_msr != prev->ds_area_msr) { | ||
| 451 | /* we clear debugctl to make sure DS | ||
| 452 | * is not in use when we change it */ | ||
| 453 | debugctl = 0; | ||
| 454 | update_debugctlmsr(0); | ||
| 455 | wrmsr(MSR_IA32_DS_AREA, next->ds_area_msr, 0); | ||
| 456 | } | ||
| 457 | 497 | ||
| 458 | if (next->debugctlmsr != debugctl) | 498 | if (next->debugctlmsr != debugctl) |
| 459 | update_debugctlmsr(next->debugctlmsr); | 499 | update_debugctlmsr(next->debugctlmsr); |
| @@ -477,13 +517,13 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | |||
| 477 | hard_enable_TSC(); | 517 | hard_enable_TSC(); |
| 478 | } | 518 | } |
| 479 | 519 | ||
| 480 | #ifdef X86_BTS | 520 | #ifdef CONFIG_X86_PTRACE_BTS |
| 481 | if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) | 521 | if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) |
| 482 | ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); | 522 | ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); |
| 483 | 523 | ||
| 484 | if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) | 524 | if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) |
| 485 | ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); | 525 | ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); |
| 486 | #endif | 526 | #endif /* CONFIG_X86_PTRACE_BTS */ |
| 487 | 527 | ||
| 488 | 528 | ||
| 489 | if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { | 529 | if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { |
