diff options
-rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 6 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 57 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 5 |
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 | |||
3238 | static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | 3236 | static 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 | ||