The code in timer.c isn't really similar enough between the i8254 and the lapic to share. Split these into separate functions, and remove timer.c Signed-off-by: Chris Lalancette <clalance@xxxxxxxxxx> --- arch/x86/kvm/Makefile | 3 +- arch/x86/kvm/i8254.c | 27 ++++++++++++++++++++++++- arch/x86/kvm/kvm_timer.h | 5 ++- arch/x86/kvm/lapic.c | 33 +++++++++++++++++++++++++++++++- arch/x86/kvm/timer.c | 47 ---------------------------------------------- 5 files changed, 61 insertions(+), 54 deletions(-) delete mode 100644 arch/x86/kvm/timer.c diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index 31a7035..8d9adf6 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -10,8 +10,7 @@ kvm-y += $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ assigned-dev.o) kvm-$(CONFIG_IOMMU_API) += $(addprefix ../../../virt/kvm/, iommu.o) -kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \ - i8254.o timer.o +kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o i8254.o kvm-intel-y += vmx.o kvm-amd-y += svm.o diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index fab7440..dc6eff4 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -277,6 +277,30 @@ static struct kvm_timer_ops kpit_ops = { .is_periodic = kpit_is_periodic, }; +static enum hrtimer_restart pit_timer_fn(struct hrtimer *data) +{ + struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer); + struct kvm *kvm = ktimer->kvm; + + /* + * There is a race window between reading and incrementing, but we do + * not care about potentially losing timer events in the !reinject + * case anyway. + */ + if (ktimer->reinject || !atomic_read(&ktimer->pending)) + atomic_inc(&ktimer->pending); + + if (waitqueue_active(&kvm->bsp_vcpu->wq)) + wake_up_interruptible(&kvm->bsp_vcpu->wq); + + if (ktimer->t_ops->is_periodic(ktimer)) { + hrtimer_add_expires_ns(&ktimer->timer, ktimer->period); + return HRTIMER_RESTART; + } + else + return HRTIMER_NORESTART; +} + static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period) { struct kvm_timer *pt = &ps->pit_timer; @@ -291,10 +315,9 @@ static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period) pt->period = interval; ps->is_periodic = is_period; - pt->timer.function = kvm_timer_fn; + pt->timer.function = pit_timer_fn; pt->t_ops = &kpit_ops; pt->kvm = ps->pit->kvm; - pt->vcpu = pt->kvm->bsp_vcpu; atomic_set(&pt->pending, 0); ps->irq_ack = 1; diff --git a/arch/x86/kvm/kvm_timer.h b/arch/x86/kvm/kvm_timer.h index 55c7524..fbd4acb 100644 --- a/arch/x86/kvm/kvm_timer.h +++ b/arch/x86/kvm/kvm_timer.h @@ -1,3 +1,5 @@ +#ifndef __KVM_TIMER_H +#define __KVM_TIMER_H struct kvm_timer { struct hrtimer timer; @@ -13,6 +15,5 @@ struct kvm_timer_ops { bool (*is_periodic)(struct kvm_timer *); }; - -enum hrtimer_restart kvm_timer_fn(struct hrtimer *data); +#endif diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 44acf7c..0005409 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1040,6 +1040,37 @@ static const struct kvm_io_device_ops apic_mmio_ops = { .write = apic_mmio_write, }; +static enum hrtimer_restart lapic_timer_fn(struct hrtimer *data) +{ + struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer); + struct kvm_vcpu *vcpu; + struct kvm_lapic *lapic; + + vcpu = ktimer->vcpu; + if (!vcpu) + return HRTIMER_NORESTART; + + lapic = vcpu->arch.apic; + + /* + * There is a race window between reading and incrementing, but we do + * not care about potentially losing timer events in the !reinject + * case anyway. + */ + if (ktimer->reinject || !atomic_read(&ktimer->pending)) + atomic_inc(&ktimer->pending); + + if (waitqueue_active(&vcpu->wq)) + wake_up_interruptible(&vcpu->wq); + + if (ktimer->t_ops->is_periodic(ktimer)) { + hrtimer_add_expires_ns(&ktimer->timer, ktimer->period); + return HRTIMER_RESTART; + } + else + return HRTIMER_NORESTART; +} + int kvm_create_lapic(struct kvm_vcpu *vcpu) { struct kvm_lapic *apic; @@ -1065,7 +1096,7 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu) hrtimer_init(&apic->lapic_timer.timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); - apic->lapic_timer.timer.function = kvm_timer_fn; + apic->lapic_timer.timer.function = lapic_timer_fn; apic->lapic_timer.t_ops = &lapic_timer_ops; apic->lapic_timer.kvm = vcpu->kvm; apic->lapic_timer.vcpu = vcpu; diff --git a/arch/x86/kvm/timer.c b/arch/x86/kvm/timer.c deleted file mode 100644 index 72b5144..0000000 --- a/arch/x86/kvm/timer.c +++ /dev/null @@ -1,47 +0,0 @@ -#include <linux/kvm_host.h> -#include <linux/kvm.h> -#include <linux/hrtimer.h> -#include <asm/atomic.h> -#include "kvm_timer.h" - -static int __kvm_timer_fn(struct kvm_vcpu *vcpu, struct kvm_timer *ktimer) -{ - int restart_timer = 0; - wait_queue_head_t *q = &vcpu->wq; - - /* - * There is a race window between reading and incrementing, but we do - * not care about potentially loosing timer events in the !reinject - * case anyway. - */ - if (ktimer->reinject || !atomic_read(&ktimer->pending)) - atomic_inc(&ktimer->pending); - - if (waitqueue_active(q)) - wake_up_interruptible(q); - - if (ktimer->t_ops->is_periodic(ktimer)) { - hrtimer_add_expires_ns(&ktimer->timer, ktimer->period); - restart_timer = 1; - } - - return restart_timer; -} - -enum hrtimer_restart kvm_timer_fn(struct hrtimer *data) -{ - int restart_timer; - struct kvm_vcpu *vcpu; - struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer); - - vcpu = ktimer->vcpu; - if (!vcpu) - return HRTIMER_NORESTART; - - restart_timer = __kvm_timer_fn(vcpu, ktimer); - if (restart_timer) - return HRTIMER_RESTART; - else - return HRTIMER_NORESTART; -} - -- 1.6.5.2 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html