diff options
Diffstat (limited to 'virt/kvm/arm/arch_timer.c')
-rw-r--r-- | virt/kvm/arm/arch_timer.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index 22fa819a9b6a..1c0772b340d8 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c | |||
@@ -61,12 +61,14 @@ static void timer_disarm(struct arch_timer_cpu *timer) | |||
61 | 61 | ||
62 | static void kvm_timer_inject_irq(struct kvm_vcpu *vcpu) | 62 | static void kvm_timer_inject_irq(struct kvm_vcpu *vcpu) |
63 | { | 63 | { |
64 | int ret; | ||
64 | struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; | 65 | struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; |
65 | 66 | ||
66 | timer->cntv_ctl |= ARCH_TIMER_CTRL_IT_MASK; | 67 | timer->cntv_ctl |= ARCH_TIMER_CTRL_IT_MASK; |
67 | kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id, | 68 | ret = kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id, |
68 | timer->irq->irq, | 69 | timer->irq->irq, |
69 | timer->irq->level); | 70 | timer->irq->level); |
71 | WARN_ON(ret); | ||
70 | } | 72 | } |
71 | 73 | ||
72 | static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id) | 74 | static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id) |
@@ -307,12 +309,24 @@ void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu) | |||
307 | timer_disarm(timer); | 309 | timer_disarm(timer); |
308 | } | 310 | } |
309 | 311 | ||
310 | int kvm_timer_init(struct kvm *kvm) | 312 | void kvm_timer_enable(struct kvm *kvm) |
311 | { | 313 | { |
312 | if (timecounter && wqueue) { | 314 | if (kvm->arch.timer.enabled) |
313 | kvm->arch.timer.cntvoff = kvm_phys_timer_read(); | 315 | return; |
316 | |||
317 | /* | ||
318 | * There is a potential race here between VCPUs starting for the first | ||
319 | * time, which may be enabling the timer multiple times. That doesn't | ||
320 | * hurt though, because we're just setting a variable to the same | ||
321 | * variable that it already was. The important thing is that all | ||
322 | * VCPUs have the enabled variable set, before entering the guest, if | ||
323 | * the arch timers are enabled. | ||
324 | */ | ||
325 | if (timecounter && wqueue) | ||
314 | kvm->arch.timer.enabled = 1; | 326 | kvm->arch.timer.enabled = 1; |
315 | } | 327 | } |
316 | 328 | ||
317 | return 0; | 329 | void kvm_timer_init(struct kvm *kvm) |
330 | { | ||
331 | kvm->arch.timer.cntvoff = kvm_phys_timer_read(); | ||
318 | } | 332 | } |