diff options
Diffstat (limited to 'arch/x86/kernel/process.c')
-rw-r--r-- | arch/x86/kernel/process.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index f18fd9c15247..e7e35219b32f 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <asm/idle.h> | 20 | #include <asm/idle.h> |
21 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
22 | #include <asm/i387.h> | 22 | #include <asm/i387.h> |
23 | #include <asm/ds.h> | ||
24 | #include <asm/debugreg.h> | 23 | #include <asm/debugreg.h> |
25 | 24 | ||
26 | unsigned long idle_halt; | 25 | unsigned long idle_halt; |
@@ -48,7 +47,6 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) | |||
48 | void free_thread_xstate(struct task_struct *tsk) | 47 | void free_thread_xstate(struct task_struct *tsk) |
49 | { | 48 | { |
50 | fpu_free(&tsk->thread.fpu); | 49 | fpu_free(&tsk->thread.fpu); |
51 | WARN(tsk->thread.ds_ctx, "leaking DS context\n"); | ||
52 | } | 50 | } |
53 | 51 | ||
54 | void free_thread_info(struct thread_info *ti) | 52 | void free_thread_info(struct thread_info *ti) |
@@ -195,11 +193,16 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | |||
195 | prev = &prev_p->thread; | 193 | prev = &prev_p->thread; |
196 | next = &next_p->thread; | 194 | next = &next_p->thread; |
197 | 195 | ||
198 | if (test_tsk_thread_flag(next_p, TIF_DS_AREA_MSR) || | 196 | if (test_tsk_thread_flag(prev_p, TIF_BLOCKSTEP) ^ |
199 | test_tsk_thread_flag(prev_p, TIF_DS_AREA_MSR)) | 197 | test_tsk_thread_flag(next_p, TIF_BLOCKSTEP)) { |
200 | ds_switch_to(prev_p, next_p); | 198 | unsigned long debugctl = get_debugctlmsr(); |
201 | else if (next->debugctlmsr != prev->debugctlmsr) | 199 | |
202 | update_debugctlmsr(next->debugctlmsr); | 200 | debugctl &= ~DEBUGCTLMSR_BTF; |
201 | if (test_tsk_thread_flag(next_p, TIF_BLOCKSTEP)) | ||
202 | debugctl |= DEBUGCTLMSR_BTF; | ||
203 | |||
204 | update_debugctlmsr(debugctl); | ||
205 | } | ||
203 | 206 | ||
204 | if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^ | 207 | if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^ |
205 | test_tsk_thread_flag(next_p, TIF_NOTSC)) { | 208 | test_tsk_thread_flag(next_p, TIF_NOTSC)) { |
@@ -543,11 +546,13 @@ static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c) | |||
543 | * check OSVW bit for CPUs that are not affected | 546 | * check OSVW bit for CPUs that are not affected |
544 | * by erratum #400 | 547 | * by erratum #400 |
545 | */ | 548 | */ |
546 | rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, val); | 549 | if (cpu_has(c, X86_FEATURE_OSVW)) { |
547 | if (val >= 2) { | 550 | rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, val); |
548 | rdmsrl(MSR_AMD64_OSVW_STATUS, val); | 551 | if (val >= 2) { |
549 | if (!(val & BIT(1))) | 552 | rdmsrl(MSR_AMD64_OSVW_STATUS, val); |
550 | goto no_c1e_idle; | 553 | if (!(val & BIT(1))) |
554 | goto no_c1e_idle; | ||
555 | } | ||
551 | } | 556 | } |
552 | return 1; | 557 | return 1; |
553 | } | 558 | } |