diff options
author | Jes Sorensen <jes@sgi.com> | 2009-04-09 16:38:14 +0200 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-04-11 19:02:35 +0300 |
commit | defdf1e543e0725019ef5095894ba16cdf552eaf (patch) | |
tree | 2ec5506b657ae21ffb756207a96d8225ffb261d4 | |
parent | bc6f84ddc4a5ae0aa146688fe40db62075c948cd (diff) |
Reorder locking as down_read() may return with local interrupts enabled,
which means we could go into vti_vcpu_run() with interrupts enabled.
This caused random crashes on the Altix as the timer interrupt tried
to read a memory mapped clock source, for which the TLB had not yet been
reinstated in the exit, before ipsr was retored.
Signed-off-by: Jes Sorensen <jes@sgi.com>
Acked-by: Xiantao Zhang <xiantao.zhang@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index d8f43e472253..112b402c84c5 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -662,20 +662,22 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) int r; again: - preempt_disable(); - local_irq_disable(); - if (signal_pending(current)) { - local_irq_enable(); - preempt_enable(); r = -EINTR; kvm_run->exit_reason = KVM_EXIT_INTR; goto out; } + /* + * down_read() may sleep and return with interrupts enabled + */ + down_read(&vcpu->kvm->slots_lock); + + preempt_disable(); + local_irq_disable(); + vcpu->guest_mode = 1; kvm_guest_enter(); - down_read(&vcpu->kvm->slots_lock); r = vti_vcpu_run(vcpu, kvm_run); if (r < 0) { local_irq_enable(); |