Jan Beulich
2012-Aug-01 09:18 UTC
linux-2.6.18/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 <jbeulich@suse.com>
--- 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();
}
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel