arm-cpu-features.c 23 KB

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