[PATCH v3 20/28] KVM: arm64: Add sanitisation for NVHCR_EL2

Yao Yuan yaoyuan at linux.alibaba.com
Thu Jul 23 23:16:46 PDT 2026


On Wed, Jul 22, 2026 at 08:42:26AM +0800, Marc Zyngier wrote:
> Just like any other VNCR-based register, NVHCR_EL2 requires some
> level of sanitisation. Being specified as a live copy of HCR_EL2,
> it adopts the exact same format, but depends on FEAT_NV3 instead.
>
> A subtle aspect is that we only want to apply the sanitisation if
> FEAT_NV3 is actually present, as the VNCR location is otherwise
> used to back accesses to HCR_EL2.
>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/kvm/config.c | 15 +++++++++++++++
>  arch/arm64/kvm/nested.c |  4 ++++
>  2 files changed, 19 insertions(+)
>
> diff --git a/arch/arm64/kvm/config.c b/arch/arm64/kvm/config.c
> index 467f57eb8e6bb..1053676551aff 100644
> --- a/arch/arm64/kvm/config.c
> +++ b/arch/arm64/kvm/config.c
> @@ -1019,6 +1019,9 @@ static const struct reg_bits_to_feat_map hcr_feat_map[] = {
>  static const DECLARE_FEAT_MAP(hcr_desc, HCR_EL2,
>  			      hcr_feat_map, FEAT_AA64EL2);
>
> +static const DECLARE_FEAT_MAP(nvhcr_desc, NVHCR_EL2,
> +			      hcr_feat_map, FEAT_NV3);
> +
>  static const struct reg_bits_to_feat_map sctlr2_feat_map[] = {
>  	NEEDS_FEAT(SCTLR2_EL1_NMEA	|
>  		   SCTLR2_EL1_EASE,
> @@ -1393,6 +1396,7 @@ void __init check_feature_map(void)
>  	check_reg_desc(&hdfgwtr2_desc);
>  	check_reg_desc(&hcrx_desc);
>  	check_reg_desc(&hcr_desc);
> +	check_reg_desc(&nvhcr_desc);
>  	check_reg_desc(&sctlr2_desc);
>  	check_reg_desc(&tcr2_el2_desc);
>  	check_reg_desc(&sctlr_el1_desc);
> @@ -1592,6 +1596,17 @@ struct resx get_reg_fixed_bits(struct kvm *kvm, enum vcpu_sysreg reg)
>  	case HCR_EL2:
>  		resx = compute_reg_resx_bits(kvm, &hcr_desc, 0, 0);
>  		break;
> +	case NVHCR_EL2:
> +		/*
> +		 * Only apply sanitisation if we do have FEAT_NV3.
> +		 * Otherwise, the register aliases with HCR_EL2 in VNCR,
> +		 * and we're better off relying on data transfers between
> +		 * NVHCR_EL2 and HCR_EL2 to sanitise things.
> +		 */
> +		resx = (kvm_has_nv3(kvm) ?
> +			compute_reg_resx_bits(kvm, &nvhcr_desc, 0, 0) :
> +			(typeof(resx)){});
> +		break;

Reviewed-by: Yuan Yao <yaoyuan at linux.alibaba.com>

>  	case SCTLR2_EL1:
>  	case SCTLR2_EL2:
>  		resx = compute_reg_resx_bits(kvm, &sctlr2_desc, 0, 0);
> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> index 35a1c42ad3f84..f646894fec9a9 100644
> --- a/arch/arm64/kvm/nested.c
> +++ b/arch/arm64/kvm/nested.c
> @@ -1830,6 +1830,10 @@ int kvm_init_nv_sysregs(struct kvm_vcpu *vcpu)
>  	resx = get_reg_fixed_bits(kvm, HCR_EL2);
>  	set_sysreg_masks(kvm, HCR_EL2, resx);
>
> +	/* NVHCR_EL2 */
> +	resx = get_reg_fixed_bits(kvm, NVHCR_EL2);
> +	set_sysreg_masks(kvm, NVHCR_EL2, resx);
> +
>  	/* HCRX_EL2 */
>  	resx = get_reg_fixed_bits(kvm, HCRX_EL2);
>  	set_sysreg_masks(kvm, HCRX_EL2, resx);
> --
> 2.47.3



More information about the linux-arm-kernel mailing list