* [PATCH 1/2] KVM: arm64: nv: Treat AMO as 1 when at EL2 and {E2H,TGE} = {1, 0}
2025-09-18 16:46 [PATCH 0/2] KVM: arm64: nv: Fix SError injection at EL2 Oliver Upton
@ 2025-09-18 16:46 ` Oliver Upton
2025-09-18 16:46 ` [PATCH 2/2] [DO NOT SUBMIT] KVM: arm64: selftests: Test effective value of HCR_EL2.AMO Oliver Upton
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Oliver Upton @ 2025-09-18 16:46 UTC (permalink / raw)
To: kvmarm; +Cc: Marc Zyngier, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Oliver Upton
SErrors are not deliverable at EL2 when the effective value of
HCR_EL2.{TGE,AMO} = {0, 0}. This is bothersome to deal with in nested
as we need to use auxiliary pending state to track the pending vSError
since HCR_EL2.VSE has no mechanism for honoring the guest HCR. On top of
that, we have no way of making that auxiliary pending state visible in
ISR_EL1.
A defect against the architecture now allows an implementation to treat
HCR_EL2.AMO as 1 when HCR_EL2.{E2H,TGE} = {1, 0}. Let's do exactly that,
meaning SErrors are always deliverable at EL2 for the typical E2H=RES1
VM.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arch/arm64/include/asm/kvm_emulate.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index fa8a08a1ccd5..64ce3fec73ee 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -220,6 +220,20 @@ static inline bool vcpu_el2_tge_is_set(const struct kvm_vcpu *vcpu)
static inline bool vcpu_el2_amo_is_set(const struct kvm_vcpu *vcpu)
{
+ /*
+ * DDI0487L.b Known Issue D22105
+ *
+ * When executing at EL2 and HCR_EL2.{E2H,TGE} = {1, 0} it is
+ * IMPLEMENTATION DEFINED whether the effective value of HCR_EL2.AMO
+ * is the value programmed or 1.
+ *
+ * Make the implementation choice of treating the effective value as 1 as
+ * we cannot subsequently catch changes to TGE or AMO that would
+ * otherwise lead to the SError becoming deliverable.
+ */
+ if (vcpu_is_el2(vcpu) && vcpu_el2_e2h_is_set(vcpu) && !vcpu_el2_tge_is_set(vcpu))
+ return true;
+
return ctxt_sys_reg(&vcpu->arch.ctxt, HCR_EL2) & HCR_AMO;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 2/2] [DO NOT SUBMIT] KVM: arm64: selftests: Test effective value of HCR_EL2.AMO
2025-09-18 16:46 [PATCH 0/2] KVM: arm64: nv: Fix SError injection at EL2 Oliver Upton
2025-09-18 16:46 ` [PATCH 1/2] KVM: arm64: nv: Treat AMO as 1 when at EL2 and {E2H,TGE} = {1, 0} Oliver Upton
@ 2025-09-18 16:46 ` Oliver Upton
2025-09-19 9:58 ` [PATCH 0/2] KVM: arm64: nv: Fix SError injection at EL2 Marc Zyngier
2025-09-19 12:39 ` Marc Zyngier
3 siblings, 0 replies; 5+ messages in thread
From: Oliver Upton @ 2025-09-18 16:46 UTC (permalink / raw)
To: kvmarm; +Cc: Marc Zyngier, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Oliver Upton
A defect against the architecture now allows an implementation to treat
AMO as 1 when HCR_EL2.{E2H, TGE} = {1, 0}. KVM now takes advantage of
this interpretation to address a quality of emulation issue w.r.t.
SError injection.
Add a corresponding test case and expect a pending SError to be taken.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
.../selftests/kvm/arm64/external_aborts.c | 38 +++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/tools/testing/selftests/kvm/arm64/external_aborts.c b/tools/testing/selftests/kvm/arm64/external_aborts.c
index 062bf84cced1..78c29975f0a6 100644
--- a/tools/testing/selftests/kvm/arm64/external_aborts.c
+++ b/tools/testing/selftests/kvm/arm64/external_aborts.c
@@ -318,6 +318,39 @@ static void test_mmio_ease(void)
kvm_vm_free(vm);
}
+static void test_serror_amo_guest(void)
+{
+ sysreg_clear_set(hcr_el2, HCR_EL2_AMO | HCR_EL2_TGE, 0);
+
+ GUEST_SYNC(0);
+ GUEST_ASSERT(read_sysreg(isr_el1) & ISR_EL1_A);
+
+ /*
+ * KVM treats the effective value of AMO as 1 when
+ * HCR_EL2.{E2H,TGE} = {1, 0}, meaning the SError will be taken when
+ * unmasked.
+ */
+ local_serror_enable();
+ isb();
+ local_serror_disable();
+
+ GUEST_FAIL("Should've taken pending SError exception");
+}
+
+static void test_serror_amo(void)
+{
+ struct kvm_vcpu *vcpu;
+ struct kvm_vm *vm = vm_create_with_dabt_handler(&vcpu, test_serror_amo_guest,
+ unexpected_dabt_handler);
+
+ vm_install_exception_handler(vm, VECTOR_ERROR_CURRENT, expect_serror_handler);
+
+ vcpu_run_expect_sync(vcpu);
+ vcpu_inject_serror(vcpu);
+ vcpu_run_expect_done(vcpu);
+ kvm_vm_free(vm);
+}
+
int main(void)
{
test_mmio_abort();
@@ -327,4 +360,9 @@ int main(void)
test_serror_masked();
test_serror_emulated();
test_mmio_ease();
+
+ if (!kvm_check_cap(KVM_CAP_ARM_EL2))
+ return 0;
+
+ test_serror_amo();
}
--
2.47.3
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH 0/2] KVM: arm64: nv: Fix SError injection at EL2
2025-09-18 16:46 [PATCH 0/2] KVM: arm64: nv: Fix SError injection at EL2 Oliver Upton
2025-09-18 16:46 ` [PATCH 1/2] KVM: arm64: nv: Treat AMO as 1 when at EL2 and {E2H,TGE} = {1, 0} Oliver Upton
2025-09-18 16:46 ` [PATCH 2/2] [DO NOT SUBMIT] KVM: arm64: selftests: Test effective value of HCR_EL2.AMO Oliver Upton
@ 2025-09-19 9:58 ` Marc Zyngier
2025-09-19 12:39 ` Marc Zyngier
3 siblings, 0 replies; 5+ messages in thread
From: Marc Zyngier @ 2025-09-19 9:58 UTC (permalink / raw)
To: Oliver Upton; +Cc: kvmarm, Joey Gouly, Suzuki K Poulose, Zenghui Yu
On Thu, 18 Sep 2025 17:46:30 +0100,
Oliver Upton <oliver.upton@linux.dev> wrote:
>
> FEAT_NV2 keeps us out of the loop on changes to HCR_EL2. That really
> sucks when the guest hypervisor toggles bits that affect the hyp
> context, such as TGE and xMO.
>
> The architecture now allows an implementation to treat HCR_EL2.AMO as 1
> any time that HCR_EL2.{E2H,TGE} = {1, 0}, effectively allowing us to
> hide what would otherwise be a quality of emulation bug in SError
> injection.
Yup. Note that the same relaxation also applies to IMO/FMO (that's the
reason why this relaxation was originally introduced), but I don't
think we need to do anything on that front.
> Unfortunately there's nothing to be done for E2H0 VMs, although given
> the direction of the architecture the offending hypervisor should just
> get with the times...
I have no sympathy for these either. Eventually, they'll get on with
the program, or experience the fate of 32bit...
I'll drag this into 6.18.
Thanks,
M.
--
Jazz isn't dead. It just smells funny.
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH 0/2] KVM: arm64: nv: Fix SError injection at EL2
2025-09-18 16:46 [PATCH 0/2] KVM: arm64: nv: Fix SError injection at EL2 Oliver Upton
` (2 preceding siblings ...)
2025-09-19 9:58 ` [PATCH 0/2] KVM: arm64: nv: Fix SError injection at EL2 Marc Zyngier
@ 2025-09-19 12:39 ` Marc Zyngier
3 siblings, 0 replies; 5+ messages in thread
From: Marc Zyngier @ 2025-09-19 12:39 UTC (permalink / raw)
To: kvmarm, Oliver Upton; +Cc: Joey Gouly, Suzuki K Poulose, Zenghui Yu
On Thu, 18 Sep 2025 09:46:30 -0700, Oliver Upton wrote:
> FEAT_NV2 keeps us out of the loop on changes to HCR_EL2. That really
> sucks when the guest hypervisor toggles bits that affect the hyp
> context, such as TGE and xMO.
>
> The architecture now allows an implementation to treat HCR_EL2.AMO as 1
> any time that HCR_EL2.{E2H,TGE} = {1, 0}, effectively allowing us to
> hide what would otherwise be a quality of emulation bug in SError
> injection.
>
> [...]
Applied to next, thanks!
[1/2] KVM: arm64: nv: Treat AMO as 1 when at EL2 and {E2H,TGE} = {1, 0}
commit: ff37a41db8b47834b747b3bb427825fc75bc86a7
Cheers,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 5+ messages in thread