From: Marc Zyngier <maz@kernel.org>
To: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
kvm@vger.kernel.org
Cc: Joey Gouly <joey.gouly@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Oliver Upton <oliver.upton@linux.dev>,
Zenghui Yu <yuzenghui@huawei.com>,
Andre Przywara <andre.przywara@arm.com>,
Eric Auger <eric.auger@redhat.com>
Subject: [PATCH v2 10/17] KVM: arm64: nv: Handle L2->L1 transition on interrupt injection
Date: Sun, 12 Jan 2025 17:08:38 +0000 [thread overview]
Message-ID: <20250112170845.1181891-11-maz@kernel.org> (raw)
In-Reply-To: <20250112170845.1181891-1-maz@kernel.org>
An interrupt being delivered to L1 while running L2 must result
in the correct exception being delivered to L1.
This means that if, on entry to L2, we found ourselves with pending
interrupts in the L1 distributor, we need to take immediate action.
This is done by posting a request which will prevent the entry in
L2, and deliver an IRQ exception to L1, forcing the switch.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/include/asm/kvm_host.h | 17 +++++++++--------
arch/arm64/kvm/arm.c | 5 +++++
arch/arm64/kvm/nested.c | 3 +++
arch/arm64/kvm/vgic/vgic.c | 23 +++++++++++++++++++++++
4 files changed, 40 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 218047cd0296d..cb969c096d7bd 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -44,14 +44,15 @@
#define KVM_REQ_SLEEP \
KVM_ARCH_REQ_FLAGS(0, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
-#define KVM_REQ_IRQ_PENDING KVM_ARCH_REQ(1)
-#define KVM_REQ_VCPU_RESET KVM_ARCH_REQ(2)
-#define KVM_REQ_RECORD_STEAL KVM_ARCH_REQ(3)
-#define KVM_REQ_RELOAD_GICv4 KVM_ARCH_REQ(4)
-#define KVM_REQ_RELOAD_PMU KVM_ARCH_REQ(5)
-#define KVM_REQ_SUSPEND KVM_ARCH_REQ(6)
-#define KVM_REQ_RESYNC_PMU_EL0 KVM_ARCH_REQ(7)
-#define KVM_REQ_NESTED_S2_UNMAP KVM_ARCH_REQ(8)
+#define KVM_REQ_IRQ_PENDING KVM_ARCH_REQ(1)
+#define KVM_REQ_VCPU_RESET KVM_ARCH_REQ(2)
+#define KVM_REQ_RECORD_STEAL KVM_ARCH_REQ(3)
+#define KVM_REQ_RELOAD_GICv4 KVM_ARCH_REQ(4)
+#define KVM_REQ_RELOAD_PMU KVM_ARCH_REQ(5)
+#define KVM_REQ_SUSPEND KVM_ARCH_REQ(6)
+#define KVM_REQ_RESYNC_PMU_EL0 KVM_ARCH_REQ(7)
+#define KVM_REQ_NESTED_S2_UNMAP KVM_ARCH_REQ(8)
+#define KVM_REQ_GUEST_HYP_IRQ_PENDING KVM_ARCH_REQ(9)
#define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \
KVM_DIRTY_LOG_INITIALLY_SET)
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 3115c44ed4042..5e353b2c225b4 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1153,6 +1153,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
* preserved on VMID roll-over if the task was preempted,
* making a thread's VMID inactive. So we need to call
* kvm_arm_vmid_update() in non-premptible context.
+ *
+ * Note that this must happen after the check_vcpu_request()
+ * call to pick the correct s2_mmu structure, as a pending
+ * nested exception (IRQ, for example) can trigger a change
+ * in translation regime.
*/
if (kvm_arm_vmid_update(&vcpu->arch.hw_mmu->vmid) &&
has_vhe())
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 37f7ef2f44bd8..2b511d30939b3 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -1295,4 +1295,7 @@ void check_nested_vcpu_requests(struct kvm_vcpu *vcpu)
}
write_unlock(&vcpu->kvm->mmu_lock);
}
+
+ if (kvm_check_request(KVM_REQ_GUEST_HYP_IRQ_PENDING, vcpu))
+ kvm_inject_nested_irq(vcpu);
}
diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
index 324c547e1b4d8..9734a71b85611 100644
--- a/arch/arm64/kvm/vgic/vgic.c
+++ b/arch/arm64/kvm/vgic/vgic.c
@@ -906,6 +906,29 @@ static inline void vgic_restore_state(struct kvm_vcpu *vcpu)
/* Flush our emulation state into the GIC hardware before entering the guest. */
void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
{
+ /*
+ * If in a nested state, we must return early. Two possibilities:
+ *
+ * - If we have any pending IRQ for the guest and the guest
+ * expects IRQs to be handled in its virtual EL2 mode (the
+ * virtual IMO bit is set) and it is not already running in
+ * virtual EL2 mode, then we have to emulate an IRQ
+ * exception to virtual EL2.
+ *
+ * We do that by placing a request to ourselves which will
+ * abort the entry procedure and inject the exception at the
+ * beginning of the run loop.
+ *
+ * - Otherwise, do exactly *NOTHING*. The guest state is
+ * already loaded, and we can carry on with running it.
+ */
+ if (vgic_state_is_nested(vcpu)) {
+ if (kvm_vgic_vcpu_pending_irq(vcpu))
+ kvm_make_request(KVM_REQ_GUEST_HYP_IRQ_PENDING, vcpu);
+
+ return;
+ }
+
/*
* If there are no virtual interrupts active or pending for this
* VCPU, then there is no work to do and we can bail out without
--
2.39.2
next prev parent reply other threads:[~2025-01-12 17:20 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-12 17:08 [PATCH v2 00/17] KVM: arm64: Add NV GICv3 support Marc Zyngier
2025-01-12 17:08 ` [PATCH v2 01/17] arm64: sysreg: Add layout for ICH_HCR_EL2 Marc Zyngier
2025-01-15 18:39 ` Andre Przywara
2025-01-12 17:08 ` [PATCH v2 02/17] arm64: sysreg: Add layout for ICH_VTR_EL2 Marc Zyngier
2025-01-15 18:40 ` Andre Przywara
2025-01-12 17:08 ` [PATCH v2 03/17] arm64: sysreg: Add layout for ICH_MISR_EL2 Marc Zyngier
2025-01-15 18:41 ` Andre Przywara
2025-01-12 17:08 ` [PATCH v2 04/17] KVM: arm64: Move host SVE/SME state flags out of vCPU Marc Zyngier
2025-01-12 17:08 ` [PATCH v2 05/17] KVM: arm64: nv: Load timer before the GIC Marc Zyngier
2025-01-12 17:08 ` [PATCH v2 06/17] KVM: arm64: nv: Add ICH_*_EL2 registers to vpcu_sysreg Marc Zyngier
2025-01-12 17:08 ` [PATCH v2 07/17] KVM: arm64: nv: Plumb handling of GICv3 EL2 accesses Marc Zyngier
2025-01-12 17:08 ` [PATCH v2 08/17] KVM: arm64: nv: Sanitise ICH_HCR_EL2 accesses Marc Zyngier
2025-01-12 17:08 ` [PATCH v2 09/17] KVM: arm64: nv: Nested GICv3 emulation Marc Zyngier
2025-01-12 17:08 ` Marc Zyngier [this message]
2025-01-12 17:08 ` [PATCH v2 11/17] KVM: arm64: nv: Add Maintenance Interrupt emulation Marc Zyngier
2025-01-12 17:08 ` [PATCH v2 12/17] KVM: arm64: nv: Respect virtual HCR_EL2.TWx setting Marc Zyngier
2025-01-12 17:08 ` [PATCH v2 13/17] KVM: arm64: nv: Request vPE doorbell upon nested ERET to L2 Marc Zyngier
2025-01-12 17:08 ` [PATCH v2 14/17] KVM: arm64: nv: Propagate used_lrs between L1 and L0 contexts Marc Zyngier
2025-01-12 17:08 ` [PATCH v2 15/17] KVM: arm64: nv: Fold GICv3 host trapping requirements into guest setup Marc Zyngier
2025-01-12 17:08 ` [PATCH v2 16/17] KVM: arm64: nv: Allow userland to set VGIC maintenance IRQ Marc Zyngier
2025-01-12 17:08 ` [PATCH v2 17/17] KVM: arm64: nv: Fail KVM init if asking for NV without GICv3 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=20250112170845.1181891-11-maz@kernel.org \
--to=maz@kernel.org \
--cc=andre.przywara@arm.com \
--cc=eric.auger@redhat.com \
--cc=joey.gouly@arm.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=oliver.upton@linux.dev \
--cc=suzuki.poulose@arm.com \
--cc=yuzenghui@huawei.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).