Probe for SVE vector sizes with the same scratch vm that
we use for probing other features.  Remove a separate
initialization path in arm_cpu_sve_finalize.
Unexport kvm_arm_sve_get_vls.

Signed-off-by: Richard Henderson <[email protected]>
---
 target/arm/kvm_arm.h  | 10 ------
 target/arm/cpu64.c    | 20 +-----------
 target/arm/kvm-stub.c |  5 ---
 target/arm/kvm.c      | 73 ++++++++++++++++---------------------------
 4 files changed, 28 insertions(+), 80 deletions(-)

diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index cc0b374254..97549766ea 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -124,16 +124,6 @@ bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
  */
 void kvm_arm_destroy_scratch_host_vcpu(int *fdarray);
 
-/**
- * kvm_arm_sve_get_vls:
- * @cpu: ARMCPU
- *
- * Get all the SVE vector lengths supported by the KVM host, setting
- * the bits corresponding to their length in quadwords minus one
- * (vq - 1) up to ARM_MAX_VQ.  Return the resulting map.
- */
-uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu);
-
 /**
  * kvm_arm_set_cpu_features_from_host:
  * @cpu: ARMCPU to set the features for
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 10c6796548..0116b6cc88 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -79,28 +79,10 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
      */
     uint32_t vq_map = cpu->sve_vq.map;
     uint32_t vq_init = cpu->sve_vq.init;
-    uint32_t vq_supported;
+    uint32_t vq_supported = cpu->sve_vq.supported;
     uint32_t vq_mask = 0;
     uint32_t tmp, vq, max_vq = 0;
 
-    /*
-     * CPU models specify a set of supported vector lengths which are
-     * enabled by default.  Attempting to enable any vector length not set
-     * in the supported bitmap results in an error.  When KVM is enabled we
-     * fetch the supported bitmap from the host.
-     */
-    if (kvm_enabled()) {
-        if (kvm_arm_sve_supported()) {
-            cpu->sve_vq.supported = kvm_arm_sve_get_vls(cpu);
-            vq_supported = cpu->sve_vq.supported;
-        } else {
-            assert(!cpu_isar_feature(aa64_sve, cpu));
-            vq_supported = 0;
-        }
-    } else {
-        vq_supported = cpu->sve_vq.supported;
-    }
-
     /*
      * Process explicit sve<N> properties.
      * From the properties, sve_vq_map<N> implies sve_vq_init<N>.
diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c
index ea67deea52..f2de36aef3 100644
--- a/target/arm/kvm-stub.c
+++ b/target/arm/kvm-stub.c
@@ -95,11 +95,6 @@ void kvm_arm_steal_time_finalize(ARMCPU *cpu, Error **errp)
     g_assert_not_reached();
 }
 
-uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu)
-{
-    g_assert_not_reached();
-}
-
 void kvm_arm_enable_mte(Object *cpuobj, Error **errp)
 {
     g_assert_not_reached();
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index e0fd79b78c..464356989b 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -60,6 +60,7 @@ typedef struct ARMHostCPUFeatures {
     ARMISARegisters isar;
     uint64_t features;
     uint32_t target;
+    uint32_t sve_vq_supported;
     const char *dtb_compatible;
 } ARMHostCPUFeatures;
 
@@ -243,58 +244,34 @@ static int get_host_cpu_reg(int fd, ARMHostCPUFeatures 
*ahcf,
     return ret;
 }
 
-uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu)
+static uint32_t kvm_arm_sve_get_vls(int fd)
 {
     /* Only call this function if kvm_arm_sve_supported() returns true. */
-    static uint64_t vls[KVM_ARM64_SVE_VLS_WORDS];
-    static bool probed;
+    uint64_t vls[KVM_ARM64_SVE_VLS_WORDS];
+    struct kvm_one_reg reg = {
+        .id = KVM_REG_ARM64_SVE_VLS,
+        .addr = (uint64_t)&vls[0],
+    };
     uint32_t vq = 0;
-    int i;
+    int ret;
 
-    /*
-     * KVM ensures all host CPUs support the same set of vector lengths.
-     * So we only need to create the scratch VCPUs once and then cache
-     * the results.
-     */
-    if (!probed) {
-        struct kvm_vcpu_init init = {
-            .target = -1,
-            .features[0] = (1 << KVM_ARM_VCPU_SVE),
-        };
-        struct kvm_one_reg reg = {
-            .id = KVM_REG_ARM64_SVE_VLS,
-            .addr = (uint64_t)&vls[0],
-        };
-        int fdarray[3], ret;
-
-        probed = true;
-
-        if (!kvm_arm_create_scratch_host_vcpu(fdarray, &init)) {
-            error_report("failed to create scratch VCPU with SVE enabled");
-            abort();
-        }
-        ret = ioctl(fdarray[2], KVM_GET_ONE_REG, &reg);
-        kvm_arm_destroy_scratch_host_vcpu(fdarray);
-        if (ret) {
-            error_report("failed to get KVM_REG_ARM64_SVE_VLS: %s",
-                         strerror(errno));
-            abort();
-        }
-
-        for (i = KVM_ARM64_SVE_VLS_WORDS - 1; i >= 0; --i) {
-            if (vls[i]) {
-                vq = 64 - clz64(vls[i]) + i * 64;
-                break;
-            }
-        }
-        if (vq > ARM_MAX_VQ) {
-            warn_report("KVM supports vector lengths larger than "
-                        "QEMU can enable");
-            vls[0] &= MAKE_64BIT_MASK(0, ARM_MAX_VQ);
-        }
+    ret = ioctl(fd, KVM_GET_ONE_REG, &reg);
+    if (ret) {
+        error_report("failed to get KVM_REG_ARM64_SVE_VLS: %s",
+                     strerror(errno));
+        abort();
     }
 
-    return vls[0];
+    for (int i = KVM_ARM64_SVE_VLS_WORDS - 1; i >= 0; --i) {
+        if (vls[i]) {
+            vq = 64 - clz64(vls[i]) + i * 64;
+            break;
+        }
+    }
+    if (vq > ARM_MAX_VQ) {
+        warn_report("KVM supports vector lengths larger than QEMU can enable");
+    }
+    return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ);
 }
 
 static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
@@ -469,6 +446,9 @@ static bool 
kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
              * So only read the register if we set KVM_ARM_VCPU_SVE above.
              */
             err |= get_host_cpu_reg(fd, ahcf, ID_AA64ZFR0_EL1_IDX);
+
+            /* Read the set of supported vector lengths. */
+            arm_host_cpu_features.sve_vq_supported = kvm_arm_sve_get_vls(fd);
         }
     }
 
@@ -516,6 +496,7 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
     cpu->kvm_target = arm_host_cpu_features.target;
     cpu->dtb_compatible = arm_host_cpu_features.dtb_compatible;
     cpu->isar = arm_host_cpu_features.isar;
+    cpu->sve_vq.supported = arm_host_cpu_features.sve_vq_supported;
     env->features = arm_host_cpu_features.features;
 }
 
-- 
2.43.0


Reply via email to