Commit 8409a06f authored by Christoffer Dall's avatar Christoffer Dall Committed by Christoffer Dall

KVM: arm/arm64: Make timer_arm and timer_disarm helpers more generic

We are about to add an additional soft timer to the arch timer state for
a VCPU and would like to be able to reuse the functions to program and
cancel a timer, so we make them slightly more generic and rename to make
it more clear that these functions work on soft timers and not the
hardware resource that this code is managing.

The armed flag on the timer state is only used to assert a condition,
and we don't rely on this assertion in any meaningful way, so we can
simply get rid of this flack and slightly reduce complexity.
Acked-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Signed-off-by: default avatarChristoffer Dall <cdall@linaro.org>
parent d33a3c8c
...@@ -48,9 +48,6 @@ struct arch_timer_cpu { ...@@ -48,9 +48,6 @@ struct arch_timer_cpu {
/* Work queued with the above timer expires */ /* Work queued with the above timer expires */
struct work_struct expired; struct work_struct expired;
/* Background timer active */
bool armed;
/* Is the timer enabled */ /* Is the timer enabled */
bool enabled; bool enabled;
}; };
......
...@@ -56,26 +56,16 @@ u64 kvm_phys_timer_read(void) ...@@ -56,26 +56,16 @@ u64 kvm_phys_timer_read(void)
return timecounter->cc->read(timecounter->cc); return timecounter->cc->read(timecounter->cc);
} }
static bool timer_is_armed(struct arch_timer_cpu *timer) static void soft_timer_start(struct hrtimer *hrt, u64 ns)
{ {
return timer->armed; hrtimer_start(hrt, ktime_add_ns(ktime_get(), ns),
}
/* timer_arm: as in "arm the timer", not as in ARM the company */
static void timer_arm(struct arch_timer_cpu *timer, u64 ns)
{
timer->armed = true;
hrtimer_start(&timer->timer, ktime_add_ns(ktime_get(), ns),
HRTIMER_MODE_ABS); HRTIMER_MODE_ABS);
} }
static void timer_disarm(struct arch_timer_cpu *timer) static void soft_timer_cancel(struct hrtimer *hrt, struct work_struct *work)
{ {
if (timer_is_armed(timer)) { hrtimer_cancel(hrt);
hrtimer_cancel(&timer->timer); cancel_work_sync(work);
cancel_work_sync(&timer->expired);
timer->armed = false;
}
} }
static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id) static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id)
...@@ -271,7 +261,7 @@ static void kvm_timer_emulate(struct kvm_vcpu *vcpu, ...@@ -271,7 +261,7 @@ static void kvm_timer_emulate(struct kvm_vcpu *vcpu,
return; return;
/* The timer has not yet expired, schedule a background timer */ /* The timer has not yet expired, schedule a background timer */
timer_arm(timer, kvm_timer_compute_delta(timer_ctx)); soft_timer_start(&timer->timer, kvm_timer_compute_delta(timer_ctx));
} }
/* /*
...@@ -285,8 +275,6 @@ void kvm_timer_schedule(struct kvm_vcpu *vcpu) ...@@ -285,8 +275,6 @@ void kvm_timer_schedule(struct kvm_vcpu *vcpu)
struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
struct arch_timer_context *ptimer = vcpu_ptimer(vcpu); struct arch_timer_context *ptimer = vcpu_ptimer(vcpu);
BUG_ON(timer_is_armed(timer));
/* /*
* No need to schedule a background timer if any guest timer has * No need to schedule a background timer if any guest timer has
* already expired, because kvm_vcpu_block will return before putting * already expired, because kvm_vcpu_block will return before putting
...@@ -306,13 +294,14 @@ void kvm_timer_schedule(struct kvm_vcpu *vcpu) ...@@ -306,13 +294,14 @@ void kvm_timer_schedule(struct kvm_vcpu *vcpu)
* The guest timers have not yet expired, schedule a background timer. * The guest timers have not yet expired, schedule a background timer.
* Set the earliest expiration time among the guest timers. * Set the earliest expiration time among the guest timers.
*/ */
timer_arm(timer, kvm_timer_earliest_exp(vcpu)); soft_timer_start(&timer->timer, kvm_timer_earliest_exp(vcpu));
} }
void kvm_timer_unschedule(struct kvm_vcpu *vcpu) void kvm_timer_unschedule(struct kvm_vcpu *vcpu)
{ {
struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
timer_disarm(timer);
soft_timer_cancel(&timer->timer, &timer->expired);
} }
static void kvm_timer_flush_hwstate_vgic(struct kvm_vcpu *vcpu) static void kvm_timer_flush_hwstate_vgic(struct kvm_vcpu *vcpu)
...@@ -448,7 +437,7 @@ void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu) ...@@ -448,7 +437,7 @@ void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu)
* This is to cancel the background timer for the physical timer * This is to cancel the background timer for the physical timer
* emulation if it is set. * emulation if it is set.
*/ */
timer_disarm(timer); soft_timer_cancel(&timer->timer, &timer->expired);
/* /*
* The guest could have modified the timer registers or the timer * The guest could have modified the timer registers or the timer
...@@ -615,7 +604,7 @@ void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu) ...@@ -615,7 +604,7 @@ void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu)
struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
timer_disarm(timer); soft_timer_cancel(&timer->timer, &timer->expired);
kvm_vgic_unmap_phys_irq(vcpu, vtimer->irq.irq); kvm_vgic_unmap_phys_irq(vcpu, vtimer->irq.irq);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment