aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJes Sorensen <jes@sgi.com>2009-04-09 16:38:14 +0200
committerAvi Kivity <avi@redhat.com>2009-04-11 19:02:35 +0300
commitdefdf1e543e0725019ef5095894ba16cdf552eaf (patch)
tree2ec5506b657ae21ffb756207a96d8225ffb261d4
parentbc6f84ddc4a5ae0aa146688fe40db62075c948cd (diff)
KVM: ia64: fix locking order entering guestkvm-85rc6kvm-85rc5kvm-85rc4kvm-85
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.c14
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();