aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/i8254.c
diff options
context:
space:
mode:
authorMarcelo Tosatti <mtosatti@redhat.com>2009-02-23 08:57:41 -0500
committerAvi Kivity <avi@redhat.com>2009-06-10 04:48:25 -0400
commitd3c7b77d1a6e7a0a27035a7ba723a3455317883e (patch)
tree65053ca8122dda5772c48ce70c9d99e8127f8cdd /arch/x86/kvm/i8254.c
parentfd66842370e32f3bbe429677280a326c07e508c1 (diff)
KVM: unify part of generic timer handling
Hide the internals of vcpu awakening / injection from the in-kernel emulated timers. This makes future changes in this logic easier and decreases the distance to more generic timer handling. Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/i8254.c')
-rw-r--r--arch/x86/kvm/i8254.c57
1 files changed, 20 insertions, 37 deletions
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 09ae841ff462..4e2e3f26dbf8 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -219,25 +219,6 @@ static void pit_latch_status(struct kvm *kvm, int channel)
219 } 219 }
220} 220}
221 221
222static int __pit_timer_fn(struct kvm_kpit_state *ps)
223{
224 struct kvm_vcpu *vcpu0 = ps->pit->kvm->vcpus[0];
225 struct kvm_kpit_timer *pt = &ps->pit_timer;
226
227 if (!atomic_inc_and_test(&pt->pending))
228 set_bit(KVM_REQ_PENDING_TIMER, &vcpu0->requests);
229
230 if (!pt->reinject)
231 atomic_set(&pt->pending, 1);
232
233 if (vcpu0 && waitqueue_active(&vcpu0->wq))
234 wake_up_interruptible(&vcpu0->wq);
235
236 hrtimer_add_expires_ns(&pt->timer, pt->period);
237
238 return (pt->period == 0 ? 0 : 1);
239}
240
241int pit_has_pending_timer(struct kvm_vcpu *vcpu) 222int pit_has_pending_timer(struct kvm_vcpu *vcpu)
242{ 223{
243 struct kvm_pit *pit = vcpu->kvm->arch.vpit; 224 struct kvm_pit *pit = vcpu->kvm->arch.vpit;
@@ -258,21 +239,6 @@ static void kvm_pit_ack_irq(struct kvm_irq_ack_notifier *kian)
258 spin_unlock(&ps->inject_lock); 239 spin_unlock(&ps->inject_lock);
259} 240}
260 241
261static enum hrtimer_restart pit_timer_fn(struct hrtimer *data)
262{
263 struct kvm_kpit_state *ps;
264 int restart_timer = 0;
265
266 ps = container_of(data, struct kvm_kpit_state, pit_timer.timer);
267
268 restart_timer = __pit_timer_fn(ps);
269
270 if (restart_timer)
271 return HRTIMER_RESTART;
272 else
273 return HRTIMER_NORESTART;
274}
275
276void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu) 242void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu)
277{ 243{
278 struct kvm_pit *pit = vcpu->kvm->arch.vpit; 244 struct kvm_pit *pit = vcpu->kvm->arch.vpit;
@@ -286,15 +252,26 @@ void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu)
286 hrtimer_start_expires(timer, HRTIMER_MODE_ABS); 252 hrtimer_start_expires(timer, HRTIMER_MODE_ABS);
287} 253}
288 254
289static void destroy_pit_timer(struct kvm_kpit_timer *pt) 255static void destroy_pit_timer(struct kvm_timer *pt)
290{ 256{
291 pr_debug("pit: execute del timer!\n"); 257 pr_debug("pit: execute del timer!\n");
292 hrtimer_cancel(&pt->timer); 258 hrtimer_cancel(&pt->timer);
293} 259}
294 260
261static bool kpit_is_periodic(struct kvm_timer *ktimer)
262{
263 struct kvm_kpit_state *ps = container_of(ktimer, struct kvm_kpit_state,
264 pit_timer);
265 return ps->is_periodic;
266}
267
268struct kvm_timer_ops kpit_ops = {
269 .is_periodic = kpit_is_periodic,
270};
271
295static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period) 272static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period)
296{ 273{
297 struct kvm_kpit_timer *pt = &ps->pit_timer; 274 struct kvm_timer *pt = &ps->pit_timer;
298 s64 interval; 275 s64 interval;
299 276
300 interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ); 277 interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ);
@@ -304,7 +281,13 @@ static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period)
304 /* TODO The new value only affected after the retriggered */ 281 /* TODO The new value only affected after the retriggered */
305 hrtimer_cancel(&pt->timer); 282 hrtimer_cancel(&pt->timer);
306 pt->period = (is_period == 0) ? 0 : interval; 283 pt->period = (is_period == 0) ? 0 : interval;
307 pt->timer.function = pit_timer_fn; 284 ps->is_periodic = is_period;
285
286 pt->timer.function = kvm_timer_fn;
287 pt->t_ops = &kpit_ops;
288 pt->kvm = ps->pit->kvm;
289 pt->vcpu_id = 0;
290
308 atomic_set(&pt->pending, 0); 291 atomic_set(&pt->pending, 0);
309 ps->irq_ack = 1; 292 ps->irq_ack = 1;
310 293