linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: Marc Zyngier <maz@kernel.org>
To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu,
	linux-arm-kernel@lists.infradead.org
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Christoffer Dall <Christoffer.Dall@arm.com>,
	James Morse <james.morse@arm.com>,
	kernel-team@android.com,
	Julien Thierry <julien.thierry.kdev@gmail.com>
Subject: [PATCH 20/23] KVM: arm64: Move irqfd routing to irqchip_flow
Date: Thu,  3 Sep 2020 16:26:07 +0100	[thread overview]
Message-ID: <20200903152610.1078827-21-maz@kernel.org> (raw)
In-Reply-To: <20200903152610.1078827-1-maz@kernel.org>

irqfd handling is still hidden away in the vgic code. Let's
extract it and move the generic part in the non-GIC code,
with the now required abstraction in the irqchip_flow struct.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/include/asm/kvm_irq.h | 11 +++++
 arch/arm64/kvm/arm.c             | 68 ++++++++++++++++++++++++++++++
 arch/arm64/kvm/vgic/vgic-init.c  |  3 ++
 arch/arm64/kvm/vgic/vgic-irqfd.c | 72 ++++++--------------------------
 arch/arm64/kvm/vgic/vgic.h       | 10 +++++
 5 files changed, 104 insertions(+), 60 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_irq.h b/arch/arm64/include/asm/kvm_irq.h
index 649b7d4c7e9f..05fbe5241642 100644
--- a/arch/arm64/include/asm/kvm_irq.h
+++ b/arch/arm64/include/asm/kvm_irq.h
@@ -19,6 +19,8 @@ enum kvm_irqchip_type {
 
 #define irqchip_finalized(k)	((k)->arch.irqchip_finalized)
 
+struct kvm_kernel_irq_routing_entry;
+
 struct kvm_irqchip_flow {
 	void (*irqchip_destroy)(struct kvm *);
 	int  (*irqchip_vcpu_init)(struct kvm_vcpu *);
@@ -41,6 +43,15 @@ struct kvm_irqchip_flow {
 				     u32, bool (*)(int));
 	int  (*irqchip_unmap_phys_irq)(struct kvm_vcpu *, unsigned int);
 	int  (*irqchip_set_owner)(struct kvm_vcpu *, unsigned int, void *);
+	int  (*irqchip_irqfd_set_irq)(struct kvm_kernel_irq_routing_entry *e,
+				      struct kvm *kvm, int irq_source_id,
+				      int level, bool line_status);
+	int  (*irqchip_set_msi)(struct kvm_kernel_irq_routing_entry *e,
+				struct kvm *kvm, int irq_source_id,
+				int level, bool line_status);
+	int  (*irqchip_set_irq_inatomic)(struct kvm_kernel_irq_routing_entry *e,
+					 struct kvm *kvm, int irq_source_id,
+					 int level, bool line_status);
 };
 
 /*
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 678533871cfa..d625904633c0 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1592,6 +1592,74 @@ void kvm_arch_irq_bypass_start(struct irq_bypass_consumer *cons)
 	kvm_arm_resume_guest(irqfd->kvm);
 }
 
+/**
+ * kvm_set_routing_entry: populate a kvm routing entry
+ * from a user routing entry
+ *
+ * @kvm: the VM this entry is applied to
+ * @e: kvm kernel routing entry handle
+ * @ue: user api routing entry handle
+ * return 0 on success, -EINVAL on errors.
+ */
+int kvm_set_routing_entry(struct kvm *kvm,
+			  struct kvm_kernel_irq_routing_entry *e,
+			  const struct kvm_irq_routing_entry *ue)
+{
+	int r = -EINVAL;
+
+	switch (ue->type) {
+	case KVM_IRQ_ROUTING_IRQCHIP:
+		e->set = kvm->arch.irqchip_flow.irqchip_irqfd_set_irq;
+		e->irqchip.irqchip = ue->u.irqchip.irqchip;
+		e->irqchip.pin = ue->u.irqchip.pin;
+		if ((e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS) ||
+		    (e->irqchip.irqchip >= KVM_NR_IRQCHIPS))
+			goto out;
+		break;
+	case KVM_IRQ_ROUTING_MSI:
+		e->set = kvm->arch.irqchip_flow.irqchip_set_msi;
+		e->msi.address_lo = ue->u.msi.address_lo;
+		e->msi.address_hi = ue->u.msi.address_hi;
+		e->msi.data = ue->u.msi.data;
+		e->msi.flags = ue->flags;
+		e->msi.devid = ue->u.msi.devid;
+		break;
+	default:
+		goto out;
+	}
+
+	if (!e->set)
+		goto out;
+
+	r = 0;
+out:
+	return r;
+}
+
+int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
+		struct kvm *kvm, int irq_source_id,
+		int level, bool line_status)
+{
+	if (!kvm->arch.irqchip_flow.irqchip_set_msi)
+		return -ENODEV;
+	return kvm->arch.irqchip_flow.irqchip_set_msi(e, kvm, irq_source_id,
+						      level, line_status);
+}
+
+int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
+			      struct kvm *kvm, int irq_source_id, int level,
+			      bool line_status)
+{
+	if (!level || !irqchip_finalized(kvm) ||
+	    !kvm->arch.irqchip_flow.irqchip_set_irq_inatomic)
+		return -EWOULDBLOCK;
+
+	return kvm->arch.irqchip_flow.irqchip_set_irq_inatomic(e, kvm,
+							       irq_source_id,
+							       level,
+							       line_status);
+}
+
 /**
  * Initialize Hyp-mode and memory mappings on all CPUs.
  */
diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
index a3e0389617a3..440b8c09c030 100644
--- a/arch/arm64/kvm/vgic/vgic-init.c
+++ b/arch/arm64/kvm/vgic/vgic-init.c
@@ -34,6 +34,9 @@ static struct kvm_irqchip_flow vgic_irqchip_flow = {
 	.irqchip_map_phys_irq		= kvm_vgic_map_phys_irq,
 	.irqchip_unmap_phys_irq		= kvm_vgic_unmap_phys_irq,
 	.irqchip_set_owner		= kvm_vgic_set_owner,
+	.irqchip_irqfd_set_irq		= vgic_irqfd_set_irq,
+	.irqchip_set_msi		= vgic_set_msi,
+	.irqchip_set_irq_inatomic	= vgic_set_irq_inatomic,
 };
 
 /*
diff --git a/arch/arm64/kvm/vgic/vgic-irqfd.c b/arch/arm64/kvm/vgic/vgic-irqfd.c
index dbece60c8dc0..5bbdfe982a00 100644
--- a/arch/arm64/kvm/vgic/vgic-irqfd.c
+++ b/arch/arm64/kvm/vgic/vgic-irqfd.c
@@ -15,9 +15,9 @@
  *
  * This is the entry point for irqfd IRQ injection
  */
-static int vgic_irqfd_set_irq(struct kvm_kernel_irq_routing_entry *e,
-			struct kvm *kvm, int irq_source_id,
-			int level, bool line_status)
+int vgic_irqfd_set_irq(struct kvm_kernel_irq_routing_entry *e,
+		       struct kvm *kvm, int irq_source_id,
+		       int level, bool line_status)
 {
 	unsigned int spi_id = e->irqchip.pin + VGIC_NR_PRIVATE_IRQS;
 
@@ -26,46 +26,6 @@ static int vgic_irqfd_set_irq(struct kvm_kernel_irq_routing_entry *e,
 	return kvm_vgic_inject_irq(kvm, 0, spi_id, level, NULL);
 }
 
-/**
- * kvm_set_routing_entry: populate a kvm routing entry
- * from a user routing entry
- *
- * @kvm: the VM this entry is applied to
- * @e: kvm kernel routing entry handle
- * @ue: user api routing entry handle
- * return 0 on success, -EINVAL on errors.
- */
-int kvm_set_routing_entry(struct kvm *kvm,
-			  struct kvm_kernel_irq_routing_entry *e,
-			  const struct kvm_irq_routing_entry *ue)
-{
-	int r = -EINVAL;
-
-	switch (ue->type) {
-	case KVM_IRQ_ROUTING_IRQCHIP:
-		e->set = vgic_irqfd_set_irq;
-		e->irqchip.irqchip = ue->u.irqchip.irqchip;
-		e->irqchip.pin = ue->u.irqchip.pin;
-		if ((e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS) ||
-		    (e->irqchip.irqchip >= KVM_NR_IRQCHIPS))
-			goto out;
-		break;
-	case KVM_IRQ_ROUTING_MSI:
-		e->set = kvm_set_msi;
-		e->msi.address_lo = ue->u.msi.address_lo;
-		e->msi.address_hi = ue->u.msi.address_hi;
-		e->msi.data = ue->u.msi.data;
-		e->msi.flags = ue->flags;
-		e->msi.devid = ue->u.msi.devid;
-		break;
-	default:
-		goto out;
-	}
-	r = 0;
-out:
-	return r;
-}
-
 static void kvm_populate_msi(struct kvm_kernel_irq_routing_entry *e,
 			     struct kvm_msi *msi)
 {
@@ -75,16 +35,17 @@ static void kvm_populate_msi(struct kvm_kernel_irq_routing_entry *e,
 	msi->flags = e->msi.flags;
 	msi->devid = e->msi.devid;
 }
+
 /**
- * kvm_set_msi: inject the MSI corresponding to the
+ * vgic_set_msi: inject the MSI corresponding to the
  * MSI routing entry
  *
  * This is the entry point for irqfd MSI injection
  * and userspace MSI injection.
  */
-int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
-		struct kvm *kvm, int irq_source_id,
-		int level, bool line_status)
+int vgic_set_msi(struct kvm_kernel_irq_routing_entry *e,
+		 struct kvm *kvm, int irq_source_id,
+		 int level, bool line_status)
 {
 	struct kvm_msi msi;
 
@@ -99,15 +60,12 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
 }
 
 /**
- * kvm_arch_set_irq_inatomic: fast-path for irqfd injection
+ * vgic_set_irq_inatomic: fast-path for irqfd injection
  */
-int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
-			      struct kvm *kvm, int irq_source_id, int level,
-			      bool line_status)
+int vgic_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
+			  struct kvm *kvm, int irq_source_id, int level,
+			  bool line_status)
 {
-	if (!level)
-		return -EWOULDBLOCK;
-
 	switch (e->type) {
 	case KVM_IRQ_ROUTING_MSI: {
 		struct kvm_msi msi;
@@ -120,12 +78,6 @@ int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
 	}
 
 	case KVM_IRQ_ROUTING_IRQCHIP:
-		/*
-		 * Injecting SPIs is always possible in atomic context
-		 * as long as the damn vgic is initialized.
-		 */
-		if (unlikely(!irqchip_finalized(kvm)))
-			break;
 		return vgic_irqfd_set_irq(e, kvm, irq_source_id, 1, line_status);
 	}
 
diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h
index c9e14a6cddf6..db3b111ed611 100644
--- a/arch/arm64/kvm/vgic/vgic.h
+++ b/arch/arm64/kvm/vgic/vgic.h
@@ -324,6 +324,16 @@ void vgic_lpi_translation_cache_init(struct kvm *kvm);
 void vgic_lpi_translation_cache_destroy(struct kvm *kvm);
 void vgic_its_invalidate_cache(struct kvm *kvm);
 
+int vgic_irqfd_set_irq(struct kvm_kernel_irq_routing_entry *e,
+		       struct kvm *kvm, int irq_source_id,
+		       int level, bool line_status);
+int vgic_set_msi(struct kvm_kernel_irq_routing_entry *e,
+		 struct kvm *kvm, int irq_source_id,
+		 int level, bool line_status);
+int vgic_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
+			  struct kvm *kvm, int irq_source_id, int level,
+			  bool line_status);
+
 bool vgic_supports_direct_msis(struct kvm *kvm);
 int vgic_v4_init(struct kvm *kvm);
 void vgic_v4_teardown(struct kvm *kvm);
-- 
2.27.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2020-09-03 15:57 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-03 15:25 [PATCH 00/23] KVM: arm64: rVIC/rVID PV interrupt controller Marc Zyngier
2020-09-03 15:25 ` [PATCH 01/23] irqchip: Add Reduced Virtual Interrupt Controller driver Marc Zyngier
2020-09-03 15:25 ` [PATCH 02/23] irqchip/rvic: Add support for untrusted interrupt allocation Marc Zyngier
2020-09-04 13:40   ` Jonathan Cameron
2020-09-03 15:25 ` [PATCH 03/23] irqchip: Add Reduced Virtual Interrupt Distributor support Marc Zyngier
2020-09-04 13:56   ` Jonathan Cameron
2020-09-03 15:25 ` [PATCH 04/23] irqchip/rvid: Add PCI MSI support Marc Zyngier
2020-09-04 14:15   ` Jonathan Cameron
2020-09-05 13:08     ` Marc Zyngier
2020-09-03 15:25 ` [PATCH 05/23] KVM: arm64: Move GIC model out of the distributor Marc Zyngier
2020-09-04 14:37   ` Jonathan Cameron
2020-09-03 15:25 ` [PATCH 06/23] KVM: arm64: vgic-v3: Move early init to kvm_vgic_create() Marc Zyngier
2020-09-03 15:25 ` [PATCH 07/23] KVM: arm64: Add irqchip callback structure to kvm_arch Marc Zyngier
2020-09-03 15:25 ` [PATCH 08/23] KVM: arm64: Move kvm_vgic_destroy to kvm_irqchip_flow Marc Zyngier
2020-09-03 15:25 ` [PATCH 09/23] KVM: arm64: Move kvm_vgic_vcpu_init() to irqchip_flow Marc Zyngier
2020-09-03 15:25 ` [PATCH 10/23] KVM: arm64: Move kvm_vgic_vcpu_[un]blocking() " Marc Zyngier
2020-09-03 15:25 ` [PATCH 11/23] KVM: arm64: Move kvm_vgic_vcpu_load/put() " Marc Zyngier
2020-09-03 15:25 ` [PATCH 12/23] KVM: arm64: Move kvm_vgic_vcpu_pending_irq() " Marc Zyngier
2020-09-04 14:57   ` Jonathan Cameron
2020-09-03 15:26 ` [PATCH 13/23] KVM: arm64: Move vgic resource mapping on first run " Marc Zyngier
2020-09-03 15:26 ` [PATCH 14/23] KVM: arm64: Move kvm_vgic_vcpu_{sync, flush}_hwstate() " Marc Zyngier
2020-09-03 15:26 ` [PATCH 15/23] KVM: arm64: nVHE: Only save/restore GICv3 state if modeling a GIC Marc Zyngier
2020-09-03 15:26 ` [PATCH 16/23] KVM: arm64: Move interrupt injection to irqchip_flow Marc Zyngier
2020-09-03 15:26 ` [PATCH 17/23] KVM: arm64: Move mapping of HW interrupts into irqchip_flow Marc Zyngier
2020-09-03 15:26 ` [PATCH 18/23] KVM: arm64: Move set_owner " Marc Zyngier
2020-09-03 15:26 ` [PATCH 19/23] KVM: arm64: Turn vgic_initialized into irqchip_finalized Marc Zyngier
2020-09-03 15:26 ` Marc Zyngier [this message]
2020-09-03 15:26 ` [PATCH 21/23] KVM: arm64: Tighten msis_require_devid reporting Marc Zyngier
2020-09-03 15:26 ` [PATCH 22/23] KVM: arm64: Add a rVIC/rVID in-kernel implementation Marc Zyngier
2020-09-04 16:00   ` Jonathan Cameron
2020-09-05 13:16     ` Marc Zyngier
2020-09-29 15:13   ` Lorenzo Pieralisi
2020-09-29 15:27     ` Marc Zyngier
2020-09-29 16:09       ` Lorenzo Pieralisi
2020-09-03 15:26 ` [PATCH 23/23] KVM: arm64: Add debugfs files for the rVIC/rVID implementation Marc Zyngier

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=20200903152610.1078827-21-maz@kernel.org \
    --to=maz@kernel.org \
    --cc=Christoffer.Dall@arm.com \
    --cc=james.morse@arm.com \
    --cc=julien.thierry.kdev@gmail.com \
    --cc=kernel-team@android.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=suzuki.poulose@arm.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).