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
next prev 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).