All of lore.kernel.org
 help / color / mirror / Atom feed
From: Suresh Warrier <warrier@linux.vnet.ibm.com>
To: kvm@vger.kernel.org, linuxppc-dev@ozlabs.org
Cc: warrier@linux.vnet.ibm.com, paulus@samba.org, agraf@suse.de,
	mpe@ellerman.id.au
Subject: [PATCH 09/14] KVM: PPC: Book3S HV: Enable KVM real mode handling of passthrough IRQs
Date: Fri, 26 Feb 2016 12:40:27 -0600	[thread overview]
Message-ID: <1456512032-31286-10-git-send-email-warrier@linux.vnet.ibm.com> (raw)
In-Reply-To: <1456512032-31286-1-git-send-email-warrier@linux.vnet.ibm.com>

The KVM real mode passthrough handling code only searches for
"cached" IRQ maps in the passthrough IRQ map when checking for
passthrough IRQs that can be redirected to the guest.
This patch enables KVM real mode handling of passthrough IRQs
by turning on caching of selected passthrough IRQs. Currently,
we follow a simple method and cache any passthrough IRQ when its
virtual IRQ is first injected into the guest.

Since we have a limit of 16 cache entries per guest, this will
limit passthrough IRQs that are handled in KVM real mode to 16.
This should work well for the general case for VMs with small
number of passthrough adapters or SRIOV VFs. In the future, we
can increase the number of cached entries, but we would then need
to come up with faster search/filtering mechanisms for an IRQ in
the map of cached passthrough IRQs.

Signed-off-by: Suresh Warrier <warrier@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/kvm_host.h |  1 +
 arch/powerpc/include/asm/kvm_ppc.h  |  2 ++
 arch/powerpc/kvm/book3s.c           | 10 +++++++++
 arch/powerpc/kvm/book3s_hv.c        |  4 ++++
 arch/powerpc/kvm/book3s_xics.c      | 41 +++++++++++++++++++++++++++++++++++++
 arch/powerpc/kvm/book3s_xics.h      |  2 ++
 6 files changed, 60 insertions(+)

diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index fc10248..558d195 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -63,6 +63,7 @@ extern int kvm_unmap_hva_range(struct kvm *kvm,
 extern int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end);
 extern int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);
 extern void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
+extern int kvmppc_cache_passthru_irq(struct kvm *kvm, int guest_gsi);
 
 static inline void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm,
 							 unsigned long address)
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index b19bb30..93531cc 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -484,6 +484,8 @@ extern int kvmppc_xics_set_icp(struct kvm_vcpu *vcpu, u64 icpval);
 extern int kvmppc_xics_connect_vcpu(struct kvm_device *dev,
 			struct kvm_vcpu *vcpu, u32 cpu);
 extern void kvmppc_xics_ipi_action(void);
+extern void kvmppc_xics_set_mapped(struct kvm *kvm, unsigned long irq);
+extern void kvmppc_xics_clr_mapped(struct kvm *kvm, unsigned long irq);
 extern int h_ipi_redirect;
 #else
 static inline struct kvmppc_passthru_irqmap *kvmppc_get_passthru_irqmap(
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 2492b7e..1b4f5bd 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -953,6 +953,16 @@ void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
 		kvm->arch.kvm_ops->irq_bypass_del_producer(cons, prod);
 }
 
+int kvmppc_cache_passthru_irq(struct kvm *kvm, int irq)
+{
+	int r = 0;
+
+	if (kvm->arch.kvm_ops->cache_passthru_irq)
+		r = kvm->arch.kvm_ops->cache_passthru_irq(kvm, irq);
+
+	return r;
+}
+
 static int kvmppc_book3s_init(void)
 {
 	int r;
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index cc5aea96..487657f 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -3468,6 +3468,8 @@ static int kvmppc_set_passthru_irq(struct kvm *kvm, int host_irq, int guest_gsi)
 
 	pimap->n_mapped++;
 
+	kvmppc_xics_set_mapped(kvm, guest_gsi);
+
 	if (!kvm->arch.pimap)
 		kvm->arch.pimap = pimap;
 
@@ -3522,6 +3524,8 @@ static int kvmppc_clr_passthru_irq(struct kvm *kvm, int host_irq, int guest_gsi)
 	if (i != pimap->n_mapped)
 		pimap->mapped[i] = pimap->mapped[pimap->n_mapped];
 
+	kvmppc_xics_clr_mapped(kvm, guest_gsi);
+
 	/*
 	 * We don't free this structure even when the count goes to
 	 * zero. The structure is freed when we destroy the VM.
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c
index be23f88..b90570c 100644
--- a/arch/powerpc/kvm/book3s_xics.c
+++ b/arch/powerpc/kvm/book3s_xics.c
@@ -88,6 +88,18 @@ static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level)
 		return -EINVAL;
 
 	/*
+	 * If this is a mapped passthrough IRQ that is not cached,
+	 * add this to the IRQ cached map so that real mode KVM
+	 * will redirect this directly to the guest where possible.
+	 * Currently, we will cache a passthrough IRQ the first time
+	 * we  inject it into the guest.
+	 */
+	if (state->pmapped && !state->pcached) {
+		if (kvmppc_cache_passthru_irq(xics->kvm, irq) == 0)
+			state->pcached = 1;
+	}
+
+	/*
 	 * We set state->asserted locklessly. This should be fine as
 	 * we are the only setter, thus concurrent access is undefined
 	 * to begin with.
@@ -1410,3 +1422,32 @@ int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin)
 {
 	return pin;
 }
+
+void kvmppc_xics_set_mapped(struct kvm *kvm, unsigned long irq)
+{
+	struct kvmppc_xics *xics = kvm->arch.xics;
+	struct kvmppc_ics *ics;
+	u16 idx;
+
+	ics = kvmppc_xics_find_ics(xics, irq, &idx);
+	if (!ics)
+		return;
+
+	ics->irq_state[idx].pmapped = 1;
+}
+EXPORT_SYMBOL_GPL(kvmppc_xics_set_mapped);
+
+void kvmppc_xics_clr_mapped(struct kvm *kvm, unsigned long irq)
+{
+	struct kvmppc_xics *xics = kvm->arch.xics;
+	struct kvmppc_ics *ics;
+	u16 idx;
+
+	ics = kvmppc_xics_find_ics(xics, irq, &idx);
+	if (!ics)
+		return;
+
+	ics->irq_state[idx].pmapped = 0;
+	ics->irq_state[idx].pcached = 0;
+}
+EXPORT_SYMBOL_GPL(kvmppc_xics_clr_mapped);
diff --git a/arch/powerpc/kvm/book3s_xics.h b/arch/powerpc/kvm/book3s_xics.h
index 56ea44f..de560f1 100644
--- a/arch/powerpc/kvm/book3s_xics.h
+++ b/arch/powerpc/kvm/book3s_xics.h
@@ -41,6 +41,8 @@ struct ics_irq_state {
 	u8  masked_pending;
 	u8  asserted; /* Only for LSI */
 	u8  exists;
+	u8  pmapped;
+	u8  pcached;
 };
 
 /* Atomic ICP state, updated with a single compare & swap */
-- 
1.8.3.4


  parent reply	other threads:[~2016-02-26 18:41 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-26 18:40 [PATCH 00/14] PCI Passthrough Interrupt Optimizations Suresh Warrier
2016-02-26 18:40 ` [PATCH 01/14] powerpc: Add simple cache inhibited MMIO accessors Suresh Warrier
2016-02-26 18:40 ` [PATCH 02/14] KVM: PPC: Book3S HV: Convert kvmppc_read_intr to a C function Suresh Warrier
2016-02-26 18:40 ` [PATCH 03/14] KVM: PPC: select IRQ_BYPASS_MANAGER Suresh Warrier
2016-02-26 18:40 ` [PATCH 04/14] KVM: PPC: Book3S HV: Introduce kvmppc_passthru_irqmap Suresh Warrier
2016-02-26 18:40 ` [PATCH 05/14] KVM: PPC: Book3S HV: Enable IRQ bypass Suresh Warrier
2016-02-26 18:40 ` [PATCH 06/14] KVM: PPC: Book3S HV: Caching for passthrough IRQ map Suresh Warrier
2016-02-26 18:40 ` [PATCH 07/14] KVM: PPC: Book3S HV: Handle passthrough interrupts in guest Suresh Warrier
2016-02-26 18:40 ` [PATCH 08/14] KVM: PPC: Book3S HV: Complete passthrough interrupt in host Suresh Warrier
2016-02-26 18:40 ` Suresh Warrier [this message]
2016-02-26 18:40 ` [PATCH 10/14] KVM: PPC: Book3S HV: Dump irqmap in debugfs Suresh Warrier
2016-02-26 18:40 ` [PATCH 11/14] KVM: PPC: Book3S HV: Tunable to disable KVM IRQ bypass Suresh Warrier
2016-02-26 18:40 ` [PATCH 12/14] KVM: PPC: Book3S HV: Update irq stats for IRQs handled in real mode Suresh Warrier
2016-02-26 18:40 ` [PATCH 13/14] KVM: PPC: Book3S HV: Change affinity for passthrough IRQ Suresh Warrier
2016-02-26 18:40 ` [PATCH 14/14] KVM: PPC: Book3S HV: Counters for passthrough IRQ stats Suresh Warrier
2016-02-26 18:49 ` [PATCH 00/14] KVM: PPC: Book3S HV: PCI Passthrough Interrupt Optimizations Suresh E. Warrier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1456512032-31286-10-git-send-email-warrier@linux.vnet.ibm.com \
    --to=warrier@linux.vnet.ibm.com \
    --cc=agraf@suse.de \
    --cc=kvm@vger.kernel.org \
    --cc=linuxppc-dev@ozlabs.org \
    --cc=mpe@ellerman.id.au \
    --cc=paulus@samba.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.