Re: [PATCH v2 3/3] KVM: selftests: arm64: Skip sea_to_user when EINJ places no poison
From: Jiaqi Yan
Date: Sun Aug 23 2026 - 14:58:01 EST
On Tue, Aug 18, 2026 at 4:29 AM Like Xu <like.xu.linux@xxxxxxxxx> wrote:
>
> sea_to_user injects a memory UER with EINJ notrigger=1 and expects the
> guest to consume it and trap to KVM as an SEA. On some firmware the test
> aborts instead:
>
> arm64/sea_to_user.c:223: exit_reason == (41)
> Wanted KVM exit reason: 41 (ARM_SEA), got: 6 (MMIO)
>
> notrigger=1 asks firmware to arm the poison without consuming it, but on
> these platforms the poison is only armed as part of the trigger step that
> notrigger skips, so nothing consumable is left in memory. The guest reads
> back the sentinel, no SEA occurs, and GUEST_FAIL fires. On arm64 a ucall
> is delivered as an MMIO write, which surfaces as the KVM_EXIT_MMIO above
> rather than a KVM bug.
Thanks for the fixes, looks good to me.
Reviewed-by: Jiaqi Yan <jiaqiyan@xxxxxxxxxx>
>
> The file already documents that the test must be skipped when firmware
> cannot deliver a consumable error. Detect the guest abort that follows a
> missing SEA and skip, instead of failing on a firmware limitation the
> test cannot control.
>
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: Like Xu <likexu@xxxxxxxxxxx>
> ---
> .../testing/selftests/kvm/arm64/sea_to_user.c | 24 +++++++++++++++++--
> 1 file changed, 22 insertions(+), 2 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/arm64/sea_to_user.c b/tools/testing/selftests/kvm/arm64/sea_to_user.c
> index 7cf95da8e594d..d4af6e0eed288 100644
> --- a/tools/testing/selftests/kvm/arm64/sea_to_user.c
> +++ b/tools/testing/selftests/kvm/arm64/sea_to_user.c
> @@ -215,13 +215,33 @@ static void run_vm(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
>
> ksft_print_msg("Dump kvm_run info about KVM_EXIT_%s\n",
> exit_reason_str(run->exit_reason));
> +
> + /*
> + * The guest's read of the injected location is expected to trap to KVM
> + * as an SEA. If it does not, the injected error was never placed as
> + * consumable poison: some firmware honours EINJ's notrigger request by
> + * arming the poison only as part of the (now skipped) trigger step, so
> + * nothing is left in memory for the guest to consume. The guest then
> + * reads back the sentinel value and reports it via GUEST_FAIL, which
> + * arm64 delivers as a ucall over MMIO (hence a KVM_EXIT_MMIO here).
> + * Treat that as "this platform cannot host the test" and skip, matching
> + * the requirement documented at the top of this file, rather than
> + * failing on a hardware/firmware limitation the test cannot control.
> + */
> + if (run->exit_reason != KVM_EXIT_ARM_SEA &&
> + get_ucall(vcpu, &uc) == UCALL_ABORT) {
> + ksft_print_msg("Guest consumed no SEA: %s", uc.buffer);
> + ksft_exit_skip("EINJ notrigger placed no consumable poison on this platform\n");
> + }
> +
> + TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_ARM_SEA);
> +
> + /* arm_sea holds valid data only for a KVM_EXIT_ARM_SEA exit. */
> ksft_print_msg("kvm_run.arm_sea: esr=%#llx, flags=%#llx\n",
> run->arm_sea.esr, run->arm_sea.flags);
> ksft_print_msg("kvm_run.arm_sea: gva=%#llx, gpa=%#llx\n",
> run->arm_sea.gva, run->arm_sea.gpa);
>
> - TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_ARM_SEA);
> -
> esr = run->arm_sea.esr;
> TEST_ASSERT_EQ(ESR_ELx_EC(esr), ESR_ELx_EC_DABT_LOW);
> TEST_ASSERT_EQ(esr & ESR_ELx_FSC_TYPE, ESR_ELx_FSC_EXTABT);
> --
> 2.50.1 (Apple Git-155)
>