static int default_sme_vl;
 
+static int sve_vl_count;
+static unsigned int sve_vls[SVE_VQ_MAX];
+static int sme_vl_count;
+static unsigned int sme_vls[SVE_VQ_MAX];
+
 extern void do_syscall(int sve_vl, int sme_vl);
 
 static void fill_random(void *buf, size_t size)
 
 static void test_one_syscall(struct syscall_cfg *cfg)
 {
-       int sve_vq, sve_vl;
-       int sme_vq, sme_vl;
+       int sve, sme;
+       int ret;
 
        /* FPSIMD only case */
        ksft_test_result(do_test(cfg, 0, default_sme_vl, 0),
                         "%s FPSIMD\n", cfg->name);
 
-       if (!(getauxval(AT_HWCAP) & HWCAP_SVE))
-               return;
-
-       for (sve_vq = SVE_VQ_MAX; sve_vq > 0; --sve_vq) {
-               sve_vl = prctl(PR_SVE_SET_VL, sve_vq * 16);
-               if (sve_vl == -1)
+       for (sve = 0; sve < sve_vl_count; sve++) {
+               ret = prctl(PR_SVE_SET_VL, sve_vls[sve]);
+               if (ret == -1)
                        ksft_exit_fail_msg("PR_SVE_SET_VL failed: %s (%d)\n",
                                           strerror(errno), errno);
 
-               sve_vl &= PR_SVE_VL_LEN_MASK;
-
-               if (sve_vq != sve_vq_from_vl(sve_vl))
-                       sve_vq = sve_vq_from_vl(sve_vl);
+               ksft_test_result(do_test(cfg, sve_vls[sve], default_sme_vl, 0),
+                                "%s SVE VL %d\n", cfg->name, sve_vls[sve]);
 
-               ksft_test_result(do_test(cfg, sve_vl, default_sme_vl, 0),
-                                "%s SVE VL %d\n", cfg->name, sve_vl);
-
-               if (!(getauxval(AT_HWCAP2) & HWCAP2_SME))
-                       continue;
-
-               for (sme_vq = SVE_VQ_MAX; sme_vq > 0; --sme_vq) {
-                       sme_vl = prctl(PR_SME_SET_VL, sme_vq * 16);
-                       if (sme_vl == -1)
+               for (sme = 0; sme < sme_vl_count; sme++) {
+                       ret = prctl(PR_SME_SET_VL, sme_vls[sme]);
+                       if (ret == -1)
                                ksft_exit_fail_msg("PR_SME_SET_VL failed: %s (%d)\n",
                                                   strerror(errno), errno);
 
-                       sme_vl &= PR_SME_VL_LEN_MASK;
-
-                       /* Found lowest VL */
-                       if (sve_vq_from_vl(sme_vl) > sme_vq)
-                               break;
-
-                       if (sme_vq != sve_vq_from_vl(sme_vl))
-                               sme_vq = sve_vq_from_vl(sme_vl);
-
-                       ksft_test_result(do_test(cfg, sve_vl, sme_vl,
+                       ksft_test_result(do_test(cfg, sve_vls[sve],
+                                                sme_vls[sme],
                                                 SVCR_ZA_MASK | SVCR_SM_MASK),
                                         "%s SVE VL %d/SME VL %d SM+ZA\n",
-                                        cfg->name, sve_vl, sme_vl);
-                       ksft_test_result(do_test(cfg, sve_vl, sme_vl,
-                                                SVCR_SM_MASK),
+                                        cfg->name, sve_vls[sve],
+                                        sme_vls[sme]);
+                       ksft_test_result(do_test(cfg, sve_vls[sve],
+                                                sme_vls[sme], SVCR_SM_MASK),
                                         "%s SVE VL %d/SME VL %d SM\n",
-                                        cfg->name, sve_vl, sme_vl);
-                       ksft_test_result(do_test(cfg, sve_vl, sme_vl,
-                                                SVCR_ZA_MASK),
+                                        cfg->name, sve_vls[sve],
+                                        sme_vls[sme]);
+                       ksft_test_result(do_test(cfg, sve_vls[sve],
+                                                sme_vls[sme], SVCR_ZA_MASK),
                                         "%s SVE VL %d/SME VL %d ZA\n",
-                                        cfg->name, sve_vl, sme_vl);
+                                        cfg->name, sve_vls[sve],
+                                        sme_vls[sme]);
                }
        }
 }
 
-int sve_count_vls(void)
+void sve_count_vls(void)
 {
        unsigned int vq;
-       int vl_count = 0;
        int vl;
 
        if (!(getauxval(AT_HWCAP) & HWCAP_SVE))
-               return 0;
+               return;
 
        /*
         * Enumerate up to SVE_VQ_MAX vector lengths
                if (vq != sve_vq_from_vl(vl))
                        vq = sve_vq_from_vl(vl);
 
-               vl_count++;
+               sve_vls[sve_vl_count++] = vl;
        }
-
-       return vl_count;
 }
 
-int sme_count_vls(void)
+void sme_count_vls(void)
 {
        unsigned int vq;
-       int vl_count = 0;
        int vl;
 
        if (!(getauxval(AT_HWCAP2) & HWCAP2_SME))
-               return 0;
-
-       /* Ensure we configure a SME VL, used to flag if SVCR is set */
-       default_sme_vl = 16;
+               return;
 
        /*
         * Enumerate up to SVE_VQ_MAX vector lengths
                if (vq != sve_vq_from_vl(vl))
                        vq = sve_vq_from_vl(vl);
 
-               vl_count++;
+               sme_vls[sme_vl_count++] = vl;
        }
 
-       return vl_count;
+       /* Ensure we configure a SME VL, used to flag if SVCR is set */
+       default_sme_vl = sme_vls[0];
 }
 
 int main(void)
        srandom(getpid());
 
        ksft_print_header();
-       tests += sve_count_vls();
-       tests += (sve_count_vls() * sme_count_vls()) * 3;
+
+       sve_count_vls();
+       sme_count_vls();
+
+       tests += sve_vl_count;
+       tests += (sve_vl_count * sme_vl_count) * 3;
        ksft_set_plan(ARRAY_SIZE(syscalls) * tests);
 
        if (getauxval(AT_HWCAP2) & HWCAP2_SME_FA64)