diff options
Diffstat (limited to 'arch/x86/kernel/process_32.c')
| -rw-r--r-- | arch/x86/kernel/process_32.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index f8476dfbb60d..5cec8a75a4e8 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
| @@ -316,6 +316,14 @@ void exit_thread(void) | |||
| 316 | tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; | 316 | tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; |
| 317 | put_cpu(); | 317 | put_cpu(); |
| 318 | } | 318 | } |
| 319 | #ifdef CONFIG_X86_DS | ||
| 320 | /* Free any DS contexts that have not been properly released. */ | ||
| 321 | if (unlikely(current->thread.ds_ctx)) { | ||
| 322 | /* we clear debugctl to make sure DS is not used. */ | ||
| 323 | update_debugctlmsr(0); | ||
| 324 | ds_free(current->thread.ds_ctx); | ||
| 325 | } | ||
| 326 | #endif /* CONFIG_X86_DS */ | ||
| 319 | } | 327 | } |
| 320 | 328 | ||
| 321 | void flush_thread(void) | 329 | void flush_thread(void) |
| @@ -482,18 +490,27 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | |||
| 482 | { | 490 | { |
| 483 | struct thread_struct *prev, *next; | 491 | struct thread_struct *prev, *next; |
| 484 | unsigned long debugctl; | 492 | unsigned long debugctl; |
| 493 | unsigned long ds_prev = 0, ds_next = 0; | ||
| 485 | 494 | ||
| 486 | prev = &prev_p->thread; | 495 | prev = &prev_p->thread; |
| 487 | next = &next_p->thread; | 496 | next = &next_p->thread; |
| 488 | 497 | ||
| 489 | debugctl = prev->debugctlmsr; | 498 | debugctl = prev->debugctlmsr; |
| 490 | if (next->ds_area_msr != prev->ds_area_msr) { | 499 | |
| 500 | #ifdef CONFIG_X86_DS | ||
| 501 | if (prev->ds_ctx) | ||
| 502 | ds_prev = (unsigned long)prev->ds_ctx->ds; | ||
| 503 | if (next->ds_ctx) | ||
| 504 | ds_next = (unsigned long)next->ds_ctx->ds; | ||
| 505 | |||
| 506 | if (ds_next != ds_prev) { | ||
| 491 | /* we clear debugctl to make sure DS | 507 | /* we clear debugctl to make sure DS |
| 492 | * is not in use when we change it */ | 508 | * is not in use when we change it */ |
| 493 | debugctl = 0; | 509 | debugctl = 0; |
| 494 | update_debugctlmsr(0); | 510 | update_debugctlmsr(0); |
| 495 | wrmsr(MSR_IA32_DS_AREA, next->ds_area_msr, 0); | 511 | wrmsr(MSR_IA32_DS_AREA, ds_next, 0); |
| 496 | } | 512 | } |
| 513 | #endif /* CONFIG_X86_DS */ | ||
| 497 | 514 | ||
| 498 | if (next->debugctlmsr != debugctl) | 515 | if (next->debugctlmsr != debugctl) |
| 499 | update_debugctlmsr(next->debugctlmsr); | 516 | update_debugctlmsr(next->debugctlmsr); |
| @@ -517,13 +534,13 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | |||
| 517 | hard_enable_TSC(); | 534 | hard_enable_TSC(); |
| 518 | } | 535 | } |
| 519 | 536 | ||
| 520 | #ifdef X86_BTS | 537 | #ifdef CONFIG_X86_PTRACE_BTS |
| 521 | if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) | 538 | if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) |
| 522 | ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); | 539 | ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); |
| 523 | 540 | ||
| 524 | if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) | 541 | if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) |
| 525 | ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); | 542 | ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); |
| 526 | #endif | 543 | #endif /* CONFIG_X86_PTRACE_BTS */ |
| 527 | 544 | ||
| 528 | 545 | ||
| 529 | if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { | 546 | if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { |
