Subject: Re: linux-next: manual merge of the kvm tree with Linus' tree

From: Christoffer Dall <[email-masked]>
Date: Thu, 1 Feb 2018 11:47:07 +0100

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