[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