Hi Mark,
On Tue, 23 Dec 2025 at 01:21, Mark Brown <[email protected]> wrote:
>
> As with SVE we can only virtualise SME vector lengths that are supported by
> all CPUs in the system, implement similar checks to those for SVE. Since
> unlike SVE there are no specific vector lengths that are architecturally
> required the handling is subtly different, we report a system where this
> happens with a maximum vector length of -1.
>
> Signed-off-by: Mark Brown <[email protected]>
> ---
> arch/arm64/kernel/fpsimd.c | 23 ++++++++++++++++++++++-
> 1 file changed, 22 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> index f4e8cee00198..22f8397c67f0 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -1257,7 +1257,8 @@ void cpu_enable_sme(const struct arm64_cpu_capabilities
> *__always_unused p)
> void __init sme_setup(void)
> {
> struct vl_info *info = &vl_info[ARM64_VEC_SME];
> - int min_bit, max_bit;
> + DECLARE_BITMAP(tmp_map, SVE_VQ_MAX);
> + int min_bit, max_bit, b;
>
> if (!system_supports_sme())
> return;
> @@ -1288,12 +1289,32 @@ void __init sme_setup(void)
> */
> set_sme_default_vl(find_supported_vector_length(ARM64_VEC_SME, 32));
>
> + bitmap_andnot(tmp_map, info->vq_partial_map, info->vq_map,
> + SVE_VQ_MAX);
> +
> + b = find_last_bit(tmp_map, SVE_VQ_MAX);
> + if (b >= SVE_VQ_MAX)
> + /* All VLs virtualisable */
> + info->max_virtualisable_vl = SVE_VQ_MAX;
> + else if (b == SVE_VQ_MAX - 1)
> + /* No virtualisable VLs */
> + info->max_virtualisable_vl = -1;
I'm not sure about -1 as the "No virtualisable VLs" value. Unless I've
missed something, this value gets used without being checked,
potentially even assigned to an unsigned int:
> kvm_max_vl[ARM64_VEC_SME] = sme_max_virtualisable_vl();
Cheers,
/fuad
> + else
> + info->max_virtualisable_vl = sve_vl_from_vq(__bit_to_vq(b +
> 1));
> +
> + if (info->max_virtualisable_vl > info->max_vl)
> + info->max_virtualisable_vl = info->max_vl;
> +
> pr_info("SME: minimum available vector length %u bytes per vector\n",
> info->min_vl);
> pr_info("SME: maximum available vector length %u bytes per vector\n",
> info->max_vl);
> pr_info("SME: default vector length %u bytes per vector\n",
> get_sme_default_vl());
> +
> + /* KVM decides whether to support mismatched systems. Just warn here:
> */
> + if (info->max_virtualisable_vl < info->max_vl)
> + pr_warn("SME: unvirtualisable vector lengths present\n");
> }
>
> void sme_suspend_exit(void)
>
> --
> 2.47.3
>