[PATCH v1 1/8] KVM: arm64: Route MOPS exceptions to EL2 when guest lacks support
Joey Gouly
joey.gouly at arm.com
Tue Nov 4 05:44:39 PST 2025
Hi Fuad,
On Tue, Nov 04, 2025 at 12:58:59PM +0000, Fuad Tabba wrote:
> MOPS exceptions must be routed to the hypervisor (EL2) when the guest
> does not support the feature. If the guest does support MOPS, exceptions
> should be handled by the guest at EL1.
>
> The existing logic was inverted: exceptions were trapped to EL2 (by
> setting HCRX_EL2_MCE2) when the guest supported MOPS, and left to be
> handled at EL1 when it did not.
>
This doesn't seem quite right? Check the commit message of 2de451a329:
A KVM guest may use the instructions at EL1 at times when the guest is
not able to handle the exception, expecting that the instructions will
only run on one CPU (e.g. when running UEFI boot services in the guest).
As KVM may reschedule the guest between different types of CPUs at any
time (on an asymmetric system), it needs to also handle the resulting
exception itself in case the guest is not able to. A similar situation
will also occur in the future when live migrating a guest from one type
of CPU to another.
So it's intentionally trapping MOPS to EL2.
Also with HCRX_EL2.MSCEn=0, execution of the MOPS instructions are UNDEFINED at
EL0/EL1, so you wouldn't take any MOPS exceptions to EL2 anyway.
Thanks,
Joey
> Fix this by moving the setting of HCRX_EL2_MCE2 from the feature-check
> block to the 'else' block, ensuring exceptions are only trapped to EL2
> when the guest cannot handle them.
>
> Fixes: 84de212d739e ("KVM: arm64: Make FEAT_MOPS UNDEF if not advertised to the guest")
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
> arch/arm64/include/asm/kvm_emulate.h | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> index c9eab316398e..0f8311263edf 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -684,7 +684,9 @@ static inline void vcpu_set_hcrx(struct kvm_vcpu *vcpu)
> vcpu->arch.hcrx_el2 = HCRX_EL2_SMPME;
>
> if (kvm_has_feat(kvm, ID_AA64ISAR2_EL1, MOPS, IMP))
> - vcpu->arch.hcrx_el2 |= (HCRX_EL2_MSCEn | HCRX_EL2_MCE2);
> + vcpu->arch.hcrx_el2 |= HCRX_EL2_MSCEn;
> + else
> + vcpu->arch.hcrx_el2 |= HCRX_EL2_MCE2;
>
> if (kvm_has_tcr2(kvm))
> vcpu->arch.hcrx_el2 |= HCRX_EL2_TCR2En;
> --
> 2.51.2.997.g839fc31de9-goog
>
More information about the linux-arm-kernel
mailing list