[PATCH v13 05/32] arm64/sve: Factor virtualizable VL discovery out of SVE specific code
From: Mark Brown <broonie@kernel.org>
Date: 2026-07-19 23:10:19
Also in:
kvm, kvmarm, linux-doc, linux-kselftest, lkml
Subsystem:
arm64 port (aarch64 architecture), the rest · Maintainers:
Catalin Marinas, Will Deacon, Linus Torvalds
In preparation for reuising it for SME pull the code for discovering the maximum virtualizable vector length out of sve_setup() into a separate function, updating to return 0 without a WARN_ON() for the case where no virtualisable VL exists. For SVE this case is architecturally invalid but for SME it is valid if ill advised. Signed-off-by: Mark Brown <broonie@kernel.org> --- arch/arm64/kernel/fpsimd.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-)
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index b5535f8c9bd9..314f5d61be11 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c@@ -1118,6 +1118,29 @@ int vec_verify_vq_map(enum vec_type type) return 0; } +static int __init vec_virtualisable_vl(struct vl_info *info) +{ + DECLARE_BITMAP(partial_only_map, SVE_VQ_MAX); + unsigned long b_min_partial, b_max_virt; + + bitmap_andnot(partial_only_map, info->vq_partial_map, info->vq_map, + SVE_VQ_MAX); + b_min_partial = find_last_bit(partial_only_map, SVE_VQ_MAX); + + /* All implemented VLs are virtualisable */ + if (b_min_partial >= SVE_VQ_MAX) + return info->max_vl; + + b_max_virt = find_next_bit(info->vq_map, SVE_VQ_MAX, b_min_partial); + + /* No implemented VLs are virtualisable */ + if (b_max_virt >= SVE_VQ_MAX) + return 0; + + /* At least one virtualisable VL exists */ + return sve_vl_from_vq(__bit_to_vq(b_max_virt)); +} + void cpu_enable_sve(const struct arm64_cpu_capabilities *__always_unused p) { write_sysreg(read_sysreg(CPACR_EL1) | CPACR_EL1_ZEN_EL1EN, CPACR_EL1);
@@ -1129,8 +1152,6 @@ void cpu_enable_sve(const struct arm64_cpu_capabilities *__always_unused p) void __init sve_setup(void) { struct vl_info *info = &vl_info[ARM64_VEC_SVE]; - DECLARE_BITMAP(tmp_map, SVE_VQ_MAX); - unsigned long b; int max_bit; if (!system_supports_sve())
@@ -1153,21 +1174,7 @@ void __init sve_setup(void) */ set_sve_default_vl(find_supported_vector_length(ARM64_VEC_SVE, 64)); - 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) - /* No non-virtualisable VLs found */ - info->max_virtualisable_vl = SVE_VQ_MAX; - else if (WARN_ON(b == SVE_VQ_MAX - 1)) - /* No virtualisable VLs? This is architecturally forbidden. */ - info->max_virtualisable_vl = SVE_VQ_MIN; - else /* b + 1 < SVE_VQ_MAX */ - 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; + info->max_virtualisable_vl = vec_virtualisable_vl(info); pr_info("%s: maximum available vector length %u bytes per vector\n", info->name, info->max_vl);
--
2.47.3