[PATCH Xenial SRU] KVM: PPC: Book3S HV: Re-enable XICS fast path for irqfd-generated interrupts

Christopher Arges chris.j.arges at canonical.com
Thu Jun 16 06:37:40 UTC 2016


ACK clean cherry-pick, nothing newer that seems to need application.
--chris

On Thu, Jun 16, 2016 at 02:52:11AM +0300, Tim Gardner wrote:
> From: Paul Mackerras <paulus at ozlabs.org>
> 
> BugLink: http://bugs.launchpad.net/bugs/1592809
> 
> Commit c9a5eccac1ab ("kvm/eventfd: add arch-specific set_irq",
> 2015-10-16) added the possibility for architecture-specific code
> to handle the generation of virtual interrupts in atomic context
> where possible, without having to schedule a work function.
> 
> Since we can easily generate virtual interrupts on XICS without
> having to do anything worse than take a spinlock, we define a
> kvm_arch_set_irq_inatomic() for XICS.  We also remove kvm_set_msi()
> since it is not used any more.
> 
> The one slightly tricky thing is that with the new interface, we
> don't get told whether the interrupt is an MSI (or other edge
> sensitive interrupt) vs. level-sensitive.  The difference as far
> as interrupt generation is concerned is that for LSIs we have to
> set the asserted flag so it will continue to fire until it is
> explicitly cleared.
> 
> In fact the XICS code gets told which interrupts are LSIs by userspace
> when it configures the interrupt via the KVM_DEV_XICS_GRP_SOURCES
> attribute group on the XICS device.  To store this information, we add
> a new "lsi" field to struct ics_irq_state.  With that we can also do a
> better job of returning accurate values when reading the attribute
> group.
> 
> Signed-off-by: Paul Mackerras <paulus at samba.org>
> (cherry picked from commit b1a4286b8f3393857a205ec89607683161b75f90)
> Signed-off-by: Tim Gardner <tim.gardner at canonical.com>
> ---
>  arch/powerpc/kvm/book3s_xics.c | 25 +++++++++++++++----------
>  arch/powerpc/kvm/book3s_xics.h |  1 +
>  2 files changed, 16 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c
> index 905e94a..df75fc8 100644
> --- a/arch/powerpc/kvm/book3s_xics.c
> +++ b/arch/powerpc/kvm/book3s_xics.c
> @@ -92,7 +92,7 @@ static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level)
>  	 * we are the only setter, thus concurrent access is undefined
>  	 * to begin with.
>  	 */
> -	if (level == 1 || level == KVM_INTERRUPT_SET_LEVEL)
> +	if ((level == 1 && state->lsi) || level == KVM_INTERRUPT_SET_LEVEL)
>  		state->asserted = 1;
>  	else if (level == 0 || level == KVM_INTERRUPT_UNSET) {
>  		state->asserted = 0;
> @@ -1174,9 +1174,11 @@ static int xics_get_source(struct kvmppc_xics *xics, long irq, u64 addr)
>  			prio = irqp->saved_priority;
>  		}
>  		val |= prio << KVM_XICS_PRIORITY_SHIFT;
> -		if (irqp->asserted)
> -			val |= KVM_XICS_LEVEL_SENSITIVE | KVM_XICS_PENDING;
> -		else if (irqp->masked_pending || irqp->resend)
> +		if (irqp->lsi) {
> +			val |= KVM_XICS_LEVEL_SENSITIVE;
> +			if (irqp->asserted)
> +				val |= KVM_XICS_PENDING;
> +		} else if (irqp->masked_pending || irqp->resend)
>  			val |= KVM_XICS_PENDING;
>  		ret = 0;
>  	}
> @@ -1228,9 +1230,13 @@ static int xics_set_source(struct kvmppc_xics *xics, long irq, u64 addr)
>  	irqp->priority = prio;
>  	irqp->resend = 0;
>  	irqp->masked_pending = 0;
> +	irqp->lsi = 0;
>  	irqp->asserted = 0;
> -	if ((val & KVM_XICS_PENDING) && (val & KVM_XICS_LEVEL_SENSITIVE))
> -		irqp->asserted = 1;
> +	if (val & KVM_XICS_LEVEL_SENSITIVE) {
> +		irqp->lsi = 1;
> +		if (val & KVM_XICS_PENDING)
> +			irqp->asserted = 1;
> +	}
>  	irqp->exists = 1;
>  	arch_spin_unlock(&ics->lock);
>  	local_irq_restore(flags);
> @@ -1249,11 +1255,10 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
>  	return ics_deliver_irq(xics, irq, level);
>  }
>  
> -int kvm_set_msi(struct kvm_kernel_irq_routing_entry *irq_entry, struct kvm *kvm,
> -		int irq_source_id, int level, bool line_status)
> +int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *irq_entry,
> +			      struct kvm *kvm, int irq_source_id,
> +			      int level, bool line_status)
>  {
> -	if (!level)
> -		return -1;
>  	return kvm_set_irq(kvm, irq_source_id, irq_entry->gsi,
>  			   level, line_status);
>  }
> diff --git a/arch/powerpc/kvm/book3s_xics.h b/arch/powerpc/kvm/book3s_xics.h
> index 56ea44f..a46b954 100644
> --- a/arch/powerpc/kvm/book3s_xics.h
> +++ b/arch/powerpc/kvm/book3s_xics.h
> @@ -39,6 +39,7 @@ struct ics_irq_state {
>  	u8  saved_priority;
>  	u8  resend;
>  	u8  masked_pending;
> +	u8  lsi;		/* level-sensitive interrupt */
>  	u8  asserted; /* Only for LSI */
>  	u8  exists;
>  };
> -- 
> 2.7.4
> 
> 
> -- 
> kernel-team mailing list
> kernel-team at lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team




More information about the kernel-team mailing list