linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Marc Zyngier <maz@kernel.org>
To: kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org
Cc: Eric Auger <eric.auger@redhat.com>,
	James Morse <james.morse@arm.com>,
	Julien Thierry <julien.thierry.kdev@gmail.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Jason Cooper <jason@lakedaemon.net>,
	Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>,
	Andrew Murray <Andrew.Murray@arm.com>
Subject: [PATCH 28/35] irqchip/gic-v4.1: Move doorbell management to the GICv4 abstraction layer
Date: Mon, 23 Sep 2019 19:25:59 +0100	[thread overview]
Message-ID: <20190923182606.32100-29-maz@kernel.org> (raw)
In-Reply-To: <20190923182606.32100-1-maz@kernel.org>

In order to hide some of the differences between v4.0 and v4.1, move
the doorbell management out of the KVM code, and into the GICv4-specific
layer. This allows the calling code to ask for the doorbell when blocking,
and otherwise to leave the doorbell permanently disabled.

This matches the v4.1 code perfectly, and only results in a minor
refactoring of the v4.0 code.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/irqchip/irq-gic-v4.c       | 49 +++++++++++++++++++++++++++---
 include/kvm/arm_vgic.h             |  1 +
 include/linux/irqchip/arm-gic-v4.h |  3 +-
 virt/kvm/arm/vgic/vgic-v3.c        |  1 +
 virt/kvm/arm/vgic/vgic-v4.c        | 34 +++++++++------------
 5 files changed, 63 insertions(+), 25 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
index c01910d53f9e..60b51d6683aa 100644
--- a/drivers/irqchip/irq-gic-v4.c
+++ b/drivers/irqchip/irq-gic-v4.c
@@ -87,6 +87,11 @@ static struct irq_domain *gic_domain;
 static const struct irq_domain_ops *vpe_domain_ops;
 static const struct irq_domain_ops *sgi_domain_ops;
 
+static bool has_v4_1(void)
+{
+	return !!sgi_domain_ops;
+}
+
 int its_alloc_vcpu_irqs(struct its_vm *vm)
 {
 	int vpe_base_irq, i;
@@ -139,18 +144,54 @@ static int its_send_vpe_cmd(struct its_vpe *vpe, struct its_cmd_info *info)
 	return irq_set_vcpu_affinity(vpe->irq, info);
 }
 
-int its_schedule_vpe(struct its_vpe *vpe, bool on)
+int its_make_vpe_non_resident(struct its_vpe *vpe, bool db)
 {
-	struct its_cmd_info info;
+	struct irq_desc *desc = irq_to_desc(vpe->irq);
+	struct its_cmd_info info = { };
 	int ret;
 
 	WARN_ON(preemptible());
 
-	info.cmd_type = on ? SCHEDULE_VPE : DESCHEDULE_VPE;
+	info.cmd_type = DESCHEDULE_VPE;
+	if (has_v4_1()) {
+		/* GICv4.1 can directly deal with doorbells */
+		info.req_db = db;
+	} else {
+		/* Undo the nested disable_irq() calls... */
+		while (db && irqd_irq_disabled(&desc->irq_data))
+			enable_irq(vpe->irq);
+	}
+
+	ret = its_send_vpe_cmd(vpe, &info);
+	if (!ret)
+		vpe->resident = false;
+
+	return ret;
+}
+
+int its_make_vpe_resident(struct its_vpe *vpe)
+{
+	struct its_cmd_info info = { };
+	int ret;
+
+	WARN_ON(preemptible());
+
+	info.cmd_type = SCHEDULE_VPE;
+	if (has_v4_1()) {
+		/*
+		 * FIXME: This needs to come from the distributor, and
+		 * not be blindly set out of thin air...
+		 */
+		info.g0en = true;
+		info.g1en = true;
+	} else {
+		/* Disabled the doorbell, as we're about to enter the guest */
+		disable_irq_nosync(vpe->irq);
+	}
 
 	ret = its_send_vpe_cmd(vpe, &info);
 	if (!ret)
-		vpe->resident = on;
+		vpe->resident = true;
 
 	return ret;
 }
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 4dc58d7a0010..86cb95171eec 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -70,6 +70,7 @@ struct vgic_global {
 
 	/* Hardware has GICv4? */
 	bool			has_gicv4;
+	bool			has_gicv4_1;
 
 	/* GIC system register CPU interface */
 	struct static_key_false gicv3_cpuif;
diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h
index 6185926e4582..084890a5c2bf 100644
--- a/include/linux/irqchip/arm-gic-v4.h
+++ b/include/linux/irqchip/arm-gic-v4.h
@@ -118,7 +118,8 @@ struct its_cmd_info {
 
 int its_alloc_vcpu_irqs(struct its_vm *vm);
 void its_free_vcpu_irqs(struct its_vm *vm);
-int its_schedule_vpe(struct its_vpe *vpe, bool on);
+int its_make_vpe_resident(struct its_vpe *vpe);
+int its_make_vpe_non_resident(struct its_vpe *vpe, bool db);
 int its_invall_vpe(struct its_vpe *vpe);
 int its_map_vlpi(int irq, struct its_vlpi_map *map);
 int its_get_vlpi(int irq, struct its_vlpi_map *map);
diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
index 48307a9eb1d8..07a33b3e71c5 100644
--- a/virt/kvm/arm/vgic/vgic-v3.c
+++ b/virt/kvm/arm/vgic/vgic-v3.c
@@ -595,6 +595,7 @@ int vgic_v3_probe(const struct gic_kvm_info *info)
 	/* GICv4 support? */
 	if (info->has_v4) {
 		kvm_vgic_global_state.has_gicv4 = gicv4_enable;
+		kvm_vgic_global_state.has_gicv4_1 = info->has_v4_1;
 		kvm_info("GICv4 support %sabled\n",
 			 gicv4_enable ? "en" : "dis");
 	}
diff --git a/virt/kvm/arm/vgic/vgic-v4.c b/virt/kvm/arm/vgic/vgic-v4.c
index 7e1f3202968a..50f84f4ce903 100644
--- a/virt/kvm/arm/vgic/vgic-v4.c
+++ b/virt/kvm/arm/vgic/vgic-v4.c
@@ -67,10 +67,10 @@
  * it. And if we've migrated our vcpu from one CPU to another, we must
  * tell the ITS (so that the messages reach the right redistributor).
  * This is done in two steps: first issue a irq_set_affinity() on the
- * irq corresponding to the vcpu, then call its_schedule_vpe(). You
- * must be in a non-preemptible context. On exit, another call to
- * its_schedule_vpe() tells the redistributor that we're done with the
- * vcpu.
+ * irq corresponding to the vcpu, then call its_make_vpe_resident().
+ * You must be in a non-preemptible context. On exit, a call to
+ * its_make_vpe_non_resident() tells the redistributor that we're done
+ * with the vcpu.
  *
  * Finally, the doorbell handling: Each vcpu is allocated an interrupt
  * which will fire each time a VLPI is made pending whilst the vcpu is
@@ -86,7 +86,8 @@ static irqreturn_t vgic_v4_doorbell_handler(int irq, void *info)
 	struct kvm_vcpu *vcpu = info;
 
 	/* We got the message, no need to fire again */
-	if (!irqd_irq_disabled(&irq_to_desc(irq)->irq_data))
+	if (!kvm_vgic_global_state.has_gicv4_1 &&
+	    !irqd_irq_disabled(&irq_to_desc(irq)->irq_data))
 		disable_irq_nosync(irq);
 
 	vcpu->arch.vgic_cpu.vgic_v3.its_vpe.pending_last = true;
@@ -199,19 +200,11 @@ void vgic_v4_teardown(struct kvm *kvm)
 int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db)
 {
 	struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe;
-	struct irq_desc *desc = irq_to_desc(vpe->irq);
 
 	if (!vgic_supports_direct_msis(vcpu->kvm) || !vpe->resident)
 		return 0;
 
-	/*
-	 * If blocking, a doorbell is required. Undo the nested
-	 * disable_irq() calls...
-	 */
-	while (need_db && irqd_irq_disabled(&desc->irq_data))
-		enable_irq(vpe->irq);
-
-	return its_schedule_vpe(vpe, false);
+	return its_make_vpe_non_resident(vpe, need_db);
 }
 
 int vgic_v4_load(struct kvm_vcpu *vcpu)
@@ -232,18 +225,19 @@ int vgic_v4_load(struct kvm_vcpu *vcpu)
 	if (err)
 		return err;
 
-	/* Disabled the doorbell, as we're about to enter the guest */
-	disable_irq_nosync(vpe->irq);
-
-	err = its_schedule_vpe(vpe, true);
+	err = its_make_vpe_resident(vpe);
 	if (err)
 		return err;
 
 	/*
 	 * Now that the VPE is resident, let's get rid of a potential
-	 * doorbell interrupt that would still be pending.
+	 * doorbell interrupt that would still be pending. This is a
+	 * GICv4.0 only "feature"...
 	 */
-	return irq_set_irqchip_state(vpe->irq, IRQCHIP_STATE_PENDING, false);
+	if (!kvm_vgic_global_state.has_gicv4_1)
+		err = irq_set_irqchip_state(vpe->irq, IRQCHIP_STATE_PENDING, false);
+
+	return err;
 }
 
 static struct vgic_its *vgic_get_its(struct kvm *kvm,
-- 
2.20.1


  parent reply	other threads:[~2019-09-23 18:28 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-23 18:25 [PATCH 00/35] irqchip/gic-v4: GICv4.1 architecture support Marc Zyngier
2019-09-23 18:25 ` [PATCH 01/35] KVM: arm64: vgic-v4: Move the GICv4 residency flow to be driven by vcpu_load/put Marc Zyngier
2019-09-23 18:25 ` [PATCH 02/35] irqchip/gic-v3-its: Factor out wait_for_syncr primitive Marc Zyngier
2019-09-24  8:58   ` Andrew Murray
2019-09-23 18:25 ` [PATCH 03/35] irqchip/gic-v3-its: Allow LPI invalidation via the DirectLPI interface Marc Zyngier
2019-09-26 14:57   ` Zenghui Yu
2019-09-26 15:34     ` Marc Zyngier
2019-09-26 16:17     ` Marc Zyngier
2019-09-27  6:59       ` Zenghui Yu
2019-09-23 18:25 ` [PATCH 04/35] irqchip/gic-v3: Detect GICv4.1 supporting RVPEID Marc Zyngier
2019-09-24 10:24   ` Andrew Murray
2019-09-24 10:49     ` Marc Zyngier
2019-09-24 11:00       ` Andrew Murray
2019-09-24 11:18         ` Marc Zyngier
2019-09-23 18:25 ` [PATCH 05/35] irqchip/gic-v3: Add GICv4.1 VPEID size discovery Marc Zyngier
2019-09-24 10:49   ` Andrew Murray
2019-09-24 11:00     ` Marc Zyngier
2019-09-23 18:25 ` [PATCH 06/35] irqchip/gic-v3-its: Make is_v4 use a TYPER copy Marc Zyngier
2019-09-23 18:25 ` [PATCH 07/35] irqchip/gic-v3-its: Kill its->ite_size and use TYPER copy instead Marc Zyngier
2019-09-23 18:25 ` [PATCH 08/35] irqchip/gic-v3-its: Kill its->device_ids " Marc Zyngier
2019-09-23 18:25 ` [PATCH 09/35] irqchip/gic-v3-its: Add get_vlpi_map() helper Marc Zyngier
2019-09-23 18:25 ` [PATCH 10/35] irqchip/gic-v4.1: VPE table (aka GICR_VPROPBASER) allocation Marc Zyngier
2019-09-25 13:04   ` Zenghui Yu
2019-09-25 14:41     ` Marc Zyngier
2019-09-25 17:14       ` Marc Zyngier
2019-09-26 15:19       ` Zenghui Yu
2019-09-26 15:57         ` Marc Zyngier
2019-09-26 16:27           ` Marc Zyngier
2019-09-27  2:01             ` Zenghui Yu
2019-09-27  1:59           ` Zenghui Yu
2019-09-23 18:25 ` [PATCH 11/35] irqchip/gic-v4.1: Implement the v4.1 flavour of VMAPP Marc Zyngier
2019-09-23 18:25 ` [PATCH 12/35] irqchip/gic-v4.1: Don't use the VPE proxy if RVPEID is set Marc Zyngier
2019-09-23 18:25 ` [PATCH 13/35] irqchip/gic-v4.1: Implement the v4.1 flavour of VMOVP Marc Zyngier
2019-09-23 18:25 ` [PATCH 14/35] irqchip/gic-v4.1: Plumb skeletal VPE irqchip Marc Zyngier
2019-09-23 18:25 ` [PATCH 15/35] irqchip/gic-v4.1: Add mask/unmask doorbell callbacks Marc Zyngier
2019-09-23 18:25 ` [PATCH 16/35] irqchip/gic-v4.1: Add VPE residency callback Marc Zyngier
2019-09-23 18:25 ` [PATCH 17/35] irqchip/gic-v4.1: Add VPE eviction callback Marc Zyngier
2019-09-23 18:25 ` [PATCH 18/35] irqchip/gic-v4.1: Add VPE INVALL callback Marc Zyngier
2019-09-23 18:25 ` [PATCH 19/35] irqchip/gic-v4.1: Suppress per-VLPI doorbell Marc Zyngier
2019-09-23 18:25 ` [PATCH 20/35] irqchip/gic-v4.1: Allow direct invalidation of VLPIs Marc Zyngier
2019-09-28  2:02   ` Zenghui Yu
2019-09-30  9:20     ` Marc Zyngier
2019-09-30  9:40       ` Zenghui Yu
2019-09-23 18:25 ` [PATCH 21/35] irqchip/gic-v4.1: Advertise support v4.1 to KVM Marc Zyngier
2019-09-23 18:25 ` [PATCH 22/35] irqchip/gic-v4.1: Map the ITS SGIR register page Marc Zyngier
2019-09-23 18:25 ` [PATCH 23/35] irqchip/gic-v4.1: Plumb skeletal VSGI irqchip Marc Zyngier
2019-09-23 18:25 ` [PATCH 24/35] irqchip/gic-v4.1: Add initial SGI configuration Marc Zyngier
2019-09-28  2:20   ` Zenghui Yu
2019-09-28  3:07     ` Zenghui Yu
2019-09-23 18:25 ` [PATCH 25/35] irqchip/gic-v4.1: Plumb mask/unmask SGI callbacks Marc Zyngier
2019-09-23 18:25 ` [PATCH 26/35] irqchip/gic-v4.1: Plumb get/set_irqchip_state " Marc Zyngier
2019-09-23 18:25 ` [PATCH 27/35] irqchip/gic-v4.1: Plumb set_vcpu_affinity " Marc Zyngier
2019-09-23 18:25 ` Marc Zyngier [this message]
2019-09-23 18:26 ` [PATCH 29/35] irqchip/gic-v4.1: Add VSGI allocation/teardown Marc Zyngier
2019-09-23 18:26 ` [PATCH 30/35] irqchip/gic-v4.1: Add VSGI property setup Marc Zyngier
2019-09-23 18:26 ` [PATCH 31/35] irqchip/gic-v4.1: Eagerly vmap vPEs Marc Zyngier
2019-09-28  3:11   ` Zenghui Yu
2019-09-30  9:23     ` Marc Zyngier
2019-09-23 18:26 ` [PATCH 32/35] KVM: arm64: GICv4.1: Let doorbells be auto-enabled Marc Zyngier
2019-09-23 18:26 ` [PATCH 33/35] KVM: arm64: GICv4.1: Add direct injection capability to SGI registers Marc Zyngier
2019-09-23 18:26 ` [PATCH 34/35] KVM: arm64: GICv4.1: Configure SGIs as HW interrupts Marc Zyngier
2019-09-23 18:26 ` [PATCH 35/35] KVM: arm64: GICv4.1: Expose HW-based SGIs in debugfs 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=20190923182606.32100-29-maz@kernel.org \
    --to=maz@kernel.org \
    --cc=Andrew.Murray@arm.com \
    --cc=eric.auger@redhat.com \
    --cc=james.morse@arm.com \
    --cc=jason@lakedaemon.net \
    --cc=julien.thierry.kdev@gmail.com \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=suzuki.poulose@arm.com \
    --cc=tglx@linutronix.de \
    /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).