Re: [PATCH v2] KVM: arm64: Preserve all guest ZCR_EL2.LEN values

From: Joey Gouly

Date: Fri May 29 2026 - 05:47:38 EST


On Fri, May 29, 2026 at 10:22:41AM +0100, Marc Zyngier wrote:
> Thanks for respinning this patch quickly.
>
> On Fri, 29 May 2026 00:01:44 +0100,
> Mark Brown <broonie@xxxxxxxxxx> wrote:
> >
> > Since commit b3d29a823099 ("KVM: arm64: nv: Handle ZCR_EL2 traps") when
> > guests write to ZCR_EL2 we have clamped the value of ZCR_EL2.LEN to be
> > at most that configuring the maximum guest VL when accessed directly as
> > ZCR_EL2. This is not clearly the behaviour the architecture documents
> > for ZCR_EL2.LEN, while things are a little ambiguous currently there is
> > a fairly direct reading that suggests values will be read as written.
> > Further, the documented procedure for enumerating vector lengths means
> > that it is expected that values larger than the largest supported vector
> > length will be written in practice.
>
> Honestly, that's not the core issue. And even $SUBJECT fails to
> capture what is at stake here.
>
> >
> > The reasoning for the current behaviour is not specifically articulated, my
>
> I don't think there is a reasoning behind each and every bug.
>
> > best guess is that it is intended to ensure that the guest can not see an
> > effective VL greater than the maximum that has been configured, though
> > this will be ineffective when a VHE guest uses the ZCR_EL1 accessor.
>
> This last point *IS* the core problem. It is that the guest can access
> VLs beyond what is intended by the VM configuration. Not getting the
> read-as-written behaviour really is secondary compared to that issue.
>
> [...]
>
> I've rewritten the commit message to make it plain what the problem
> is, see below. I've also slightly tidied up access_zcr_el2(), but the
> fix otherwise looks good.

Seems like you're starting your own CMAAS! https://lore.kernel.org/kvmarm/86cxyzxymq.wl-maz@xxxxxxxxxx/

>
> Thanks,
>
> M.
>
> KVM: arm64: Correctly cap ZCR_EL2 provided by a guest hypervisor
>
> ZCR_EL2 can be updated by a VHE guest hypervisor either using ZCR_EL2
> (which traps) or ZCR_EL1 (which does not trap). KVM handles both in
> different way:
>
> - on ZCR_EL2 trap, ZCR_EL2.LEN is immediately capped at the VM's own
> VL limit. This has the potential to break existing SW that relies
> on the full LEN field to be stateful.
>
> - on ZCR_EL1 access, we do absolutely nothing.
>
> On restoring the SVE context for an L2 guest, we directly restore the
> guest hypervisor's view of ZCR_EL2 into the physical ZCR_EL2. If the
> guest's view of the register was updated using the ZCR_EL2 accessor,
> the value has already been sanitised (with the caveat mentioned above).
>
> But if the guest used ZCR_EL1, the raw value is written into the HW,
> and the L2 guest can now access VLs that it shouldn't.
>
> Fix all the above by moving the VL capping to the restore points,
> ensuring that:
>
> - the HW is always programmed with a capped value, irrespective of
> the accessor being used,
>
> - the ZCR_EL2.LEN field is always completely stateful, irrespective
> of the accessor being used.
>
> Additionally, move ZCR_EL2 to be a sanitised register, ensuring that
> only the LEN field is actually stateful. This requires some creative
> construction of the RES0 mask, as the sysreg generation script does
> not yet generate RAZ/WI fields.
>
> --

Reviewed-by: Joey Gouly <joey.gouly@xxxxxxx>

Thanks,
Joey

> Without deviation from the norm, progress is not possible.