KVM: arm/arm64: Support arch timers with a userspace gic
authorAlexander Graf <agraf@suse.de>
Tue, 27 Sep 2016 19:08:06 +0000 (21:08 +0200)
committerChristoffer Dall <cdall@linaro.org>
Sun, 9 Apr 2017 14:49:38 +0000 (07:49 -0700)
commitd9e1397783765a275c3a7930250dcdb7e9480d7d
tree378a3533159595a77a117bda8f242e8288295893
parent3fe17e6826162021d5e9274949571b19fc94826b
KVM: arm/arm64: Support arch timers with a userspace gic

If you're running with a userspace gic or other interrupt controller
(that is no vgic in the kernel), then you have so far not been able to
use the architected timers, because the output of the architected
timers, which are driven inside the kernel, was a kernel-only construct
between the arch timer code and the vgic.

This patch implements the new KVM_CAP_ARM_USER_IRQ feature, where we use a
side channel on the kvm_run structure, run->s.regs.device_irq_level, to
always notify userspace of the timer output levels when using a userspace
irqchip.

This works by ensuring that before we enter the guest, if the timer
output level has changed compared to what we last told userspace, we
don't enter the guest, but instead return to userspace to notify it of
the new level.  If we are exiting, because of an MMIO for example, and
the level changed at the same time, the value is also updated and
userspace can sample the line as it needs.  This is nicely achieved
simply always updating the timer_irq_level field after the main run
loop.

Note that the kvm_timer_update_irq trace event is changed to show the
host IRQ number for the timer instead of the guest IRQ number, because
the kernel no longer know which IRQ userspace wires up the timer signal
to.

Also note that this patch implements all required functionality but does
not yet advertise the capability.

Reviewed-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
arch/arm/kvm/arm.c
include/kvm/arm_arch_timer.h
virt/kvm/arm/arch_timer.c