Hi, On Thu, Feb 01, 2018 at 12:55:12PM +1100, Stephen Rothwell wrote: > Hi all, > > Today's linux-next merge of the kvm tree got a conflict in: > > virt/kvm/arm/arch_timer.c > > between commit: > > 36e5cfd410ad ("KVM: arm/arm64: Properly handle arch-timer IRQs after vtimer_save_state") > > from Linus' tree and commits: > > 70450a9fbe06 ("KVM: arm/arm64: Don't cache the timer IRQ level") > 13e59ece5b30 ("KVM: arm/arm64: Fix incorrect timer_is_pending logic") > > from the kvm tree. > > I fixed it up (I think - see below) and can carry the fix as > necessary. This is now fixed as far as linux-next is concerned, but any > non trivial conflicts should be mentioned to your upstream maintainer > when your tree is submitted for merging. You may also want to consider > cooperating with the maintainer of the conflicting tree to minimise any > particularly complex conflicts. > While the suggested fix is functional it does result in some code duplication, and the better resolution is the following: diff --cc virt/kvm/arm/arch_timer.c index cc29a8148328,fb6bd9b9845e..000000000000 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c @@@ -92,27 -92,18 +92,22 @@@ static irqreturn_t kvm_arch_timer_handl { struct kvm_vcpu *vcpu = *(struct kvm_vcpu **)dev_id; struct arch_timer_context *vtimer; - u32 cnt_ctl; - if (!vcpu) { - pr_warn_once("Spurious arch timer IRQ on non-VCPU thread\n"); - return IRQ_NONE; - } + /* + * We may see a timer interrupt after vcpu_put() has been called which + * sets the CPU's vcpu pointer to NULL, because even though the timer + * has been disabled in vtimer_save_state(), the hardware interrupt + * signal may not have been retired from the interrupt controller yet. + */ + if (!vcpu) + return IRQ_HANDLED; vtimer = vcpu_vtimer(vcpu); - if (!vtimer->irq.level) { - cnt_ctl = read_sysreg_el0(cntv_ctl); - cnt_ctl &= ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_STAT | - ARCH_TIMER_CTRL_IT_MASK; - if (cnt_ctl == (ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_STAT)) - kvm_timer_update_irq(vcpu, true, vtimer); - } + if (kvm_timer_should_fire(vtimer)) + kvm_timer_update_irq(vcpu, true, vtimer); - if (unlikely(!irqchip_in_kernel(vcpu->kvm))) + if (static_branch_unlikely(&userspace_irqchip_in_use) && + unlikely(!irqchip_in_kernel(vcpu->kvm))) kvm_vtimer_update_mask_user(vcpu); return IRQ_HANDLED; Thanks, -Christoffer