arm-cpu-features.c 25 KB

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