aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ia64/kvm/kvm-ia64.c6
-rw-r--r--arch/x86/kvm/x86.c57
-rw-r--r--virt/kvm/kvm_main.c5
3 files changed, 40 insertions, 28 deletions
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index 4623a90e515a..d2a90fd505b0 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -488,10 +488,10 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu)
488 hrtimer_cancel(p_ht); 488 hrtimer_cancel(p_ht);
489 vcpu->arch.ht_active = 0; 489 vcpu->arch.ht_active = 0;
490 490
491 if (test_and_clear_bit(KVM_REQ_UNHALT, &vcpu->requests)) 491 if (test_and_clear_bit(KVM_REQ_UNHALT, &vcpu->requests) ||
492 kvm_cpu_has_pending_timer(vcpu))
492 if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED) 493 if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED)
493 vcpu->arch.mp_state = 494 vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
494 KVM_MP_STATE_RUNNABLE;
495 495
496 if (vcpu->arch.mp_state != KVM_MP_STATE_RUNNABLE) 496 if (vcpu->arch.mp_state != KVM_MP_STATE_RUNNABLE)
497 return -EINTR; 497 return -EINTR;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index c0ae5e6cba9b..8fca7a4e95a3 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3133,9 +3133,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3133 } 3133 }
3134 } 3134 }
3135 3135
3136 clear_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests);
3137 kvm_inject_pending_timer_irqs(vcpu);
3138
3139 preempt_disable(); 3136 preempt_disable();
3140 3137
3141 kvm_x86_ops->prepare_guest_switch(vcpu); 3138 kvm_x86_ops->prepare_guest_switch(vcpu);
@@ -3235,6 +3232,7 @@ out:
3235 return r; 3232 return r;
3236} 3233}
3237 3234
3235
3238static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 3236static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3239{ 3237{
3240 int r; 3238 int r;
@@ -3261,29 +3259,42 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3261 kvm_vcpu_block(vcpu); 3259 kvm_vcpu_block(vcpu);
3262 down_read(&vcpu->kvm->slots_lock); 3260 down_read(&vcpu->kvm->slots_lock);
3263 if (test_and_clear_bit(KVM_REQ_UNHALT, &vcpu->requests)) 3261 if (test_and_clear_bit(KVM_REQ_UNHALT, &vcpu->requests))
3264 if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED) 3262 {
3263 switch(vcpu->arch.mp_state) {
3264 case KVM_MP_STATE_HALTED:
3265 vcpu->arch.mp_state = 3265 vcpu->arch.mp_state =
3266 KVM_MP_STATE_RUNNABLE; 3266 KVM_MP_STATE_RUNNABLE;
3267 if (vcpu->arch.mp_state != KVM_MP_STATE_RUNNABLE) 3267 case KVM_MP_STATE_RUNNABLE:
3268 r = -EINTR; 3268 break;
3269 case KVM_MP_STATE_SIPI_RECEIVED:
3270 default:
3271 r = -EINTR;
3272 break;
3273 }
3274 }
3269 } 3275 }
3270 3276
3271 if (r > 0) { 3277 if (r <= 0)
3272 if (dm_request_for_irq_injection(vcpu, kvm_run)) { 3278 break;
3273 r = -EINTR; 3279
3274 kvm_run->exit_reason = KVM_EXIT_INTR; 3280 clear_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests);
3275 ++vcpu->stat.request_irq_exits; 3281 if (kvm_cpu_has_pending_timer(vcpu))
3276 } 3282 kvm_inject_pending_timer_irqs(vcpu);
3277 if (signal_pending(current)) { 3283
3278 r = -EINTR; 3284 if (dm_request_for_irq_injection(vcpu, kvm_run)) {
3279 kvm_run->exit_reason = KVM_EXIT_INTR; 3285 r = -EINTR;
3280 ++vcpu->stat.signal_exits; 3286 kvm_run->exit_reason = KVM_EXIT_INTR;
3281 } 3287 ++vcpu->stat.request_irq_exits;
3282 if (need_resched()) { 3288 }
3283 up_read(&vcpu->kvm->slots_lock); 3289 if (signal_pending(current)) {
3284 kvm_resched(vcpu); 3290 r = -EINTR;
3285 down_read(&vcpu->kvm->slots_lock); 3291 kvm_run->exit_reason = KVM_EXIT_INTR;
3286 } 3292 ++vcpu->stat.signal_exits;
3293 }
3294 if (need_resched()) {
3295 up_read(&vcpu->kvm->slots_lock);
3296 kvm_resched(vcpu);
3297 down_read(&vcpu->kvm->slots_lock);
3287 } 3298 }
3288 } 3299 }
3289 3300
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 934dd1c9487e..a1a4272fa57c 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1611,11 +1611,12 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)
1611 prepare_to_wait(&vcpu->wq, &wait, TASK_INTERRUPTIBLE); 1611 prepare_to_wait(&vcpu->wq, &wait, TASK_INTERRUPTIBLE);
1612 1612
1613 if (kvm_cpu_has_interrupt(vcpu) || 1613 if (kvm_cpu_has_interrupt(vcpu) ||
1614 kvm_cpu_has_pending_timer(vcpu) || 1614 kvm_arch_vcpu_runnable(vcpu)) {
1615 kvm_arch_vcpu_runnable(vcpu)) {
1616 set_bit(KVM_REQ_UNHALT, &vcpu->requests); 1615 set_bit(KVM_REQ_UNHALT, &vcpu->requests);
1617 break; 1616 break;
1618 } 1617 }
1618 if (kvm_cpu_has_pending_timer(vcpu))
1619 break;
1619 if (signal_pending(current)) 1620 if (signal_pending(current))
1620 break; 1621 break;
1621 1622