diff options
Diffstat (limited to 'arch/x86/kvm/i8254.c')
-rw-r--r-- | arch/x86/kvm/i8254.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 3324d90038e4..3829aa7b663f 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c | |||
@@ -200,10 +200,12 @@ int __pit_timer_fn(struct kvm_kpit_state *ps) | |||
200 | 200 | ||
201 | atomic_inc(&pt->pending); | 201 | atomic_inc(&pt->pending); |
202 | smp_mb__after_atomic_inc(); | 202 | smp_mb__after_atomic_inc(); |
203 | /* FIXME: handle case where the guest is in guest mode */ | 203 | if (vcpu0) { |
204 | if (vcpu0 && waitqueue_active(&vcpu0->wq)) { | 204 | set_bit(KVM_REQ_PENDING_TIMER, &vcpu0->requests); |
205 | vcpu0->arch.mp_state = KVM_MP_STATE_RUNNABLE; | 205 | if (waitqueue_active(&vcpu0->wq)) { |
206 | wake_up_interruptible(&vcpu0->wq); | 206 | vcpu0->arch.mp_state = KVM_MP_STATE_RUNNABLE; |
207 | wake_up_interruptible(&vcpu0->wq); | ||
208 | } | ||
207 | } | 209 | } |
208 | 210 | ||
209 | pt->timer.expires = ktime_add_ns(pt->timer.expires, pt->period); | 211 | pt->timer.expires = ktime_add_ns(pt->timer.expires, pt->period); |
@@ -216,7 +218,7 @@ int pit_has_pending_timer(struct kvm_vcpu *vcpu) | |||
216 | { | 218 | { |
217 | struct kvm_pit *pit = vcpu->kvm->arch.vpit; | 219 | struct kvm_pit *pit = vcpu->kvm->arch.vpit; |
218 | 220 | ||
219 | if (pit && vcpu->vcpu_id == 0) | 221 | if (pit && vcpu->vcpu_id == 0 && pit->pit_state.inject_pending) |
220 | return atomic_read(&pit->pit_state.pit_timer.pending); | 222 | return atomic_read(&pit->pit_state.pit_timer.pending); |
221 | 223 | ||
222 | return 0; | 224 | return 0; |
@@ -237,6 +239,19 @@ static enum hrtimer_restart pit_timer_fn(struct hrtimer *data) | |||
237 | return HRTIMER_NORESTART; | 239 | return HRTIMER_NORESTART; |
238 | } | 240 | } |
239 | 241 | ||
242 | void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu) | ||
243 | { | ||
244 | struct kvm_pit *pit = vcpu->kvm->arch.vpit; | ||
245 | struct hrtimer *timer; | ||
246 | |||
247 | if (vcpu->vcpu_id != 0 || !pit) | ||
248 | return; | ||
249 | |||
250 | timer = &pit->pit_state.pit_timer.timer; | ||
251 | if (hrtimer_cancel(timer)) | ||
252 | hrtimer_start(timer, timer->expires, HRTIMER_MODE_ABS); | ||
253 | } | ||
254 | |||
240 | static void destroy_pit_timer(struct kvm_kpit_timer *pt) | 255 | static void destroy_pit_timer(struct kvm_kpit_timer *pt) |
241 | { | 256 | { |
242 | pr_debug("pit: execute del timer!\n"); | 257 | pr_debug("pit: execute del timer!\n"); |