[PATCH v1 1/8] KVM: arm64: Route MOPS exceptions to EL2 when guest lacks support

Fuad Tabba tabba at google.com
Tue Nov 4 05:49:18 PST 2025


Hi Joey,

On Tue, 4 Nov 2025 at 13:44, Joey Gouly <joey.gouly at arm.com> wrote:
>
> 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 for the clarification, you're right. I'll drop this patch.

Cheers,
/fuad

> 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