x86: fix context switch on debug hypervisor after 1183:5e3c342a325e Looking at anything but the result field of a multicall structure after issuing the multicall is invalid - the debug hypervisor intentionally clobbers all other fields. On i386 also remove some left over debugging code. Signed-off-by: Jan Beulich --- a/arch/i386/kernel/process-xen.c +++ b/arch/i386/kernel/process-xen.c @@ -548,7 +548,7 @@ struct task_struct fastcall * __switch_t { struct thread_struct *prev = &prev_p->thread, *next = &next_p->thread; - int cpu = smp_processor_id(); + int cpu = smp_processor_id(), cr0_ts; #ifndef CONFIG_X86_NO_TSS struct tss_struct *tss = &per_cpu(init_tss, cpu); #endif @@ -575,9 +575,6 @@ struct task_struct fastcall * __switch_t mcl->args[0] = 1; mcl++; } -#if 0 /* lazy fpu sanity check */ - else BUG_ON(!(read_cr0() & 8)); -#endif /* * Reload esp0. @@ -639,11 +636,14 @@ struct task_struct fastcall * __switch_t BUG_ON(pdo > _pdo + ARRAY_SIZE(_pdo)); #endif BUG_ON(mcl > _mcl + ARRAY_SIZE(_mcl)); - if (_mcl->op == __HYPERVISOR_fpu_taskswitch) + if (_mcl->op == __HYPERVISOR_fpu_taskswitch) { __get_cpu_var(xen_x86_cr0_upd) = X86_CR0_TS; + cr0_ts = 1; + } else + cr0_ts = 0; if (unlikely(HYPERVISOR_multicall_check(_mcl, mcl - _mcl, NULL))) BUG(); - if (_mcl->op == __HYPERVISOR_fpu_taskswitch) { + if (cr0_ts) { __get_cpu_var(xen_x86_cr0) |= X86_CR0_TS; xen_clear_cr0_upd(); } --- a/arch/x86_64/kernel/process-xen.c +++ b/arch/x86_64/kernel/process-xen.c @@ -486,7 +486,7 @@ __switch_to(struct task_struct *prev_p, { struct thread_struct *prev = &prev_p->thread, *next = &next_p->thread; - int cpu = smp_processor_id(); + int cpu = smp_processor_id(), cr0_ts; #ifndef CONFIG_X86_NO_TSS struct tss_struct *tss = &per_cpu(init_tss, cpu); #endif @@ -572,11 +572,14 @@ __switch_to(struct task_struct *prev_p, BUG_ON(pdo > _pdo + ARRAY_SIZE(_pdo)); #endif BUG_ON(mcl > _mcl + ARRAY_SIZE(_mcl)); - if (_mcl->op == __HYPERVISOR_fpu_taskswitch) + if (_mcl->op == __HYPERVISOR_fpu_taskswitch) { __get_cpu_var(xen_x86_cr0_upd) = X86_CR0_TS; + cr0_ts = 1; + } else + cr0_ts = 0; if (unlikely(HYPERVISOR_multicall_check(_mcl, mcl - _mcl, NULL))) BUG(); - if (_mcl->op == __HYPERVISOR_fpu_taskswitch) { + if (cr0_ts) { __get_cpu_var(xen_x86_cr0) |= X86_CR0_TS; xen_clear_cr0_upd(); }