[PATCH v1] KVM: arm64: Allocate for maximum vector length for pKVM host sve state
Fuad Tabba
tabba at google.com
Wed Jun 5 08:03:12 PDT 2024
In a heterogeneous system, a cpu could have an sve/sme vector
length that is larger than the rest. Store the value of the
largest possible vector length in the system. When allocating
memory for the host sve state in pKVM, allocate for the largest
possible sve vector length.
Fixes: 66d5b53e20a6 ("KVM: arm64: Allocate memory mapped at hyp for host sve state in pKVM")
Reported-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Fuad Tabba <tabba at google.com>
---
Based on kvmarm/fixes (afb91f5f8ad7)
Mark Brown submitted a patch series that fixes this [1].
I'm sending this patch since it might be simpler.
[1] https://lore.kernel.org/all/20240605-kvm-arm64-fix-pkvm-sve-vl-v1-0-680d6b43b4c1@kernel.org/
---
arch/arm64/include/asm/fpsimd.h | 13 +++++++++++++
arch/arm64/kernel/fpsimd.c | 7 ++++++-
arch/arm64/kvm/reset.c | 2 +-
3 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index bc69ac368d73..a72dda932291 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -184,6 +184,9 @@ struct vl_info {
int max_vl;
int max_virtualisable_vl;
+ /* The maximum vl encountered for any cpu in the system. */
+ int max_system_vl;
+
/*
* Set of available vector lengths,
* where length vq encoded as bit __vq_to_bit(vq):
@@ -274,6 +277,11 @@ static inline int vec_max_virtualisable_vl(enum vec_type type)
return vl_info[type].max_virtualisable_vl;
}
+static inline int vec_max_system_vl(enum vec_type type)
+{
+ return vl_info[type].max_system_vl;
+}
+
static inline int sve_max_vl(void)
{
return vec_max_vl(ARM64_VEC_SVE);
@@ -284,6 +292,11 @@ static inline int sve_max_virtualisable_vl(void)
return vec_max_virtualisable_vl(ARM64_VEC_SVE);
}
+static inline int sve_max_system_vl(void)
+{
+ return vec_max_system_vl(ARM64_VEC_SVE);
+}
+
/* Ensure vq >= SVE_VQ_MIN && vq <= SVE_VQ_MAX before calling this function */
static inline bool vq_available(enum vec_type type, unsigned int vq)
{
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 82e8a6017382..e0af4c3c9a40 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1006,7 +1006,7 @@ int sme_get_current_vl(void)
static void vec_probe_vqs(struct vl_info *info,
DECLARE_BITMAP(map, SVE_VQ_MAX))
{
- unsigned int vq, vl;
+ unsigned int vq, vl, max_vl = 0;
bitmap_zero(map, SVE_VQ_MAX);
@@ -1031,7 +1031,12 @@ static void vec_probe_vqs(struct vl_info *info,
vq = sve_vq_from_vl(vl); /* skip intervening lengths */
set_bit(__vq_to_bit(vq), map);
+
+ if (!max_vl)
+ max_vl = vl;
}
+
+ info->max_system_vl = max((int) max_vl, info->max_system_vl);
}
/*
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 3fc8ca164dbe..6236f9d0a0ec 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -52,7 +52,7 @@ int __init kvm_arm_init_sve(void)
{
if (system_supports_sve()) {
kvm_sve_max_vl = sve_max_virtualisable_vl();
- kvm_host_sve_max_vl = sve_max_vl();
+ kvm_host_sve_max_vl = sve_max_system_vl();
kvm_nvhe_sym(kvm_host_sve_max_vl) = kvm_host_sve_max_vl;
/*
base-commit: afb91f5f8ad7af172d993a34fde1947892408f53
--
2.45.2.505.gda0bf45e8d-goog
More information about the linux-arm-kernel
mailing list