* [PATCH 0/3] KVM: arm64: FEAT_{S1POE,ATS1A} support fixes
@ 2026-06-02 15:54 Marc Zyngier
2026-06-02 15:54 ` [PATCH 1/3] KVM: arm64: Key CPTR_EL2.E0POE propagation on FEAT_S1POE Marc Zyngier
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: Marc Zyngier @ 2026-06-02 15:54 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, kvm
Cc: Steffen Eiden, Joey Gouly, Suzuki K Poulose, Oliver Upton,
Zenghui Yu
Whilst working on a slightly unrelated feature (FEAT_NV3), I found out
that an L2 guest wouldn't boot if the host was exposed to FEAT_S1POE.
Upon investigation (and hours wasted in a SW model), it became
apparent that while the AT S1E1A code was ready for action, it had
never been fully plugged in (blame the usual suspect...).
This resulted in an extremely odd failure mode, with an L2 being
unable to make forward progress, but KVM at L1 not taking the hint
that something was really wrong. Additionally, an embarrassing typo
was spotted in the CPTR_EL2 handling.
With this in, FEAT_S1POE no longer breaks our NV guests.
Marc Zyngier (3):
KVM: arm64: Key CPTR_EL2.E0POE propagation on FEAT_S1POE
KVM: arm64: Wire AT S1E1A in the system instruction handling table
arm64: cpufeature: Expose ID_AA64ISAR2_EL1.ATS1A to KVM
arch/arm64/kernel/cpufeature.c | 1 +
arch/arm64/kvm/hyp/include/hyp/switch.h | 2 +-
arch/arm64/kvm/sys_regs.c | 1 +
3 files changed, 3 insertions(+), 1 deletion(-)
--
2.47.3
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/3] KVM: arm64: Key CPTR_EL2.E0POE propagation on FEAT_S1POE
2026-06-02 15:54 [PATCH 0/3] KVM: arm64: FEAT_{S1POE,ATS1A} support fixes Marc Zyngier
@ 2026-06-02 15:54 ` Marc Zyngier
2026-06-02 16:15 ` sashiko-bot
2026-06-02 15:54 ` [PATCH 2/3] KVM: arm64: Wire AT S1E1A in the system instruction handling table Marc Zyngier
` (3 subsequent siblings)
4 siblings, 1 reply; 7+ messages in thread
From: Marc Zyngier @ 2026-06-02 15:54 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, kvm
Cc: Steffen Eiden, Joey Gouly, Suzuki K Poulose, Oliver Upton,
Zenghui Yu
We propagate CPTR_EL2.E0POE from a L1 into the L0 configuration, but
we key this on the L1 guest supporting FEAT_S2POE. This is obviously
wrong, as this bit is solely concerned with Stage-1 translation.
Fix this by making the update depend on FEAT_S1POE.
Fixes: cd931bd6093cb ("KVM: arm64: nv: Add additional trap setup for CPTR_EL2")
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kvm/hyp/include/hyp/switch.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index bf0eb5e434274..161bb2a3e1d90 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -141,7 +141,7 @@ static inline void __activate_cptr_traps_vhe(struct kvm_vcpu *vcpu)
if (!(SYS_FIELD_GET(CPACR_EL1, ZEN, cptr) & BIT(0)))
val &= ~CPACR_EL1_ZEN;
- if (kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, S2POE, IMP))
+ if (kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, S1POE, IMP))
val |= cptr & CPACR_EL1_E0POE;
val |= cptr & CPTR_EL2_TCPAC;
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/3] KVM: arm64: Wire AT S1E1A in the system instruction handling table
2026-06-02 15:54 [PATCH 0/3] KVM: arm64: FEAT_{S1POE,ATS1A} support fixes Marc Zyngier
2026-06-02 15:54 ` [PATCH 1/3] KVM: arm64: Key CPTR_EL2.E0POE propagation on FEAT_S1POE Marc Zyngier
@ 2026-06-02 15:54 ` Marc Zyngier
2026-06-02 15:54 ` [PATCH 3/3] arm64: cpufeature: Expose ID_AA64ISAR2_EL1.ATS1A to KVM Marc Zyngier
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Marc Zyngier @ 2026-06-02 15:54 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, kvm
Cc: Steffen Eiden, Joey Gouly, Suzuki K Poulose, Oliver Upton,
Zenghui Yu
Despite having handling code for AT S1E1A, the instruction was
never plugged into the system instruction table, leading to an
exception being injected in the guest.
If the guest is Linux and using the __kvm_at() helper, the exception
is actually handled in the helper, and KVM continues more or less
silently by reentering the guest. Not exactly what you'd expect.
Fix this by plugging the emulation code where required.
Fixes: ff987ffc0c18c ("KVM: arm64: nv: Add support for FEAT_ATS1A")
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kvm/sys_regs.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 148fc3400ea81..753fe30d322c3 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -4217,6 +4217,7 @@ static struct sys_reg_desc sys_insn_descs[] = {
SYS_INSN(AT_S1E0W, handle_at_s1e01),
SYS_INSN(AT_S1E1RP, handle_at_s1e01),
SYS_INSN(AT_S1E1WP, handle_at_s1e01),
+ SYS_INSN(AT_S1E1A, handle_at_s1e01),
{ SYS_DESC(SYS_DC_CSW), access_dcsw },
{ SYS_DESC(SYS_DC_CGSW), access_dcgsw },
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/3] arm64: cpufeature: Expose ID_AA64ISAR2_EL1.ATS1A to KVM
2026-06-02 15:54 [PATCH 0/3] KVM: arm64: FEAT_{S1POE,ATS1A} support fixes Marc Zyngier
2026-06-02 15:54 ` [PATCH 1/3] KVM: arm64: Key CPTR_EL2.E0POE propagation on FEAT_S1POE Marc Zyngier
2026-06-02 15:54 ` [PATCH 2/3] KVM: arm64: Wire AT S1E1A in the system instruction handling table Marc Zyngier
@ 2026-06-02 15:54 ` Marc Zyngier
2026-06-02 17:49 ` [PATCH 0/3] KVM: arm64: FEAT_{S1POE,ATS1A} support fixes Oliver Upton
2026-06-03 10:41 ` Joey Gouly
4 siblings, 0 replies; 7+ messages in thread
From: Marc Zyngier @ 2026-06-02 15:54 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, kvm
Cc: Steffen Eiden, Joey Gouly, Suzuki K Poulose, Oliver Upton,
Zenghui Yu
KVM needs to know if the HW implements FEAT_ATS1A in order to correctly
sanitise HFGITR_EL2.ATS1E1A, which otherwise defaults to RES0 and
AT S1E1A traps are handled as UNDEF.
Solves this by exposing ID_AA64ISAR2_EL1.ATS1A to the rest of the kernel.
Fixes: ff987ffc0c18c ("KVM: arm64: nv: Add support for FEAT_ATS1A")
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kernel/cpufeature.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6d53bb15cf7bb..62b0d77217eeb 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -266,6 +266,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
};
static const struct arm64_ftr_bits ftr_id_aa64isar2[] = {
+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_ATS1A_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_LUT_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CSSC_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_RPRFM_SHIFT, 4, 0),
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/3] KVM: arm64: Key CPTR_EL2.E0POE propagation on FEAT_S1POE
2026-06-02 15:54 ` [PATCH 1/3] KVM: arm64: Key CPTR_EL2.E0POE propagation on FEAT_S1POE Marc Zyngier
@ 2026-06-02 16:15 ` sashiko-bot
0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-06-02 16:15 UTC (permalink / raw)
To: Marc Zyngier; +Cc: kvm
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] KVM fails to set CPACR_EL1_E0POE in hardware CPTR_EL2 for normal (non-nested) guests, causing all guest EL0 accesses to POR_EL0 to unexpectedly trap to KVM and result in injected UNDEF exceptions.
- [High] KVM breaks host Permission Overlay Extension (POE) usage upon returning from a VHE guest because __deactivate_cptr_traps_vhe() strips CPACR_EL1_E0POE.
--
commit d1828ccf84b404181eed585a3aaf208b36c6b88e
Author: Marc Zyngier <maz@kernel.org>
KVM: arm64: Key CPTR_EL2.E0POE propagation on FEAT_S1POE
We propagate CPTR_EL2.E0POE from a L1 into the L0 configuration, but
we key this on the L1 guest supporting FEAT_S2POE. This is obviously
wrong, as this bit is solely concerned with Stage-1 translation.
Fix this by making the update depend on FEAT_S1POE.
> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> index 98b2976837b11..4d814ae90613d 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> @@ -141,7 +141,7 @@ static inline void __activate_cptr_traps_vhe(struct kvm_vcpu *vcpu)
> if (!(SYS_FIELD_GET(CPACR_EL1, ZEN, cptr) & BIT(0)))
> val &= ~CPACR_EL1_ZEN;
>
> - if (kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, S2POE, IMP))
> + if (kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, S1POE, IMP))
> val |= cptr & CPACR_EL1_E0POE;
[Severity: High]
This isn't a bug introduced by this patch, but does this logic apply to
normal guests?
Looking at __activate_cptr_traps_vhe(), normal (non-nested) guests bypass
this nested trap propagation via:
if (!vcpu_has_nv(vcpu))
goto write;
As a result, CPACR_EL1_E0POE is never added to the val written to cpacr_el1,
so CPTR_EL2.E0POE is 0. Any guest EL0 access to POR_EL0 will then trap to
EL2.
Because SYS_POR_EL0 lacks an access callback in sys_reg_descs[] in
arch/arm64/kvm/sys_regs.c, kvm_handle_sys_reg() injects an undefined
instruction exception into the guest, crashing guest applications that rely
on POE.
[Severity: High]
This is a pre-existing issue, but does host POE remain active after running
a VHE guest?
Looking at __deactivate_cptr_traps_vhe() in the same file, the host's
cpacr_el1 is restored with a hardcoded bitmask (FPEN, ZEN, SMEN), and
CPACR_EL1_E0POE is unconditionally stripped:
u64 val = CPACR_EL1_FPEN;
if (cpus_have_final_cap(ARM64_SVE))
val |= CPACR_EL1_ZEN;
if (cpus_have_final_cap(ARM64_SME))
val |= CPACR_EL1_SMEN;
write_sysreg(val, cpacr_el1);
Since the E0POE bit enabled by the host kernel is overwritten, when the host
returns to userspace, EL0 tasks executing POE instructions will trap to EL2.
Because the host kernel has no hook for POR_EL0 in sys64_hooks, do_el0_sys()
falls back to do_el0_undef(), sending SIGILL and crashing the userspace
task.
> val |= cptr & CPTR_EL2_TCPAC;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260602155430.2088142-1-maz@kernel.org?part=1
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/3] KVM: arm64: FEAT_{S1POE,ATS1A} support fixes
2026-06-02 15:54 [PATCH 0/3] KVM: arm64: FEAT_{S1POE,ATS1A} support fixes Marc Zyngier
` (2 preceding siblings ...)
2026-06-02 15:54 ` [PATCH 3/3] arm64: cpufeature: Expose ID_AA64ISAR2_EL1.ATS1A to KVM Marc Zyngier
@ 2026-06-02 17:49 ` Oliver Upton
2026-06-03 10:41 ` Joey Gouly
4 siblings, 0 replies; 7+ messages in thread
From: Oliver Upton @ 2026-06-02 17:49 UTC (permalink / raw)
To: Marc Zyngier
Cc: kvmarm, linux-arm-kernel, kvm, Steffen Eiden, Joey Gouly,
Suzuki K Poulose, Zenghui Yu
On Tue, Jun 02, 2026 at 04:54:26PM +0100, Marc Zyngier wrote:
> Whilst working on a slightly unrelated feature (FEAT_NV3), I found out
> that an L2 guest wouldn't boot if the host was exposed to FEAT_S1POE.
>
> Upon investigation (and hours wasted in a SW model), it became
> apparent that while the AT S1E1A code was ready for action, it had
> never been fully plugged in (blame the usual suspect...).
>
> This resulted in an extremely odd failure mode, with an L2 being
> unable to make forward progress, but KVM at L1 not taking the hint
> that something was really wrong. Additionally, an embarrassing typo
> was spotted in the CPTR_EL2 handling.
>
> With this in, FEAT_S1POE no longer breaks our NV guests.
>
> Marc Zyngier (3):
> KVM: arm64: Key CPTR_EL2.E0POE propagation on FEAT_S1POE
> KVM: arm64: Wire AT S1E1A in the system instruction handling table
> arm64: cpufeature: Expose ID_AA64ISAR2_EL1.ATS1A to KVM
Reviewed-by: Oliver Upton <oupton@kernel.org>
Thanks,
Oliver
> arch/arm64/kernel/cpufeature.c | 1 +
> arch/arm64/kvm/hyp/include/hyp/switch.h | 2 +-
> arch/arm64/kvm/sys_regs.c | 1 +
> 3 files changed, 3 insertions(+), 1 deletion(-)
>
> --
> 2.47.3
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/3] KVM: arm64: FEAT_{S1POE,ATS1A} support fixes
2026-06-02 15:54 [PATCH 0/3] KVM: arm64: FEAT_{S1POE,ATS1A} support fixes Marc Zyngier
` (3 preceding siblings ...)
2026-06-02 17:49 ` [PATCH 0/3] KVM: arm64: FEAT_{S1POE,ATS1A} support fixes Oliver Upton
@ 2026-06-03 10:41 ` Joey Gouly
4 siblings, 0 replies; 7+ messages in thread
From: Joey Gouly @ 2026-06-03 10:41 UTC (permalink / raw)
To: Marc Zyngier
Cc: kvmarm, linux-arm-kernel, kvm, Steffen Eiden, Suzuki K Poulose,
Oliver Upton, Zenghui Yu
On Tue, Jun 02, 2026 at 04:54:26PM +0100, Marc Zyngier wrote:
> Whilst working on a slightly unrelated feature (FEAT_NV3), I found out
> that an L2 guest wouldn't boot if the host was exposed to FEAT_S1POE.
>
> Upon investigation (and hours wasted in a SW model), it became
> apparent that while the AT S1E1A code was ready for action, it had
> never been fully plugged in (blame the usual suspect...).
>
> This resulted in an extremely odd failure mode, with an L2 being
> unable to make forward progress, but KVM at L1 not taking the hint
> that something was really wrong. Additionally, an embarrassing typo
> was spotted in the CPTR_EL2 handling.
>
> With this in, FEAT_S1POE no longer breaks our NV guests.
>
> Marc Zyngier (3):
> KVM: arm64: Key CPTR_EL2.E0POE propagation on FEAT_S1POE
> KVM: arm64: Wire AT S1E1A in the system instruction handling table
> arm64: cpufeature: Expose ID_AA64ISAR2_EL1.ATS1A to KVM
>
> arch/arm64/kernel/cpufeature.c | 1 +
> arch/arm64/kvm/hyp/include/hyp/switch.h | 2 +-
> arch/arm64/kvm/sys_regs.c | 1 +
> 3 files changed, 3 insertions(+), 1 deletion(-)
Reviewed-by: Joey Gouly <joey.gouly@arm.com>
Thanks,
Joey
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-06-03 10:41 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-02 15:54 [PATCH 0/3] KVM: arm64: FEAT_{S1POE,ATS1A} support fixes Marc Zyngier
2026-06-02 15:54 ` [PATCH 1/3] KVM: arm64: Key CPTR_EL2.E0POE propagation on FEAT_S1POE Marc Zyngier
2026-06-02 16:15 ` sashiko-bot
2026-06-02 15:54 ` [PATCH 2/3] KVM: arm64: Wire AT S1E1A in the system instruction handling table Marc Zyngier
2026-06-02 15:54 ` [PATCH 3/3] arm64: cpufeature: Expose ID_AA64ISAR2_EL1.ATS1A to KVM Marc Zyngier
2026-06-02 17:49 ` [PATCH 0/3] KVM: arm64: FEAT_{S1POE,ATS1A} support fixes Oliver Upton
2026-06-03 10:41 ` Joey Gouly
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox