i8254.c (ab4c14763b434d48bc7732e475ff4d5b6b9d3e3b) i8254.c (a0aace5ac0efdb2bcb71e10d9c9ca6a851fa59f9)
1/*
2 * 8253/8254 interval timer emulation
3 *
4 * Copyright (c) 2003-2004 Fabrice Bellard
5 * Copyright (c) 2006 Intel Corporation
6 * Copyright (c) 2007 Keir Fraser, XenSource Inc
7 * Copyright (c) 2008 Intel Corporation
8 * Copyright 2009 Red Hat, Inc. and/or its affiliates.

--- 250 unchanged lines hidden (view full) ---

259static void pit_do_work(struct kthread_work *work)
260{
261 struct kvm_pit *pit = container_of(work, struct kvm_pit, expired);
262 struct kvm *kvm = pit->kvm;
263 struct kvm_vcpu *vcpu;
264 int i;
265 struct kvm_kpit_state *ps = &pit->pit_state;
266
1/*
2 * 8253/8254 interval timer emulation
3 *
4 * Copyright (c) 2003-2004 Fabrice Bellard
5 * Copyright (c) 2006 Intel Corporation
6 * Copyright (c) 2007 Keir Fraser, XenSource Inc
7 * Copyright (c) 2008 Intel Corporation
8 * Copyright 2009 Red Hat, Inc. and/or its affiliates.

--- 250 unchanged lines hidden (view full) ---

259static void pit_do_work(struct kthread_work *work)
260{
261 struct kvm_pit *pit = container_of(work, struct kvm_pit, expired);
262 struct kvm *kvm = pit->kvm;
263 struct kvm_vcpu *vcpu;
264 int i;
265 struct kvm_kpit_state *ps = &pit->pit_state;
266
267 if (ps->reinject && !atomic_xchg(&ps->irq_ack, 0))
267 if (atomic_read(&ps->reinject) && !atomic_xchg(&ps->irq_ack, 0))
268 return;
269
270 kvm_set_irq(kvm, pit->irq_source_id, 0, 1, false);
271 kvm_set_irq(kvm, pit->irq_source_id, 0, 0, false);
272
273 /*
274 * Provides NMI watchdog support via Virtual Wire mode.
275 * The route is: PIT -> LVT0 in NMI mode.

--- 8 unchanged lines hidden (view full) ---

284 kvm_apic_nmi_wd_deliver(vcpu);
285}
286
287static enum hrtimer_restart pit_timer_fn(struct hrtimer *data)
288{
289 struct kvm_kpit_state *ps = container_of(data, struct kvm_kpit_state, timer);
290 struct kvm_pit *pt = pit_state_to_pit(ps);
291
268 return;
269
270 kvm_set_irq(kvm, pit->irq_source_id, 0, 1, false);
271 kvm_set_irq(kvm, pit->irq_source_id, 0, 0, false);
272
273 /*
274 * Provides NMI watchdog support via Virtual Wire mode.
275 * The route is: PIT -> LVT0 in NMI mode.

--- 8 unchanged lines hidden (view full) ---

284 kvm_apic_nmi_wd_deliver(vcpu);
285}
286
287static enum hrtimer_restart pit_timer_fn(struct hrtimer *data)
288{
289 struct kvm_kpit_state *ps = container_of(data, struct kvm_kpit_state, timer);
290 struct kvm_pit *pt = pit_state_to_pit(ps);
291
292 if (ps->reinject)
292 if (atomic_read(&ps->reinject))
293 atomic_inc(&ps->pending);
294
295 queue_kthread_work(&pt->worker, &pt->expired);
296
297 if (ps->is_periodic) {
298 hrtimer_add_expires_ns(&ps->timer, ps->period);
299 return HRTIMER_RESTART;
300 } else

--- 6 unchanged lines hidden (view full) ---

307 atomic_set(&pit->pit_state.irq_ack, 1);
308}
309
310void kvm_pit_set_reinject(struct kvm_pit *pit, bool reinject)
311{
312 struct kvm_kpit_state *ps = &pit->pit_state;
313 struct kvm *kvm = pit->kvm;
314
293 atomic_inc(&ps->pending);
294
295 queue_kthread_work(&pt->worker, &pt->expired);
296
297 if (ps->is_periodic) {
298 hrtimer_add_expires_ns(&ps->timer, ps->period);
299 return HRTIMER_RESTART;
300 } else

--- 6 unchanged lines hidden (view full) ---

307 atomic_set(&pit->pit_state.irq_ack, 1);
308}
309
310void kvm_pit_set_reinject(struct kvm_pit *pit, bool reinject)
311{
312 struct kvm_kpit_state *ps = &pit->pit_state;
313 struct kvm *kvm = pit->kvm;
314
315 if (ps->reinject == reinject)
315 if (atomic_read(&ps->reinject) == reinject)
316 return;
317
318 if (reinject) {
319 /* The initial state is preserved while ps->reinject == 0. */
320 kvm_pit_reset_reinject(pit);
321 kvm_register_irq_ack_notifier(kvm, &ps->irq_ack_notifier);
322 kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
323 } else {
324 kvm_unregister_irq_ack_notifier(kvm, &ps->irq_ack_notifier);
325 kvm_unregister_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
326 }
327
316 return;
317
318 if (reinject) {
319 /* The initial state is preserved while ps->reinject == 0. */
320 kvm_pit_reset_reinject(pit);
321 kvm_register_irq_ack_notifier(kvm, &ps->irq_ack_notifier);
322 kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
323 } else {
324 kvm_unregister_irq_ack_notifier(kvm, &ps->irq_ack_notifier);
325 kvm_unregister_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
326 }
327
328 ps->reinject = reinject;
328 atomic_set(&ps->reinject, reinject);
329}
330
331static void create_pit_timer(struct kvm_pit *pit, u32 val, int is_period)
332{
333 struct kvm_kpit_state *ps = &pit->pit_state;
334 struct kvm *kvm = pit->kvm;
335 s64 interval;
336

--- 420 unchanged lines hidden ---
329}
330
331static void create_pit_timer(struct kvm_pit *pit, u32 val, int is_period)
332{
333 struct kvm_kpit_state *ps = &pit->pit_state;
334 struct kvm *kvm = pit->kvm;
335 s64 interval;
336

--- 420 unchanged lines hidden ---