test-guest-state-buffer.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  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. static void test_creating_buffer(struct kunit *test)
  7. {
  8. struct kvmppc_gs_buff *gsb;
  9. size_t size = 0x100;
  10. gsb = kvmppc_gsb_new(size, 0, 0, GFP_KERNEL);
  11. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gsb);
  12. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gsb->hdr);
  13. KUNIT_EXPECT_EQ(test, gsb->capacity, roundup_pow_of_two(size));
  14. KUNIT_EXPECT_EQ(test, gsb->len, sizeof(__be32));
  15. kvmppc_gsb_free(gsb);
  16. }
  17. static void test_adding_element(struct kunit *test)
  18. {
  19. const struct kvmppc_gs_elem *head, *curr;
  20. union {
  21. __vector128 v;
  22. u64 dw[2];
  23. } u;
  24. int rem;
  25. struct kvmppc_gs_buff *gsb;
  26. size_t size = 0x1000;
  27. int i, rc;
  28. u64 data;
  29. gsb = kvmppc_gsb_new(size, 0, 0, GFP_KERNEL);
  30. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gsb);
  31. /* Single elements, direct use of __kvmppc_gse_put() */
  32. data = 0xdeadbeef;
  33. rc = __kvmppc_gse_put(gsb, KVMPPC_GSID_GPR(0), 8, &data);
  34. KUNIT_EXPECT_GE(test, rc, 0);
  35. head = kvmppc_gsb_data(gsb);
  36. KUNIT_EXPECT_EQ(test, kvmppc_gse_iden(head), KVMPPC_GSID_GPR(0));
  37. KUNIT_EXPECT_EQ(test, kvmppc_gse_len(head), 8);
  38. data = 0;
  39. memcpy(&data, kvmppc_gse_data(head), 8);
  40. KUNIT_EXPECT_EQ(test, data, 0xdeadbeef);
  41. /* Multiple elements, simple wrapper */
  42. rc = kvmppc_gse_put_u64(gsb, KVMPPC_GSID_GPR(1), 0xcafef00d);
  43. KUNIT_EXPECT_GE(test, rc, 0);
  44. u.dw[0] = 0x1;
  45. u.dw[1] = 0x2;
  46. rc = kvmppc_gse_put_vector128(gsb, KVMPPC_GSID_VSRS(0), &u.v);
  47. KUNIT_EXPECT_GE(test, rc, 0);
  48. u.dw[0] = 0x0;
  49. u.dw[1] = 0x0;
  50. kvmppc_gsb_for_each_elem(i, curr, gsb, rem) {
  51. switch (i) {
  52. case 0:
  53. KUNIT_EXPECT_EQ(test, kvmppc_gse_iden(curr),
  54. KVMPPC_GSID_GPR(0));
  55. KUNIT_EXPECT_EQ(test, kvmppc_gse_len(curr), 8);
  56. KUNIT_EXPECT_EQ(test, kvmppc_gse_get_be64(curr),
  57. 0xdeadbeef);
  58. break;
  59. case 1:
  60. KUNIT_EXPECT_EQ(test, kvmppc_gse_iden(curr),
  61. KVMPPC_GSID_GPR(1));
  62. KUNIT_EXPECT_EQ(test, kvmppc_gse_len(curr), 8);
  63. KUNIT_EXPECT_EQ(test, kvmppc_gse_get_u64(curr),
  64. 0xcafef00d);
  65. break;
  66. case 2:
  67. KUNIT_EXPECT_EQ(test, kvmppc_gse_iden(curr),
  68. KVMPPC_GSID_VSRS(0));
  69. KUNIT_EXPECT_EQ(test, kvmppc_gse_len(curr), 16);
  70. kvmppc_gse_get_vector128(curr, &u.v);
  71. KUNIT_EXPECT_EQ(test, u.dw[0], 0x1);
  72. KUNIT_EXPECT_EQ(test, u.dw[1], 0x2);
  73. break;
  74. }
  75. }
  76. KUNIT_EXPECT_EQ(test, i, 3);
  77. kvmppc_gsb_reset(gsb);
  78. KUNIT_EXPECT_EQ(test, kvmppc_gsb_nelems(gsb), 0);
  79. KUNIT_EXPECT_EQ(test, kvmppc_gsb_len(gsb),
  80. sizeof(struct kvmppc_gs_header));
  81. kvmppc_gsb_free(gsb);
  82. }
  83. static void test_gs_parsing(struct kunit *test)
  84. {
  85. struct kvmppc_gs_elem *gse;
  86. struct kvmppc_gs_parser gsp = { 0 };
  87. struct kvmppc_gs_buff *gsb;
  88. size_t size = 0x1000;
  89. u64 tmp1, tmp2;
  90. gsb = kvmppc_gsb_new(size, 0, 0, GFP_KERNEL);
  91. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gsb);
  92. tmp1 = 0xdeadbeefull;
  93. kvmppc_gse_put_u64(gsb, KVMPPC_GSID_GPR(0), tmp1);
  94. KUNIT_EXPECT_GE(test, kvmppc_gse_parse(&gsp, gsb), 0);
  95. gse = kvmppc_gsp_lookup(&gsp, KVMPPC_GSID_GPR(0));
  96. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gse);
  97. tmp2 = kvmppc_gse_get_u64(gse);
  98. KUNIT_EXPECT_EQ(test, tmp2, 0xdeadbeefull);
  99. kvmppc_gsb_free(gsb);
  100. }
  101. static void test_gs_bitmap(struct kunit *test)
  102. {
  103. struct kvmppc_gs_bitmap gsbm = { 0 };
  104. struct kvmppc_gs_bitmap gsbm1 = { 0 };
  105. struct kvmppc_gs_bitmap gsbm2 = { 0 };
  106. u16 iden;
  107. int i, j;
  108. i = 0;
  109. for (u16 iden = KVMPPC_GSID_HOST_STATE_SIZE;
  110. iden <= KVMPPC_GSID_PROCESS_TABLE; iden++) {
  111. kvmppc_gsbm_set(&gsbm, iden);
  112. kvmppc_gsbm_set(&gsbm1, iden);
  113. KUNIT_EXPECT_TRUE(test, kvmppc_gsbm_test(&gsbm, iden));
  114. kvmppc_gsbm_clear(&gsbm, iden);
  115. KUNIT_EXPECT_FALSE(test, kvmppc_gsbm_test(&gsbm, iden));
  116. i++;
  117. }
  118. for (u16 iden = KVMPPC_GSID_RUN_INPUT; iden <= KVMPPC_GSID_VPA;
  119. iden++) {
  120. kvmppc_gsbm_set(&gsbm, iden);
  121. kvmppc_gsbm_set(&gsbm1, iden);
  122. KUNIT_EXPECT_TRUE(test, kvmppc_gsbm_test(&gsbm, iden));
  123. kvmppc_gsbm_clear(&gsbm, iden);
  124. KUNIT_EXPECT_FALSE(test, kvmppc_gsbm_test(&gsbm, iden));
  125. i++;
  126. }
  127. for (u16 iden = KVMPPC_GSID_GPR(0); iden <= KVMPPC_GSE_DW_REGS_END; iden++) {
  128. kvmppc_gsbm_set(&gsbm, iden);
  129. kvmppc_gsbm_set(&gsbm1, iden);
  130. KUNIT_EXPECT_TRUE(test, kvmppc_gsbm_test(&gsbm, iden));
  131. kvmppc_gsbm_clear(&gsbm, iden);
  132. KUNIT_EXPECT_FALSE(test, kvmppc_gsbm_test(&gsbm, iden));
  133. i++;
  134. }
  135. for (u16 iden = KVMPPC_GSID_CR; iden <= KVMPPC_GSID_PSPB; iden++) {
  136. kvmppc_gsbm_set(&gsbm, iden);
  137. kvmppc_gsbm_set(&gsbm1, iden);
  138. KUNIT_EXPECT_TRUE(test, kvmppc_gsbm_test(&gsbm, iden));
  139. kvmppc_gsbm_clear(&gsbm, iden);
  140. KUNIT_EXPECT_FALSE(test, kvmppc_gsbm_test(&gsbm, iden));
  141. i++;
  142. }
  143. for (u16 iden = KVMPPC_GSID_VSRS(0); iden <= KVMPPC_GSID_VSRS(63);
  144. iden++) {
  145. kvmppc_gsbm_set(&gsbm, iden);
  146. kvmppc_gsbm_set(&gsbm1, iden);
  147. KUNIT_EXPECT_TRUE(test, kvmppc_gsbm_test(&gsbm, iden));
  148. kvmppc_gsbm_clear(&gsbm, iden);
  149. KUNIT_EXPECT_FALSE(test, kvmppc_gsbm_test(&gsbm, iden));
  150. i++;
  151. }
  152. for (u16 iden = KVMPPC_GSID_HDAR; iden <= KVMPPC_GSID_ASDR; iden++) {
  153. kvmppc_gsbm_set(&gsbm, iden);
  154. kvmppc_gsbm_set(&gsbm1, iden);
  155. KUNIT_EXPECT_TRUE(test, kvmppc_gsbm_test(&gsbm, iden));
  156. kvmppc_gsbm_clear(&gsbm, iden);
  157. KUNIT_EXPECT_FALSE(test, kvmppc_gsbm_test(&gsbm, iden));
  158. i++;
  159. }
  160. j = 0;
  161. kvmppc_gsbm_for_each(&gsbm1, iden)
  162. {
  163. kvmppc_gsbm_set(&gsbm2, iden);
  164. j++;
  165. }
  166. KUNIT_EXPECT_EQ(test, i, j);
  167. KUNIT_EXPECT_MEMEQ(test, &gsbm1, &gsbm2, sizeof(gsbm1));
  168. }
  169. struct kvmppc_gs_msg_test1_data {
  170. u64 a;
  171. u32 b;
  172. struct kvmppc_gs_part_table c;
  173. struct kvmppc_gs_proc_table d;
  174. struct kvmppc_gs_buff_info e;
  175. };
  176. static size_t test1_get_size(struct kvmppc_gs_msg *gsm)
  177. {
  178. size_t size = 0;
  179. u16 ids[] = {
  180. KVMPPC_GSID_PARTITION_TABLE,
  181. KVMPPC_GSID_PROCESS_TABLE,
  182. KVMPPC_GSID_RUN_INPUT,
  183. KVMPPC_GSID_GPR(0),
  184. KVMPPC_GSID_CR,
  185. };
  186. for (int i = 0; i < ARRAY_SIZE(ids); i++)
  187. size += kvmppc_gse_total_size(kvmppc_gsid_size(ids[i]));
  188. return size;
  189. }
  190. static int test1_fill_info(struct kvmppc_gs_buff *gsb,
  191. struct kvmppc_gs_msg *gsm)
  192. {
  193. struct kvmppc_gs_msg_test1_data *data = gsm->data;
  194. if (kvmppc_gsm_includes(gsm, KVMPPC_GSID_GPR(0)))
  195. kvmppc_gse_put_u64(gsb, KVMPPC_GSID_GPR(0), data->a);
  196. if (kvmppc_gsm_includes(gsm, KVMPPC_GSID_CR))
  197. kvmppc_gse_put_u32(gsb, KVMPPC_GSID_CR, data->b);
  198. if (kvmppc_gsm_includes(gsm, KVMPPC_GSID_PARTITION_TABLE))
  199. kvmppc_gse_put_part_table(gsb, KVMPPC_GSID_PARTITION_TABLE,
  200. data->c);
  201. if (kvmppc_gsm_includes(gsm, KVMPPC_GSID_PROCESS_TABLE))
  202. kvmppc_gse_put_proc_table(gsb, KVMPPC_GSID_PARTITION_TABLE,
  203. data->d);
  204. if (kvmppc_gsm_includes(gsm, KVMPPC_GSID_RUN_INPUT))
  205. kvmppc_gse_put_buff_info(gsb, KVMPPC_GSID_RUN_INPUT, data->e);
  206. return 0;
  207. }
  208. static int test1_refresh_info(struct kvmppc_gs_msg *gsm,
  209. struct kvmppc_gs_buff *gsb)
  210. {
  211. struct kvmppc_gs_parser gsp = { 0 };
  212. struct kvmppc_gs_msg_test1_data *data = gsm->data;
  213. struct kvmppc_gs_elem *gse;
  214. int rc;
  215. rc = kvmppc_gse_parse(&gsp, gsb);
  216. if (rc < 0)
  217. return rc;
  218. gse = kvmppc_gsp_lookup(&gsp, KVMPPC_GSID_GPR(0));
  219. if (gse)
  220. data->a = kvmppc_gse_get_u64(gse);
  221. gse = kvmppc_gsp_lookup(&gsp, KVMPPC_GSID_CR);
  222. if (gse)
  223. data->b = kvmppc_gse_get_u32(gse);
  224. return 0;
  225. }
  226. static struct kvmppc_gs_msg_ops gs_msg_test1_ops = {
  227. .get_size = test1_get_size,
  228. .fill_info = test1_fill_info,
  229. .refresh_info = test1_refresh_info,
  230. };
  231. static void test_gs_msg(struct kunit *test)
  232. {
  233. struct kvmppc_gs_msg_test1_data test1_data = {
  234. .a = 0xdeadbeef,
  235. .b = 0x1,
  236. };
  237. struct kvmppc_gs_msg *gsm;
  238. struct kvmppc_gs_buff *gsb;
  239. gsm = kvmppc_gsm_new(&gs_msg_test1_ops, &test1_data, GSM_SEND,
  240. GFP_KERNEL);
  241. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gsm);
  242. gsb = kvmppc_gsb_new(kvmppc_gsm_size(gsm), 0, 0, GFP_KERNEL);
  243. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gsb);
  244. kvmppc_gsm_include(gsm, KVMPPC_GSID_PARTITION_TABLE);
  245. kvmppc_gsm_include(gsm, KVMPPC_GSID_PROCESS_TABLE);
  246. kvmppc_gsm_include(gsm, KVMPPC_GSID_RUN_INPUT);
  247. kvmppc_gsm_include(gsm, KVMPPC_GSID_GPR(0));
  248. kvmppc_gsm_include(gsm, KVMPPC_GSID_CR);
  249. kvmppc_gsm_fill_info(gsm, gsb);
  250. memset(&test1_data, 0, sizeof(test1_data));
  251. kvmppc_gsm_refresh_info(gsm, gsb);
  252. KUNIT_EXPECT_EQ(test, test1_data.a, 0xdeadbeef);
  253. KUNIT_EXPECT_EQ(test, test1_data.b, 0x1);
  254. kvmppc_gsm_free(gsm);
  255. }
  256. static struct kunit_case guest_state_buffer_testcases[] = {
  257. KUNIT_CASE(test_creating_buffer),
  258. KUNIT_CASE(test_adding_element),
  259. KUNIT_CASE(test_gs_bitmap),
  260. KUNIT_CASE(test_gs_parsing),
  261. KUNIT_CASE(test_gs_msg),
  262. {}
  263. };
  264. static struct kunit_suite guest_state_buffer_test_suite = {
  265. .name = "guest_state_buffer_test",
  266. .test_cases = guest_state_buffer_testcases,
  267. };
  268. kunit_test_suites(&guest_state_buffer_test_suite);
  269. MODULE_DESCRIPTION("KUnit tests for Guest State Buffer APIs");
  270. MODULE_LICENSE("GPL");