xref: /openbmc/qemu/tests/qtest/arm-cpu-features.c (revision 6016b7b4)
1 /*
2  * Arm CPU feature test cases
3  *
4  * Copyright (c) 2019 Red Hat Inc.
5  * Authors:
6  *  Andrew Jones <drjones@redhat.com>
7  *
8  * This work is licensed under the terms of the GNU GPL, version 2 or later.
9  * See the COPYING file in the top-level directory.
10  */
11 #include "qemu/osdep.h"
12 #include "qemu/bitops.h"
13 #include "libqos/libqtest.h"
14 #include "qapi/qmp/qdict.h"
15 #include "qapi/qmp/qjson.h"
16 
17 /*
18  * We expect the SVE max-vq to be 16. Also it must be <= 64
19  * for our test code, otherwise 'vls' can't just be a uint64_t.
20  */
21 #define SVE_MAX_VQ 16
22 
23 #define MACHINE     "-machine virt,gic-version=max -accel tcg "
24 #define MACHINE_KVM "-machine virt,gic-version=max -accel kvm -accel tcg "
25 #define QUERY_HEAD  "{ 'execute': 'query-cpu-model-expansion', " \
26                     "  'arguments': { 'type': 'full', "
27 #define QUERY_TAIL  "}}"
28 
29 static QDict *do_query_no_props(QTestState *qts, const char *cpu_type)
30 {
31     return qtest_qmp(qts, QUERY_HEAD "'model': { 'name': %s }"
32                           QUERY_TAIL, cpu_type);
33 }
34 
35 static QDict *do_query(QTestState *qts, const char *cpu_type,
36                        const char *fmt, ...)
37 {
38     QDict *resp;
39 
40     if (fmt) {
41         QDict *args;
42         va_list ap;
43 
44         va_start(ap, fmt);
45         args = qdict_from_vjsonf_nofail(fmt, ap);
46         va_end(ap);
47 
48         resp = qtest_qmp(qts, QUERY_HEAD "'model': { 'name': %s, "
49                                                     "'props': %p }"
50                               QUERY_TAIL, cpu_type, args);
51     } else {
52         resp = do_query_no_props(qts, cpu_type);
53     }
54 
55     return resp;
56 }
57 
58 static const char *resp_get_error(QDict *resp)
59 {
60     QDict *qdict;
61 
62     g_assert(resp);
63 
64     qdict = qdict_get_qdict(resp, "error");
65     if (qdict) {
66         return qdict_get_str(qdict, "desc");
67     }
68 
69     return NULL;
70 }
71 
72 #define assert_error(qts, cpu_type, expected_error, fmt, ...)          \
73 ({                                                                     \
74     QDict *_resp;                                                      \
75     const char *_error;                                                \
76                                                                        \
77     _resp = do_query(qts, cpu_type, fmt, ##__VA_ARGS__);               \
78     g_assert(_resp);                                                   \
79     _error = resp_get_error(_resp);                                    \
80     g_assert(_error);                                                  \
81     g_assert(g_str_equal(_error, expected_error));                     \
82     qobject_unref(_resp);                                              \
83 })
84 
85 static bool resp_has_props(QDict *resp)
86 {
87     QDict *qdict;
88 
89     g_assert(resp);
90 
91     if (!qdict_haskey(resp, "return")) {
92         return false;
93     }
94     qdict = qdict_get_qdict(resp, "return");
95 
96     if (!qdict_haskey(qdict, "model")) {
97         return false;
98     }
99     qdict = qdict_get_qdict(qdict, "model");
100 
101     return qdict_haskey(qdict, "props");
102 }
103 
104 static QDict *resp_get_props(QDict *resp)
105 {
106     QDict *qdict;
107 
108     g_assert(resp);
109     g_assert(resp_has_props(resp));
110 
111     qdict = qdict_get_qdict(resp, "return");
112     qdict = qdict_get_qdict(qdict, "model");
113     qdict = qdict_get_qdict(qdict, "props");
114 
115     return qdict;
116 }
117 
118 static bool resp_get_feature(QDict *resp, const char *feature)
119 {
120     QDict *props;
121 
122     g_assert(resp);
123     g_assert(resp_has_props(resp));
124     props = resp_get_props(resp);
125     g_assert(qdict_get(props, feature));
126     return qdict_get_bool(props, feature);
127 }
128 
129 #define assert_has_feature(qts, cpu_type, feature)                     \
130 ({                                                                     \
131     QDict *_resp = do_query_no_props(qts, cpu_type);                   \
132     g_assert(_resp);                                                   \
133     g_assert(resp_has_props(_resp));                                   \
134     g_assert(qdict_get(resp_get_props(_resp), feature));               \
135     qobject_unref(_resp);                                              \
136 })
137 
138 #define assert_has_not_feature(qts, cpu_type, feature)                 \
139 ({                                                                     \
140     QDict *_resp = do_query_no_props(qts, cpu_type);                   \
141     g_assert(_resp);                                                   \
142     g_assert(!resp_has_props(_resp) ||                                 \
143              !qdict_get(resp_get_props(_resp), feature));              \
144     qobject_unref(_resp);                                              \
145 })
146 
147 #define resp_assert_feature(resp, feature, expected_value)             \
148 ({                                                                     \
149     QDict *_props;                                                     \
150                                                                        \
151     g_assert(_resp);                                                   \
152     g_assert(resp_has_props(_resp));                                   \
153     _props = resp_get_props(_resp);                                    \
154     g_assert(qdict_get(_props, feature));                              \
155     g_assert(qdict_get_bool(_props, feature) == (expected_value));     \
156 })
157 
158 #define assert_feature(qts, cpu_type, feature, expected_value)         \
159 ({                                                                     \
160     QDict *_resp;                                                      \
161                                                                        \
162     _resp = do_query_no_props(qts, cpu_type);                          \
163     g_assert(_resp);                                                   \
164     resp_assert_feature(_resp, feature, expected_value);               \
165     qobject_unref(_resp);                                              \
166 })
167 
168 #define assert_set_feature(qts, cpu_type, feature, value)              \
169 ({                                                                     \
170     const char *_fmt = (value) ? "{ %s: true }" : "{ %s: false }";     \
171     QDict *_resp;                                                      \
172                                                                        \
173     _resp = do_query(qts, cpu_type, _fmt, feature);                    \
174     g_assert(_resp);                                                   \
175     resp_assert_feature(_resp, feature, value);                        \
176     qobject_unref(_resp);                                              \
177 })
178 
179 #define assert_has_feature_enabled(qts, cpu_type, feature)             \
180     assert_feature(qts, cpu_type, feature, true)
181 
182 #define assert_has_feature_disabled(qts, cpu_type, feature)            \
183     assert_feature(qts, cpu_type, feature, false)
184 
185 static void assert_type_full(QTestState *qts)
186 {
187     const char *error;
188     QDict *resp;
189 
190     resp = qtest_qmp(qts, "{ 'execute': 'query-cpu-model-expansion', "
191                             "'arguments': { 'type': 'static', "
192                                            "'model': { 'name': 'foo' }}}");
193     g_assert(resp);
194     error = resp_get_error(resp);
195     g_assert(error);
196     g_assert(g_str_equal(error,
197                          "The requested expansion type is not supported"));
198     qobject_unref(resp);
199 }
200 
201 static void assert_bad_props(QTestState *qts, const char *cpu_type)
202 {
203     const char *error;
204     QDict *resp;
205 
206     resp = qtest_qmp(qts, "{ 'execute': 'query-cpu-model-expansion', "
207                             "'arguments': { 'type': 'full', "
208                                            "'model': { 'name': %s, "
209                                                       "'props': false }}}",
210                      cpu_type);
211     g_assert(resp);
212     error = resp_get_error(resp);
213     g_assert(error);
214     g_assert(g_str_equal(error,
215                          "Invalid parameter type for 'props', expected: dict"));
216     qobject_unref(resp);
217 }
218 
219 static uint64_t resp_get_sve_vls(QDict *resp)
220 {
221     QDict *props;
222     const QDictEntry *e;
223     uint64_t vls = 0;
224     int n = 0;
225 
226     g_assert(resp);
227     g_assert(resp_has_props(resp));
228 
229     props = resp_get_props(resp);
230 
231     for (e = qdict_first(props); e; e = qdict_next(props, e)) {
232         if (strlen(e->key) > 3 && !strncmp(e->key, "sve", 3) &&
233             g_ascii_isdigit(e->key[3])) {
234             char *endptr;
235             int bits;
236 
237             bits = g_ascii_strtoll(&e->key[3], &endptr, 10);
238             if (!bits || *endptr != '\0') {
239                 continue;
240             }
241 
242             if (qdict_get_bool(props, e->key)) {
243                 vls |= BIT_ULL((bits / 128) - 1);
244             }
245             ++n;
246         }
247     }
248 
249     g_assert(n == SVE_MAX_VQ);
250 
251     return vls;
252 }
253 
254 #define assert_sve_vls(qts, cpu_type, expected_vls, fmt, ...)          \
255 ({                                                                     \
256     QDict *_resp = do_query(qts, cpu_type, fmt, ##__VA_ARGS__);        \
257     g_assert(_resp);                                                   \
258     g_assert(resp_has_props(_resp));                                   \
259     g_assert(resp_get_sve_vls(_resp) == expected_vls);                 \
260     qobject_unref(_resp);                                              \
261 })
262 
263 static void sve_tests_default(QTestState *qts, const char *cpu_type)
264 {
265     /*
266      * With no sve-max-vq or sve<N> properties on the command line
267      * the default is to have all vector lengths enabled. This also
268      * tests that 'sve' is 'on' by default.
269      */
270     assert_sve_vls(qts, cpu_type, BIT_ULL(SVE_MAX_VQ) - 1, NULL);
271 
272     /* With SVE off, all vector lengths should also be off. */
273     assert_sve_vls(qts, cpu_type, 0, "{ 'sve': false }");
274 
275     /* With SVE on, we must have at least one vector length enabled. */
276     assert_error(qts, cpu_type, "cannot disable sve128", "{ 'sve128': false }");
277 
278     /* Basic enable/disable tests. */
279     assert_sve_vls(qts, cpu_type, 0x7, "{ 'sve384': true }");
280     assert_sve_vls(qts, cpu_type, ((BIT_ULL(SVE_MAX_VQ) - 1) & ~BIT_ULL(2)),
281                    "{ 'sve384': false }");
282 
283     /*
284      * ---------------------------------------------------------------------
285      *               power-of-two(vq)   all-power-            can      can
286      *                                  of-two(< vq)        enable   disable
287      * ---------------------------------------------------------------------
288      * vq < max_vq      no                MUST*              yes      yes
289      * vq < max_vq      yes               MUST*              yes      no
290      * ---------------------------------------------------------------------
291      * vq == max_vq     n/a               MUST*              yes**    yes**
292      * ---------------------------------------------------------------------
293      * vq > max_vq      n/a               no                 no       yes
294      * vq > max_vq      n/a               yes                yes      yes
295      * ---------------------------------------------------------------------
296      *
297      * [*] "MUST" means this requirement must already be satisfied,
298      *     otherwise 'max_vq' couldn't itself be enabled.
299      *
300      * [**] Not testable with the QMP interface, only with the command line.
301      */
302 
303     /* max_vq := 8 */
304     assert_sve_vls(qts, cpu_type, 0x8b, "{ 'sve1024': true }");
305 
306     /* max_vq := 8, vq < max_vq, !power-of-two(vq) */
307     assert_sve_vls(qts, cpu_type, 0x8f,
308                    "{ 'sve1024': true, 'sve384': true }");
309     assert_sve_vls(qts, cpu_type, 0x8b,
310                    "{ 'sve1024': true, 'sve384': false }");
311 
312     /* max_vq := 8, vq < max_vq, power-of-two(vq) */
313     assert_sve_vls(qts, cpu_type, 0x8b,
314                    "{ 'sve1024': true, 'sve256': true }");
315     assert_error(qts, cpu_type, "cannot disable sve256",
316                  "{ 'sve1024': true, 'sve256': false }");
317 
318     /* max_vq := 3, vq > max_vq, !all-power-of-two(< vq) */
319     assert_error(qts, cpu_type, "cannot disable sve512",
320                  "{ 'sve384': true, 'sve512': false, 'sve640': true }");
321 
322     /*
323      * We can disable power-of-two vector lengths when all larger lengths
324      * are also disabled. We only need to disable the power-of-two length,
325      * as all non-enabled larger lengths will then be auto-disabled.
326      */
327     assert_sve_vls(qts, cpu_type, 0x7, "{ 'sve512': false }");
328 
329     /* max_vq := 3, vq > max_vq, all-power-of-two(< vq) */
330     assert_sve_vls(qts, cpu_type, 0x1f,
331                    "{ 'sve384': true, 'sve512': true, 'sve640': true }");
332     assert_sve_vls(qts, cpu_type, 0xf,
333                    "{ 'sve384': true, 'sve512': true, 'sve640': false }");
334 }
335 
336 static void sve_tests_sve_max_vq_8(const void *data)
337 {
338     QTestState *qts;
339 
340     qts = qtest_init(MACHINE "-cpu max,sve-max-vq=8");
341 
342     assert_sve_vls(qts, "max", BIT_ULL(8) - 1, NULL);
343 
344     /*
345      * Disabling the max-vq set by sve-max-vq is not allowed, but
346      * of course enabling it is OK.
347      */
348     assert_error(qts, "max", "cannot disable sve1024", "{ 'sve1024': false }");
349     assert_sve_vls(qts, "max", 0xff, "{ 'sve1024': true }");
350 
351     /*
352      * Enabling anything larger than max-vq set by sve-max-vq is not
353      * allowed, but of course disabling everything larger is OK.
354      */
355     assert_error(qts, "max", "cannot enable sve1152", "{ 'sve1152': true }");
356     assert_sve_vls(qts, "max", 0xff, "{ 'sve1152': false }");
357 
358     /*
359      * We can enable/disable non power-of-two lengths smaller than the
360      * max-vq set by sve-max-vq, but, while we can enable power-of-two
361      * lengths, we can't disable them.
362      */
363     assert_sve_vls(qts, "max", 0xff, "{ 'sve384': true }");
364     assert_sve_vls(qts, "max", 0xfb, "{ 'sve384': false }");
365     assert_sve_vls(qts, "max", 0xff, "{ 'sve256': true }");
366     assert_error(qts, "max", "cannot disable sve256", "{ 'sve256': false }");
367 
368     qtest_quit(qts);
369 }
370 
371 static void sve_tests_sve_off(const void *data)
372 {
373     QTestState *qts;
374 
375     qts = qtest_init(MACHINE "-cpu max,sve=off");
376 
377     /* SVE is off, so the map should be empty. */
378     assert_sve_vls(qts, "max", 0, NULL);
379 
380     /* The map stays empty even if we turn lengths off. */
381     assert_sve_vls(qts, "max", 0, "{ 'sve128': false }");
382 
383     /* It's an error to enable lengths when SVE is off. */
384     assert_error(qts, "max", "cannot enable sve128", "{ 'sve128': true }");
385 
386     /* With SVE re-enabled we should get all vector lengths enabled. */
387     assert_sve_vls(qts, "max", BIT_ULL(SVE_MAX_VQ) - 1, "{ 'sve': true }");
388 
389     /* Or enable SVE with just specific vector lengths. */
390     assert_sve_vls(qts, "max", 0x3,
391                    "{ 'sve': true, 'sve128': true, 'sve256': true }");
392 
393     qtest_quit(qts);
394 }
395 
396 static void sve_tests_sve_off_kvm(const void *data)
397 {
398     QTestState *qts;
399 
400     qts = qtest_init(MACHINE_KVM "-cpu max,sve=off");
401 
402     /*
403      * We don't know if this host supports SVE so we don't
404      * attempt to test enabling anything. We only test that
405      * everything is disabled (as it should be with sve=off)
406      * and that using sve<N>=off to explicitly disable vector
407      * lengths is OK too.
408      */
409     assert_sve_vls(qts, "max", 0, NULL);
410     assert_sve_vls(qts, "max", 0, "{ 'sve128': false }");
411 
412     qtest_quit(qts);
413 }
414 
415 static void pauth_tests_default(QTestState *qts, const char *cpu_type)
416 {
417     assert_has_feature_enabled(qts, cpu_type, "pauth");
418     assert_has_feature_disabled(qts, cpu_type, "pauth-impdef");
419     assert_set_feature(qts, cpu_type, "pauth", false);
420     assert_set_feature(qts, cpu_type, "pauth", true);
421     assert_set_feature(qts, cpu_type, "pauth-impdef", true);
422     assert_set_feature(qts, cpu_type, "pauth-impdef", false);
423     assert_error(qts, cpu_type, "cannot enable pauth-impdef without pauth",
424                  "{ 'pauth': false, 'pauth-impdef': true }");
425 }
426 
427 static void test_query_cpu_model_expansion(const void *data)
428 {
429     QTestState *qts;
430 
431     qts = qtest_init(MACHINE "-cpu max");
432 
433     /* Test common query-cpu-model-expansion input validation */
434     assert_type_full(qts);
435     assert_bad_props(qts, "max");
436     assert_error(qts, "foo", "The CPU type 'foo' is not a recognized "
437                  "ARM CPU type", NULL);
438     assert_error(qts, "max", "Parameter 'not-a-prop' is unexpected",
439                  "{ 'not-a-prop': false }");
440     assert_error(qts, "host", "The CPU type 'host' requires KVM", NULL);
441 
442     /* Test expected feature presence/absence for some cpu types */
443     assert_has_feature_enabled(qts, "cortex-a15", "pmu");
444     assert_has_not_feature(qts, "cortex-a15", "aarch64");
445 
446     /* Enabling and disabling pmu should always work. */
447     assert_has_feature_enabled(qts, "max", "pmu");
448     assert_set_feature(qts, "max", "pmu", false);
449     assert_set_feature(qts, "max", "pmu", true);
450 
451     assert_has_not_feature(qts, "max", "kvm-no-adjvtime");
452     assert_has_not_feature(qts, "max", "kvm-steal-time");
453 
454     if (g_str_equal(qtest_get_arch(), "aarch64")) {
455         assert_has_feature_enabled(qts, "max", "aarch64");
456         assert_has_feature_enabled(qts, "max", "sve");
457         assert_has_feature_enabled(qts, "max", "sve128");
458         assert_has_feature_enabled(qts, "cortex-a57", "pmu");
459         assert_has_feature_enabled(qts, "cortex-a57", "aarch64");
460 
461         assert_has_feature_enabled(qts, "a64fx", "pmu");
462         assert_has_feature_enabled(qts, "a64fx", "aarch64");
463         /*
464          * A64FX does not support any other vector lengths besides those
465          * that are enabled by default(128bit, 256bits, 512bit).
466          */
467         assert_has_feature_enabled(qts, "a64fx", "sve");
468         assert_sve_vls(qts, "a64fx", 0xb, NULL);
469         assert_error(qts, "a64fx", "cannot enable sve384",
470                      "{ 'sve384': true }");
471         assert_error(qts, "a64fx", "cannot enable sve640",
472                      "{ 'sve640': true }");
473 
474         sve_tests_default(qts, "max");
475         pauth_tests_default(qts, "max");
476 
477         /* Test that features that depend on KVM generate errors without. */
478         assert_error(qts, "max",
479                      "'aarch64' feature cannot be disabled "
480                      "unless KVM is enabled and 32-bit EL1 "
481                      "is supported",
482                      "{ 'aarch64': false }");
483     }
484 
485     qtest_quit(qts);
486 }
487 
488 static void test_query_cpu_model_expansion_kvm(const void *data)
489 {
490     QTestState *qts;
491 
492     qts = qtest_init(MACHINE_KVM "-cpu max");
493 
494     /* Enabling and disabling kvm-no-adjvtime should always work. */
495     assert_has_feature_disabled(qts, "host", "kvm-no-adjvtime");
496     assert_set_feature(qts, "host", "kvm-no-adjvtime", true);
497     assert_set_feature(qts, "host", "kvm-no-adjvtime", false);
498 
499     if (g_str_equal(qtest_get_arch(), "aarch64")) {
500         bool kvm_supports_steal_time;
501         bool kvm_supports_sve;
502         char max_name[8], name[8];
503         uint32_t max_vq, vq;
504         uint64_t vls;
505         QDict *resp;
506         char *error;
507 
508         assert_error(qts, "cortex-a15",
509             "We cannot guarantee the CPU type 'cortex-a15' works "
510             "with KVM on this host", NULL);
511 
512         assert_has_feature_enabled(qts, "host", "aarch64");
513 
514         /* Enabling and disabling pmu should always work. */
515         assert_has_feature_enabled(qts, "host", "pmu");
516         assert_set_feature(qts, "host", "pmu", false);
517         assert_set_feature(qts, "host", "pmu", true);
518 
519         /*
520          * Some features would be enabled by default, but they're disabled
521          * because this instance of KVM doesn't support them. Test that the
522          * features are present, and, when enabled, issue further tests.
523          */
524         assert_has_feature(qts, "host", "kvm-steal-time");
525         assert_has_feature(qts, "host", "sve");
526 
527         resp = do_query_no_props(qts, "host");
528         kvm_supports_steal_time = resp_get_feature(resp, "kvm-steal-time");
529         kvm_supports_sve = resp_get_feature(resp, "sve");
530         vls = resp_get_sve_vls(resp);
531         qobject_unref(resp);
532 
533         if (kvm_supports_steal_time) {
534             /* If we have steal-time then we should be able to toggle it. */
535             assert_set_feature(qts, "host", "kvm-steal-time", false);
536             assert_set_feature(qts, "host", "kvm-steal-time", true);
537         }
538 
539         if (kvm_supports_sve) {
540             g_assert(vls != 0);
541             max_vq = 64 - __builtin_clzll(vls);
542             sprintf(max_name, "sve%u", max_vq * 128);
543 
544             /* Enabling a supported length is of course fine. */
545             assert_sve_vls(qts, "host", vls, "{ %s: true }", max_name);
546 
547             /* Get the next supported length smaller than max-vq. */
548             vq = 64 - __builtin_clzll(vls & ~BIT_ULL(max_vq - 1));
549             if (vq) {
550                 /*
551                  * We have at least one length smaller than max-vq,
552                  * so we can disable max-vq.
553                  */
554                 assert_sve_vls(qts, "host", (vls & ~BIT_ULL(max_vq - 1)),
555                                "{ %s: false }", max_name);
556 
557                 /*
558                  * Smaller, supported vector lengths cannot be disabled
559                  * unless all larger, supported vector lengths are also
560                  * disabled.
561                  */
562                 sprintf(name, "sve%u", vq * 128);
563                 error = g_strdup_printf("cannot disable %s", name);
564                 assert_error(qts, "host", error,
565                              "{ %s: true, %s: false }",
566                              max_name, name);
567                 g_free(error);
568             }
569 
570             /*
571              * The smallest, supported vector length is required, because
572              * we need at least one vector length enabled.
573              */
574             vq = __builtin_ffsll(vls);
575             sprintf(name, "sve%u", vq * 128);
576             error = g_strdup_printf("cannot disable %s", name);
577             assert_error(qts, "host", error, "{ %s: false }", name);
578             g_free(error);
579 
580             /* Get an unsupported length. */
581             for (vq = 1; vq <= max_vq; ++vq) {
582                 if (!(vls & BIT_ULL(vq - 1))) {
583                     break;
584                 }
585             }
586             if (vq <= SVE_MAX_VQ) {
587                 sprintf(name, "sve%u", vq * 128);
588                 error = g_strdup_printf("cannot enable %s", name);
589                 assert_error(qts, "host", error, "{ %s: true }", name);
590                 g_free(error);
591             }
592         } else {
593             g_assert(vls == 0);
594         }
595     } else {
596         assert_has_not_feature(qts, "host", "aarch64");
597         assert_has_not_feature(qts, "host", "pmu");
598         assert_has_not_feature(qts, "host", "sve");
599         assert_has_not_feature(qts, "host", "kvm-steal-time");
600     }
601 
602     qtest_quit(qts);
603 }
604 
605 int main(int argc, char **argv)
606 {
607     g_test_init(&argc, &argv, NULL);
608 
609     qtest_add_data_func("/arm/query-cpu-model-expansion",
610                         NULL, test_query_cpu_model_expansion);
611 
612     /*
613      * For now we only run KVM specific tests with AArch64 QEMU in
614      * order avoid attempting to run an AArch32 QEMU with KVM on
615      * AArch64 hosts. That won't work and isn't easy to detect.
616      */
617     if (g_str_equal(qtest_get_arch(), "aarch64") && qtest_has_accel("kvm")) {
618         /*
619          * This tests target the 'host' CPU type, so register it only if
620          * KVM is available.
621          */
622         qtest_add_data_func("/arm/kvm/query-cpu-model-expansion",
623                             NULL, test_query_cpu_model_expansion_kvm);
624     }
625 
626     if (g_str_equal(qtest_get_arch(), "aarch64")) {
627         qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-max-vq-8",
628                             NULL, sve_tests_sve_max_vq_8);
629         qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-off",
630                             NULL, sve_tests_sve_off);
631         qtest_add_data_func("/arm/kvm/query-cpu-model-expansion/sve-off",
632                             NULL, sve_tests_sve_off_kvm);
633     }
634 
635     return g_test_run();
636 }
637