test-guest-state-buffer.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. #include <linux/init.h>
  3. #include <linux/log2.h>
  4. #include <kunit/test.h>
  5. #include <asm/guest-state-buffer.h>
  6. #include <asm/kvm_ppc.h>
  7. static void test_creating_buffer(struct kunit *test)
  8. {
  9. struct kvmppc_gs_buff *gsb;
  10. size_t size = 0x100;
  11. gsb = kvmppc_gsb_new(size, 0, 0, GFP_KERNEL);
  12. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gsb);
  13. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gsb->hdr);
  14. KUNIT_EXPECT_EQ(test, gsb->capacity, roundup_pow_of_two(size));
  15. KUNIT_EXPECT_EQ(test, gsb->len, sizeof(__be32));
  16. kvmppc_gsb_free(gsb);
  17. }
  18. static void test_adding_element(struct kunit *test)
  19. {
  20. const struct kvmppc_gs_elem *head, *curr;
  21. union {
  22. __vector128 v;
  23. u64 dw[2];
  24. } u;
  25. int rem;
  26. struct kvmppc_gs_buff *gsb;
  27. size_t size = 0x1000;
  28. int i, rc;
  29. u64 data;
  30. gsb = kvmppc_gsb_new(size, 0, 0, GFP_KERNEL);
  31. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gsb);
  32. /* Single elements, direct use of __kvmppc_gse_put() */
  33. data = 0xdeadbeef;
  34. rc = __kvmppc_gse_put(gsb, KVMPPC_GSID_GPR(0), 8, &data);
  35. KUNIT_EXPECT_GE(test, rc, 0);
  36. head = kvmppc_gsb_data(gsb);
  37. KUNIT_EXPECT_EQ(test, kvmppc_gse_iden(head), KVMPPC_GSID_GPR(0));
  38. KUNIT_EXPECT_EQ(test, kvmppc_gse_len(head), 8);
  39. data = 0;
  40. memcpy(&data, kvmppc_gse_data(head), 8);
  41. KUNIT_EXPECT_EQ(test, data, 0xdeadbeef);
  42. /* Multiple elements, simple wrapper */
  43. rc = kvmppc_gse_put_u64(gsb, KVMPPC_GSID_GPR(1), 0xcafef00d);
  44. KUNIT_EXPECT_GE(test, rc, 0);
  45. u.dw[0] = 0x1;
  46. u.dw[1] = 0x2;
  47. rc = kvmppc_gse_put_vector128(gsb, KVMPPC_GSID_VSRS(0), &u.v);
  48. KUNIT_EXPECT_GE(test, rc, 0);
  49. u.dw[0] = 0x0;
  50. u.dw[1] = 0x0;
  51. kvmppc_gsb_for_each_elem(i, curr, gsb, rem) {
  52. switch (i) {
  53. case 0:
  54. KUNIT_EXPECT_EQ(test, kvmppc_gse_iden(curr),
  55. KVMPPC_GSID_GPR(0));
  56. KUNIT_EXPECT_EQ(test, kvmppc_gse_len(curr), 8);
  57. KUNIT_EXPECT_EQ(test, kvmppc_gse_get_be64(curr),
  58. 0xdeadbeef);
  59. break;
  60. case 1:
  61. KUNIT_EXPECT_EQ(test, kvmppc_gse_iden(curr),
  62. KVMPPC_GSID_GPR(1));
  63. KUNIT_EXPECT_EQ(test, kvmppc_gse_len(curr), 8);
  64. KUNIT_EXPECT_EQ(test, kvmppc_gse_get_u64(curr),
  65. 0xcafef00d);
  66. break;
  67. case 2:
  68. KUNIT_EXPECT_EQ(test, kvmppc_gse_iden(curr),
  69. KVMPPC_GSID_VSRS(0));
  70. KUNIT_EXPECT_EQ(test, kvmppc_gse_len(curr), 16);
  71. kvmppc_gse_get_vector128(curr, &u.v);
  72. KUNIT_EXPECT_EQ(test, u.dw[0], 0x1);
  73. KUNIT_EXPECT_EQ(test, u.dw[1], 0x2);
  74. break;
  75. }
  76. }
  77. KUNIT_EXPECT_EQ(test, i, 3);
  78. kvmppc_gsb_reset(gsb);
  79. KUNIT_EXPECT_EQ(test, kvmppc_gsb_nelems(gsb), 0);
  80. KUNIT_EXPECT_EQ(test, kvmppc_gsb_len(gsb),
  81. sizeof(struct kvmppc_gs_header));
  82. kvmppc_gsb_free(gsb);
  83. }
  84. static void test_gs_parsing(struct kunit *test)
  85. {
  86. struct kvmppc_gs_elem *gse;
  87. struct kvmppc_gs_parser gsp = { 0 };
  88. struct kvmppc_gs_buff *gsb;
  89. size_t size = 0x1000;
  90. u64 tmp1, tmp2;
  91. gsb = kvmppc_gsb_new(size, 0, 0, GFP_KERNEL);
  92. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gsb);
  93. tmp1 = 0xdeadbeefull;
  94. kvmppc_gse_put_u64(gsb, KVMPPC_GSID_GPR(0), tmp1);
  95. KUNIT_EXPECT_GE(test, kvmppc_gse_parse(&gsp, gsb), 0);
  96. gse = kvmppc_gsp_lookup(&gsp, KVMPPC_GSID_GPR(0));
  97. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gse);
  98. tmp2 = kvmppc_gse_get_u64(gse);
  99. KUNIT_EXPECT_EQ(test, tmp2, 0xdeadbeefull);
  100. kvmppc_gsb_free(gsb);
  101. }
  102. static void test_gs_bitmap(struct kunit *test)
  103. {
  104. struct kvmppc_gs_bitmap gsbm = { 0 };
  105. struct kvmppc_gs_bitmap gsbm1 = { 0 };
  106. struct kvmppc_gs_bitmap gsbm2 = { 0 };
  107. u16 iden;
  108. int i, j;
  109. i = 0;
  110. for (u16 iden = KVMPPC_GSID_HOST_STATE_SIZE;
  111. iden <= KVMPPC_GSID_PROCESS_TABLE; iden++) {
  112. kvmppc_gsbm_set(&gsbm, iden);
  113. kvmppc_gsbm_set(&gsbm1, iden);
  114. KUNIT_EXPECT_TRUE(test, kvmppc_gsbm_test(&gsbm, iden));
  115. kvmppc_gsbm_clear(&gsbm, iden);
  116. KUNIT_EXPECT_FALSE(test, kvmppc_gsbm_test(&gsbm, iden));
  117. i++;
  118. }
  119. for (u16 iden = KVMPPC_GSID_L0_GUEST_HEAP;
  120. iden <= KVMPPC_GSID_L0_GUEST_PGTABLE_RECLAIM; iden++) {
  121. kvmppc_gsbm_set(&gsbm, iden);
  122. kvmppc_gsbm_set(&gsbm1, iden);
  123. KUNIT_EXPECT_TRUE(test, kvmppc_gsbm_test(&gsbm, iden));
  124. kvmppc_gsbm_clear(&gsbm, iden);
  125. KUNIT_EXPECT_FALSE(test, kvmppc_gsbm_test(&gsbm, iden));
  126. i++;
  127. }
  128. for (u16 iden = KVMPPC_GSID_RUN_INPUT; iden <= KVMPPC_GSID_VPA;
  129. iden++) {
  130. kvmppc_gsbm_set(&gsbm, iden);
  131. kvmppc_gsbm_set(&gsbm1, iden);
  132. KUNIT_EXPECT_TRUE(test, kvmppc_gsbm_test(&gsbm, iden));
  133. kvmppc_gsbm_clear(&gsbm, iden);
  134. KUNIT_EXPECT_FALSE(test, kvmppc_gsbm_test(&gsbm, iden));
  135. i++;
  136. }
  137. for (u16 iden = KVMPPC_GSID_GPR(0); iden <= KVMPPC_GSE_DW_REGS_END; iden++) {
  138. kvmppc_gsbm_set(&gsbm, iden);
  139. kvmppc_gsbm_set(&gsbm1, iden);
  140. KUNIT_EXPECT_TRUE(test, kvmppc_gsbm_test(&gsbm, iden));
  141. kvmppc_gsbm_clear(&gsbm, iden);
  142. KUNIT_EXPECT_FALSE(test, kvmppc_gsbm_test(&gsbm, iden));
  143. i++;
  144. }
  145. for (u16 iden = KVMPPC_GSID_CR; iden <= KVMPPC_GSID_PSPB; iden++) {
  146. kvmppc_gsbm_set(&gsbm, iden);
  147. kvmppc_gsbm_set(&gsbm1, iden);
  148. KUNIT_EXPECT_TRUE(test, kvmppc_gsbm_test(&gsbm, iden));
  149. kvmppc_gsbm_clear(&gsbm, iden);
  150. KUNIT_EXPECT_FALSE(test, kvmppc_gsbm_test(&gsbm, iden));
  151. i++;
  152. }
  153. for (u16 iden = KVMPPC_GSID_VSRS(0); iden <= KVMPPC_GSID_VSRS(63);
  154. iden++) {
  155. kvmppc_gsbm_set(&gsbm, iden);
  156. kvmppc_gsbm_set(&gsbm1, iden);
  157. KUNIT_EXPECT_TRUE(test, kvmppc_gsbm_test(&gsbm, iden));
  158. kvmppc_gsbm_clear(&gsbm, iden);
  159. KUNIT_EXPECT_FALSE(test, kvmppc_gsbm_test(&gsbm, iden));
  160. i++;
  161. }
  162. for (u16 iden = KVMPPC_GSID_HDAR; iden <= KVMPPC_GSID_ASDR; iden++) {
  163. kvmppc_gsbm_set(&gsbm, iden);
  164. kvmppc_gsbm_set(&gsbm1, iden);
  165. KUNIT_EXPECT_TRUE(test, kvmppc_gsbm_test(&gsbm, iden));
  166. kvmppc_gsbm_clear(&gsbm, iden);
  167. KUNIT_EXPECT_FALSE(test, kvmppc_gsbm_test(&gsbm, iden));
  168. i++;
  169. }
  170. j = 0;
  171. kvmppc_gsbm_for_each(&gsbm1, iden)
  172. {
  173. kvmppc_gsbm_set(&gsbm2, iden);
  174. j++;
  175. }
  176. KUNIT_EXPECT_EQ(test, i, j);
  177. KUNIT_EXPECT_MEMEQ(test, &gsbm1, &gsbm2, sizeof(gsbm1));
  178. }
  179. struct kvmppc_gs_msg_test1_data {
  180. u64 a;
  181. u32 b;
  182. struct kvmppc_gs_part_table c;
  183. struct kvmppc_gs_proc_table d;
  184. struct kvmppc_gs_buff_info e;
  185. };
  186. static size_t test1_get_size(struct kvmppc_gs_msg *gsm)
  187. {
  188. size_t size = 0;
  189. u16 ids[] = {
  190. KVMPPC_GSID_PARTITION_TABLE,
  191. KVMPPC_GSID_PROCESS_TABLE,
  192. KVMPPC_GSID_RUN_INPUT,
  193. KVMPPC_GSID_GPR(0),
  194. KVMPPC_GSID_CR,
  195. };
  196. for (int i = 0; i < ARRAY_SIZE(ids); i++)
  197. size += kvmppc_gse_total_size(kvmppc_gsid_size(ids[i]));
  198. return size;
  199. }
  200. static int test1_fill_info(struct kvmppc_gs_buff *gsb,
  201. struct kvmppc_gs_msg *gsm)
  202. {
  203. struct kvmppc_gs_msg_test1_data *data = gsm->data;
  204. if (kvmppc_gsm_includes(gsm, KVMPPC_GSID_GPR(0)))
  205. kvmppc_gse_put_u64(gsb, KVMPPC_GSID_GPR(0), data->a);
  206. if (kvmppc_gsm_includes(gsm, KVMPPC_GSID_CR))
  207. kvmppc_gse_put_u32(gsb, KVMPPC_GSID_CR, data->b);
  208. if (kvmppc_gsm_includes(gsm, KVMPPC_GSID_PARTITION_TABLE))
  209. kvmppc_gse_put_part_table(gsb, KVMPPC_GSID_PARTITION_TABLE,
  210. data->c);
  211. if (kvmppc_gsm_includes(gsm, KVMPPC_GSID_PROCESS_TABLE))
  212. kvmppc_gse_put_proc_table(gsb, KVMPPC_GSID_PARTITION_TABLE,
  213. data->d);
  214. if (kvmppc_gsm_includes(gsm, KVMPPC_GSID_RUN_INPUT))
  215. kvmppc_gse_put_buff_info(gsb, KVMPPC_GSID_RUN_INPUT, data->e);
  216. return 0;
  217. }
  218. static int test1_refresh_info(struct kvmppc_gs_msg *gsm,
  219. struct kvmppc_gs_buff *gsb)
  220. {
  221. struct kvmppc_gs_parser gsp = { 0 };
  222. struct kvmppc_gs_msg_test1_data *data = gsm->data;
  223. struct kvmppc_gs_elem *gse;
  224. int rc;
  225. rc = kvmppc_gse_parse(&gsp, gsb);
  226. if (rc < 0)
  227. return rc;
  228. gse = kvmppc_gsp_lookup(&gsp, KVMPPC_GSID_GPR(0));
  229. if (gse)
  230. data->a = kvmppc_gse_get_u64(gse);
  231. gse = kvmppc_gsp_lookup(&gsp, KVMPPC_GSID_CR);
  232. if (gse)
  233. data->b = kvmppc_gse_get_u32(gse);
  234. return 0;
  235. }
  236. static struct kvmppc_gs_msg_ops gs_msg_test1_ops = {
  237. .get_size = test1_get_size,
  238. .fill_info = test1_fill_info,
  239. .refresh_info = test1_refresh_info,
  240. };
  241. static void test_gs_msg(struct kunit *test)
  242. {
  243. struct kvmppc_gs_msg_test1_data test1_data = {
  244. .a = 0xdeadbeef,
  245. .b = 0x1,
  246. };
  247. struct kvmppc_gs_msg *gsm;
  248. struct kvmppc_gs_buff *gsb;
  249. gsm = kvmppc_gsm_new(&gs_msg_test1_ops, &test1_data, GSM_SEND,
  250. GFP_KERNEL);
  251. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gsm);
  252. gsb = kvmppc_gsb_new(kvmppc_gsm_size(gsm), 0, 0, GFP_KERNEL);
  253. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gsb);
  254. kvmppc_gsm_include(gsm, KVMPPC_GSID_PARTITION_TABLE);
  255. kvmppc_gsm_include(gsm, KVMPPC_GSID_PROCESS_TABLE);
  256. kvmppc_gsm_include(gsm, KVMPPC_GSID_RUN_INPUT);
  257. kvmppc_gsm_include(gsm, KVMPPC_GSID_GPR(0));
  258. kvmppc_gsm_include(gsm, KVMPPC_GSID_CR);
  259. kvmppc_gsm_fill_info(gsm, gsb);
  260. memset(&test1_data, 0, sizeof(test1_data));
  261. kvmppc_gsm_refresh_info(gsm, gsb);
  262. KUNIT_EXPECT_EQ(test, test1_data.a, 0xdeadbeef);
  263. KUNIT_EXPECT_EQ(test, test1_data.b, 0x1);
  264. kvmppc_gsm_free(gsm);
  265. }
  266. /* Test data struct for hostwide/L0 counters */
  267. struct kvmppc_gs_msg_test_hostwide_data {
  268. u64 guest_heap;
  269. u64 guest_heap_max;
  270. u64 guest_pgtable_size;
  271. u64 guest_pgtable_size_max;
  272. u64 guest_pgtable_reclaim;
  273. };
  274. static size_t test_hostwide_get_size(struct kvmppc_gs_msg *gsm)
  275. {
  276. size_t size = 0;
  277. u16 ids[] = {
  278. KVMPPC_GSID_L0_GUEST_HEAP,
  279. KVMPPC_GSID_L0_GUEST_HEAP_MAX,
  280. KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE,
  281. KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE_MAX,
  282. KVMPPC_GSID_L0_GUEST_PGTABLE_RECLAIM
  283. };
  284. for (int i = 0; i < ARRAY_SIZE(ids); i++)
  285. size += kvmppc_gse_total_size(kvmppc_gsid_size(ids[i]));
  286. return size;
  287. }
  288. static int test_hostwide_fill_info(struct kvmppc_gs_buff *gsb,
  289. struct kvmppc_gs_msg *gsm)
  290. {
  291. struct kvmppc_gs_msg_test_hostwide_data *data = gsm->data;
  292. if (kvmppc_gsm_includes(gsm, KVMPPC_GSID_L0_GUEST_HEAP))
  293. kvmppc_gse_put_u64(gsb, KVMPPC_GSID_L0_GUEST_HEAP,
  294. data->guest_heap);
  295. if (kvmppc_gsm_includes(gsm, KVMPPC_GSID_L0_GUEST_HEAP_MAX))
  296. kvmppc_gse_put_u64(gsb, KVMPPC_GSID_L0_GUEST_HEAP_MAX,
  297. data->guest_heap_max);
  298. if (kvmppc_gsm_includes(gsm, KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE))
  299. kvmppc_gse_put_u64(gsb, KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE,
  300. data->guest_pgtable_size);
  301. if (kvmppc_gsm_includes(gsm, KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE_MAX))
  302. kvmppc_gse_put_u64(gsb, KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE_MAX,
  303. data->guest_pgtable_size_max);
  304. if (kvmppc_gsm_includes(gsm, KVMPPC_GSID_L0_GUEST_PGTABLE_RECLAIM))
  305. kvmppc_gse_put_u64(gsb, KVMPPC_GSID_L0_GUEST_PGTABLE_RECLAIM,
  306. data->guest_pgtable_reclaim);
  307. return 0;
  308. }
  309. static int test_hostwide_refresh_info(struct kvmppc_gs_msg *gsm,
  310. struct kvmppc_gs_buff *gsb)
  311. {
  312. struct kvmppc_gs_parser gsp = { 0 };
  313. struct kvmppc_gs_msg_test_hostwide_data *data = gsm->data;
  314. struct kvmppc_gs_elem *gse;
  315. int rc;
  316. rc = kvmppc_gse_parse(&gsp, gsb);
  317. if (rc < 0)
  318. return rc;
  319. gse = kvmppc_gsp_lookup(&gsp, KVMPPC_GSID_L0_GUEST_HEAP);
  320. if (gse)
  321. data->guest_heap = kvmppc_gse_get_u64(gse);
  322. gse = kvmppc_gsp_lookup(&gsp, KVMPPC_GSID_L0_GUEST_HEAP_MAX);
  323. if (gse)
  324. data->guest_heap_max = kvmppc_gse_get_u64(gse);
  325. gse = kvmppc_gsp_lookup(&gsp, KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE);
  326. if (gse)
  327. data->guest_pgtable_size = kvmppc_gse_get_u64(gse);
  328. gse = kvmppc_gsp_lookup(&gsp, KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE_MAX);
  329. if (gse)
  330. data->guest_pgtable_size_max = kvmppc_gse_get_u64(gse);
  331. gse = kvmppc_gsp_lookup(&gsp, KVMPPC_GSID_L0_GUEST_PGTABLE_RECLAIM);
  332. if (gse)
  333. data->guest_pgtable_reclaim = kvmppc_gse_get_u64(gse);
  334. return 0;
  335. }
  336. static struct kvmppc_gs_msg_ops gs_msg_test_hostwide_ops = {
  337. .get_size = test_hostwide_get_size,
  338. .fill_info = test_hostwide_fill_info,
  339. .refresh_info = test_hostwide_refresh_info,
  340. };
  341. static void test_gs_hostwide_msg(struct kunit *test)
  342. {
  343. struct kvmppc_gs_msg_test_hostwide_data test_data = {
  344. .guest_heap = 0xdeadbeef,
  345. .guest_heap_max = ~0ULL,
  346. .guest_pgtable_size = 0xff,
  347. .guest_pgtable_size_max = 0xffffff,
  348. .guest_pgtable_reclaim = 0xdeadbeef,
  349. };
  350. struct kvmppc_gs_msg *gsm;
  351. struct kvmppc_gs_buff *gsb;
  352. gsm = kvmppc_gsm_new(&gs_msg_test_hostwide_ops, &test_data, GSM_SEND,
  353. GFP_KERNEL);
  354. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gsm);
  355. gsb = kvmppc_gsb_new(kvmppc_gsm_size(gsm), 0, 0, GFP_KERNEL);
  356. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gsb);
  357. kvmppc_gsm_include(gsm, KVMPPC_GSID_L0_GUEST_HEAP);
  358. kvmppc_gsm_include(gsm, KVMPPC_GSID_L0_GUEST_HEAP_MAX);
  359. kvmppc_gsm_include(gsm, KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE);
  360. kvmppc_gsm_include(gsm, KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE_MAX);
  361. kvmppc_gsm_include(gsm, KVMPPC_GSID_L0_GUEST_PGTABLE_RECLAIM);
  362. kvmppc_gsm_fill_info(gsm, gsb);
  363. memset(&test_data, 0, sizeof(test_data));
  364. kvmppc_gsm_refresh_info(gsm, gsb);
  365. KUNIT_EXPECT_EQ(test, test_data.guest_heap, 0xdeadbeef);
  366. KUNIT_EXPECT_EQ(test, test_data.guest_heap_max, ~0ULL);
  367. KUNIT_EXPECT_EQ(test, test_data.guest_pgtable_size, 0xff);
  368. KUNIT_EXPECT_EQ(test, test_data.guest_pgtable_size_max, 0xffffff);
  369. KUNIT_EXPECT_EQ(test, test_data.guest_pgtable_reclaim, 0xdeadbeef);
  370. kvmppc_gsm_free(gsm);
  371. }
  372. /* Test if the H_GUEST_GET_STATE for hostwide counters works */
  373. static void test_gs_hostwide_counters(struct kunit *test)
  374. {
  375. struct kvmppc_gs_msg_test_hostwide_data test_data;
  376. struct kvmppc_gs_parser gsp = { 0 };
  377. struct kvmppc_gs_msg *gsm;
  378. struct kvmppc_gs_buff *gsb;
  379. struct kvmppc_gs_elem *gse;
  380. int rc;
  381. if (!kvmhv_on_pseries())
  382. kunit_skip(test, "This test need a kmv-hv guest");
  383. gsm = kvmppc_gsm_new(&gs_msg_test_hostwide_ops, &test_data, GSM_SEND,
  384. GFP_KERNEL);
  385. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gsm);
  386. gsb = kvmppc_gsb_new(kvmppc_gsm_size(gsm), 0, 0, GFP_KERNEL);
  387. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gsb);
  388. kvmppc_gsm_include(gsm, KVMPPC_GSID_L0_GUEST_HEAP);
  389. kvmppc_gsm_include(gsm, KVMPPC_GSID_L0_GUEST_HEAP_MAX);
  390. kvmppc_gsm_include(gsm, KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE);
  391. kvmppc_gsm_include(gsm, KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE_MAX);
  392. kvmppc_gsm_include(gsm, KVMPPC_GSID_L0_GUEST_PGTABLE_RECLAIM);
  393. kvmppc_gsm_fill_info(gsm, gsb);
  394. /* With HOST_WIDE flags guestid and vcpuid will be ignored */
  395. rc = kvmppc_gsb_recv(gsb, KVMPPC_GS_FLAGS_HOST_WIDE);
  396. KUNIT_ASSERT_EQ(test, rc, 0);
  397. /* Parse the guest state buffer is successful */
  398. rc = kvmppc_gse_parse(&gsp, gsb);
  399. KUNIT_ASSERT_EQ(test, rc, 0);
  400. /* Parse the GSB and get the counters */
  401. gse = kvmppc_gsp_lookup(&gsp, KVMPPC_GSID_L0_GUEST_HEAP);
  402. KUNIT_ASSERT_NOT_NULL_MSG(test, gse, "L0 Heap counter missing");
  403. kunit_info(test, "Guest Heap Size=%llu bytes",
  404. kvmppc_gse_get_u64(gse));
  405. gse = kvmppc_gsp_lookup(&gsp, KVMPPC_GSID_L0_GUEST_HEAP_MAX);
  406. KUNIT_ASSERT_NOT_NULL_MSG(test, gse, "L0 Heap counter max missing");
  407. kunit_info(test, "Guest Heap Size Max=%llu bytes",
  408. kvmppc_gse_get_u64(gse));
  409. gse = kvmppc_gsp_lookup(&gsp, KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE);
  410. KUNIT_ASSERT_NOT_NULL_MSG(test, gse, "L0 page-table size missing");
  411. kunit_info(test, "Guest Page-table Size=%llu bytes",
  412. kvmppc_gse_get_u64(gse));
  413. gse = kvmppc_gsp_lookup(&gsp, KVMPPC_GSID_L0_GUEST_PGTABLE_SIZE_MAX);
  414. KUNIT_ASSERT_NOT_NULL_MSG(test, gse, "L0 page-table size-max missing");
  415. kunit_info(test, "Guest Page-table Size Max=%llu bytes",
  416. kvmppc_gse_get_u64(gse));
  417. gse = kvmppc_gsp_lookup(&gsp, KVMPPC_GSID_L0_GUEST_PGTABLE_RECLAIM);
  418. KUNIT_ASSERT_NOT_NULL_MSG(test, gse, "L0 page-table reclaim size missing");
  419. kunit_info(test, "Guest Page-table Reclaim Size=%llu bytes",
  420. kvmppc_gse_get_u64(gse));
  421. kvmppc_gsm_free(gsm);
  422. kvmppc_gsb_free(gsb);
  423. }
  424. static struct kunit_case guest_state_buffer_testcases[] = {
  425. KUNIT_CASE(test_creating_buffer),
  426. KUNIT_CASE(test_adding_element),
  427. KUNIT_CASE(test_gs_bitmap),
  428. KUNIT_CASE(test_gs_parsing),
  429. KUNIT_CASE(test_gs_msg),
  430. KUNIT_CASE(test_gs_hostwide_msg),
  431. KUNIT_CASE(test_gs_hostwide_counters),
  432. {}
  433. };
  434. static struct kunit_suite guest_state_buffer_test_suite = {
  435. .name = "guest_state_buffer_test",
  436. .test_cases = guest_state_buffer_testcases,
  437. };
  438. kunit_test_suites(&guest_state_buffer_test_suite);
  439. MODULE_DESCRIPTION("KUnit tests for Guest State Buffer APIs");
  440. MODULE_LICENSE("GPL");