[PATCH v2 4/6] KVM: arm64: Account for RES1 bits in DECLARE_FEAT_MAP() and co

Nathan Chancellor nathan at kernel.org
Wed Jan 21 15:32:04 PST 2026


On Wed, Jan 21, 2026 at 10:50:45AM +0000, Marc Zyngier wrote:
> Let me guess: Cortex-A72 or similarly ancient ARM-designed CPUs, as
> hinted by the lack of GICv3 TDIR control? Then these do not have
> FEAT_FGT.

Yeah, Cortex-A72 for the one box and an Ampere Altra Q80-26 (which I
believe is Neoverse-N1 cores?), so indeed, no FGT it seems.

> The issue stems from the fact that as an optimisation, we skip the
> parsing of the FGT trap table on such hardware, which also results in
> the FGT masks of known bits not being updated. We then compute the
> effective feature map, and discover that the two don't match.
> 
> It was harmless so far, as we were only dealing with RES0 bits, and
> assuming that anything that wasn't a RES0 bit was a stateful bit. With
> the introduction of RES1 handling, we've run out of luck. To be clear,
> that's just a warning, not a functional issue.
> 
> At this point, I don't think the above "optimisation" is worth having.
> This is only done *once*, at boot time, so the gain is extremely
> small. I'd like the checks to be effective irrespective of the HW the
> kernel runs on, which is consistent with what we do for other tables
> describing the architectural state.
> 
> Anyway, I came up with the following hack, which performs the checks,
> but avoid inserting the FGT information in the sysreg xarray if the HW
> doesn't support it, as a memory saving measure. Please let me know if
> that helps (it does on my old boxes).

Works for me as well, no warnings on either box with this patch applied.
If it is useful for a follow up submission:

Tested-by: Nathan Chancellor <nathan at kernel.org>

> diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
> index 88336336efc9f..fa8fa09de67dc 100644
> --- a/arch/arm64/kvm/emulate-nested.c
> +++ b/arch/arm64/kvm/emulate-nested.c
> @@ -2284,9 +2284,6 @@ int __init populate_nv_trap_config(void)
>  	kvm_info("nv: %ld coarse grained trap handlers\n",
>  		 ARRAY_SIZE(encoding_to_cgt));
>  
> -	if (!cpus_have_final_cap(ARM64_HAS_FGT))
> -		goto check_mcb;
> -
>  	for (int i = 0; i < ARRAY_SIZE(encoding_to_fgt); i++) {
>  		const struct encoding_to_trap_config *fgt = &encoding_to_fgt[i];
>  		union trap_config tc;
> @@ -2306,6 +2303,15 @@ int __init populate_nv_trap_config(void)
>  			}
>  
>  			tc.val |= fgt->tc.val;
> +
> +			if (!aggregate_fgt(tc)) {
> +				ret = -EINVAL;
> +				print_nv_trap_error(fgt, "FGT bit is reserved", ret);
> +			}
> +
> +			if (!cpus_have_final_cap(ARM64_HAS_FGT))
> +				continue;
> +
>  			prev = xa_store(&sr_forward_xa, enc,
>  					xa_mk_value(tc.val), GFP_KERNEL);
>  
> @@ -2313,11 +2319,6 @@ int __init populate_nv_trap_config(void)
>  				ret = xa_err(prev);
>  				print_nv_trap_error(fgt, "Failed FGT insertion", ret);
>  			}
> -
> -			if (!aggregate_fgt(tc)) {
> -				ret = -EINVAL;
> -				print_nv_trap_error(fgt, "FGT bit is reserved", ret);
> -			}
>  		}
>  	}
>  
> @@ -2333,7 +2334,6 @@ int __init populate_nv_trap_config(void)
>  	kvm_info("nv: %ld fine grained trap handlers\n",
>  		 ARRAY_SIZE(encoding_to_fgt));
>  
> -check_mcb:
>  	for (int id = __MULTIPLE_CONTROL_BITS__; id < __COMPLEX_CONDITIONS__; id++) {
>  		const enum cgt_group_id *cgids;
>  
> 
> -- 
> Without deviation from the norm, progress is not possible.



More information about the linux-arm-kernel mailing list