xref: /spdk/test/unit/lib/nvmf/vfio_user.c/vfio_user_ut.c (revision b09de013a5df946650e14acd608a19c0cce22140)
1488570ebSJim Harris /*   SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse  *   Copyright (C) 2021 Intel Corporation. All rights reserved.
31b28efb5SChangpeng Liu  */
41b28efb5SChangpeng Liu 
51b28efb5SChangpeng Liu #include "spdk/stdinc.h"
6ae431e31SKonrad Sztyber #include "spdk_internal/cunit.h"
71b28efb5SChangpeng Liu #include "common/lib/test_env.c"
81b28efb5SChangpeng Liu #include "nvmf/vfio_user.c"
91b28efb5SChangpeng Liu #include "nvmf/transport.c"
101b28efb5SChangpeng Liu 
111b28efb5SChangpeng Liu DEFINE_STUB(spdk_nvmf_ctrlr_get_regs, const struct spdk_nvmf_registers *,
121b28efb5SChangpeng Liu 	    (struct spdk_nvmf_ctrlr *ctrlr), NULL);
131b28efb5SChangpeng Liu DEFINE_STUB(spdk_mem_register, int, (void *vaddr, size_t len), 0);
141b28efb5SChangpeng Liu DEFINE_STUB(spdk_mem_unregister, int, (void *vaddr, size_t len), 0);
151b28efb5SChangpeng Liu DEFINE_STUB_V(spdk_nvmf_request_exec, (struct spdk_nvmf_request *req));
161b28efb5SChangpeng Liu DEFINE_STUB(spdk_nvmf_request_complete, int, (struct spdk_nvmf_request *req), 0);
171b28efb5SChangpeng Liu DEFINE_STUB_V(spdk_nvmf_tgt_new_qpair, (struct spdk_nvmf_tgt *tgt, struct spdk_nvmf_qpair *qpair));
181b28efb5SChangpeng Liu DEFINE_STUB(nvmf_ctrlr_abort_request, int, (struct spdk_nvmf_request *req), 0);
19608b54a2SKonrad Sztyber DEFINE_STUB(spdk_nvmf_qpair_disconnect, int, (struct spdk_nvmf_qpair *qpair), 0);
201b28efb5SChangpeng Liu DEFINE_STUB(spdk_nvmf_subsystem_get_nqn, const char *,
211b28efb5SChangpeng Liu 	    (const struct spdk_nvmf_subsystem *subsystem), NULL);
22*b09de013SShuhei Matsumoto DEFINE_STUB(spdk_bdev_desc_get_block_size, uint32_t, (struct spdk_bdev_desc *desc), 512);
23b3cd421fSChangpeng Liu DEFINE_STUB(spdk_nvmf_subsystem_pause, int, (struct spdk_nvmf_subsystem *subsystem,
24b3cd421fSChangpeng Liu 		uint32_t nsid, spdk_nvmf_subsystem_state_change_done cb_fn, void *cb_arg), 0);
25b3cd421fSChangpeng Liu DEFINE_STUB(spdk_nvmf_subsystem_resume, int, (struct spdk_nvmf_subsystem *subsystem,
26b3cd421fSChangpeng Liu 		spdk_nvmf_subsystem_state_change_done cb_fn, void *cb_arg), 0);
27414ff9bcSSzulik, Maciej DEFINE_STUB_V(spdk_nvmf_ctrlr_abort_aer, (struct spdk_nvmf_ctrlr *ctrlr));
28414ff9bcSSzulik, Maciej DEFINE_STUB(spdk_nvmf_ctrlr_async_event_error_event, int, (struct spdk_nvmf_ctrlr *ctrlr,
29414ff9bcSSzulik, Maciej 		enum spdk_nvme_async_event_info_error info), 0);
30723adbafSChangpeng Liu DEFINE_STUB(spdk_nvme_transport_id_adrfam_str, const char *, (enum spdk_nvmf_adrfam adrfam), NULL);
31723adbafSChangpeng Liu DEFINE_STUB(spdk_nvmf_qpair_get_listen_trid, int, (struct spdk_nvmf_qpair *qpair,
32723adbafSChangpeng Liu 		struct spdk_nvme_transport_id *trid), 0);
33723adbafSChangpeng Liu DEFINE_STUB(spdk_nvme_transport_id_compare, int, (const struct spdk_nvme_transport_id *trid1,
34723adbafSChangpeng Liu 		const struct spdk_nvme_transport_id *trid2), 0);
35b3cd421fSChangpeng Liu DEFINE_STUB(nvmf_subsystem_get_ctrlr, struct spdk_nvmf_ctrlr *,
36b3cd421fSChangpeng Liu 	    (struct spdk_nvmf_subsystem *subsystem, uint16_t cntlid), NULL);
37a576bcccSChangpeng Liu DEFINE_STUB_V(nvmf_ctrlr_set_fatal_status, (struct spdk_nvmf_ctrlr *ctrlr));
38982c25feSChangpeng Liu DEFINE_STUB(spdk_nvmf_ctrlr_save_migr_data, int, (struct spdk_nvmf_ctrlr *ctrlr,
39982c25feSChangpeng Liu 		struct spdk_nvmf_ctrlr_migr_data *data), 0);
40982c25feSChangpeng Liu DEFINE_STUB(spdk_nvmf_ctrlr_restore_migr_data, int, (struct spdk_nvmf_ctrlr *ctrlr,
41982c25feSChangpeng Liu 		const struct spdk_nvmf_ctrlr_migr_data *data), 0);
421ac56070SKonrad Sztyber DEFINE_STUB(spdk_mempool_lookup, struct spdk_mempool *, (const char *name), NULL);
43a1a770d0SMichael Haeuptle DEFINE_STUB(nvmf_subsystem_gen_cntlid, uint16_t, (struct spdk_nvmf_subsystem *subsystem), 1)
441b28efb5SChangpeng Liu 
451b28efb5SChangpeng Liu static void *
46ea14933aSJohn Levon gpa_to_vva(void *prv, uint64_t addr, uint64_t len, uint32_t flags)
471b28efb5SChangpeng Liu {
481b28efb5SChangpeng Liu 	return (void *)(uintptr_t)addr;
491b28efb5SChangpeng Liu }
501b28efb5SChangpeng Liu 
511b28efb5SChangpeng Liu static void
521b28efb5SChangpeng Liu test_nvme_cmd_map_prps(void)
531b28efb5SChangpeng Liu {
541b28efb5SChangpeng Liu 	struct spdk_nvme_cmd cmd = {};
551b28efb5SChangpeng Liu 	struct iovec iovs[33];
561b28efb5SChangpeng Liu 	uint64_t phy_addr, *prp;
571b28efb5SChangpeng Liu 	uint32_t len;
581b28efb5SChangpeng Liu 	void *buf, *prps;
591b28efb5SChangpeng Liu 	int i, ret;
601b28efb5SChangpeng Liu 	size_t mps = 4096;
611b28efb5SChangpeng Liu 
621b28efb5SChangpeng Liu 	buf = spdk_zmalloc(132 * 1024, 4096, &phy_addr, 0, 0);
631b28efb5SChangpeng Liu 	CU_ASSERT(buf != NULL);
641b28efb5SChangpeng Liu 	prps = spdk_zmalloc(4096, 4096, &phy_addr, 0, 0);
651b28efb5SChangpeng Liu 	CU_ASSERT(prps != NULL);
661b28efb5SChangpeng Liu 
671b28efb5SChangpeng Liu 	/* test case 1: 4KiB with PRP1 only */
681b28efb5SChangpeng Liu 	cmd.dptr.prp.prp1 = (uint64_t)(uintptr_t)buf;
691b28efb5SChangpeng Liu 	len = 4096;
701b28efb5SChangpeng Liu 	ret = nvme_cmd_map_prps(NULL, &cmd, iovs, 33, len, mps, gpa_to_vva);
711b28efb5SChangpeng Liu 	CU_ASSERT(ret == 1);
721b28efb5SChangpeng Liu 	CU_ASSERT(iovs[0].iov_base == (void *)(uintptr_t)cmd.dptr.prp.prp1);
731b28efb5SChangpeng Liu 	CU_ASSERT(iovs[0].iov_len == len);
741b28efb5SChangpeng Liu 
751b28efb5SChangpeng Liu 	/* test case 2: 4KiB with PRP1 and PRP2, 1KiB in first iov, and 3KiB in second iov */
761b28efb5SChangpeng Liu 	cmd.dptr.prp.prp1 = (uint64_t)(uintptr_t)buf + 1024 * 3;
771b28efb5SChangpeng Liu 	cmd.dptr.prp.prp2 = (uint64_t)(uintptr_t)buf + 4096;
781b28efb5SChangpeng Liu 	len = 4096;
791b28efb5SChangpeng Liu 	ret = nvme_cmd_map_prps(NULL, &cmd, iovs, 1, len, mps, gpa_to_vva);
801b28efb5SChangpeng Liu 	CU_ASSERT(ret == -ERANGE);
811b28efb5SChangpeng Liu 	ret = nvme_cmd_map_prps(NULL, &cmd, iovs, 33, len, mps, gpa_to_vva);
821b28efb5SChangpeng Liu 	CU_ASSERT(ret == 2);
831b28efb5SChangpeng Liu 	CU_ASSERT(iovs[0].iov_base == (void *)(uintptr_t)cmd.dptr.prp.prp1);
841b28efb5SChangpeng Liu 	CU_ASSERT(iovs[0].iov_len == 1024);
851b28efb5SChangpeng Liu 	CU_ASSERT(iovs[1].iov_base == (void *)(uintptr_t)cmd.dptr.prp.prp2);
861b28efb5SChangpeng Liu 	CU_ASSERT(iovs[1].iov_len == 1024 * 3);
871b28efb5SChangpeng Liu 
881b28efb5SChangpeng Liu 	/* test case 3: 128KiB with PRP list, 1KiB in first iov, 3KiB in last iov */
891b28efb5SChangpeng Liu 	cmd.dptr.prp.prp1 = (uint64_t)(uintptr_t)buf + 1024 * 3;
901b28efb5SChangpeng Liu 	cmd.dptr.prp.prp2 = (uint64_t)(uintptr_t)prps;
911b28efb5SChangpeng Liu 	len = 128 * 1024;
921b28efb5SChangpeng Liu 	prp = prps;
931b28efb5SChangpeng Liu 	for (i = 1; i < 33; i++) {
941b28efb5SChangpeng Liu 		*prp = (uint64_t)(uintptr_t)buf + i * 4096;
951b28efb5SChangpeng Liu 		prp++;
961b28efb5SChangpeng Liu 	}
971b28efb5SChangpeng Liu 	ret = nvme_cmd_map_prps(NULL, &cmd, iovs, 33, len, mps, gpa_to_vva);
981b28efb5SChangpeng Liu 	CU_ASSERT(ret == 33);
991b28efb5SChangpeng Liu 	CU_ASSERT(iovs[0].iov_base == (void *)(uintptr_t)cmd.dptr.prp.prp1);
1001b28efb5SChangpeng Liu 	CU_ASSERT(iovs[0].iov_len == 1024);
1011b28efb5SChangpeng Liu 	for (i = 1; i < 32; i++) {
1021b28efb5SChangpeng Liu 		CU_ASSERT(iovs[i].iov_base == (void *)((uintptr_t)buf + i * 4096));
1031b28efb5SChangpeng Liu 		CU_ASSERT(iovs[i].iov_len == 4096);
1041b28efb5SChangpeng Liu 	}
1051b28efb5SChangpeng Liu 	CU_ASSERT(iovs[32].iov_base == (void *)((uintptr_t)buf + 32 * 4096));
1061b28efb5SChangpeng Liu 	CU_ASSERT(iovs[32].iov_len == 1024 * 3);
1071b28efb5SChangpeng Liu 
1081b28efb5SChangpeng Liu 	/* test case 4: 256KiB with PRP list, not enough iovs */
1091b28efb5SChangpeng Liu 	cmd.dptr.prp.prp1 = (uint64_t)(uintptr_t)buf + 1024 * 3;
1101b28efb5SChangpeng Liu 	cmd.dptr.prp.prp2 = (uint64_t)(uintptr_t)prps;
1111b28efb5SChangpeng Liu 	len = 256 * 1024;
1121b28efb5SChangpeng Liu 	ret = nvme_cmd_map_prps(NULL, &cmd, iovs, 33, len, mps, gpa_to_vva);
1131b28efb5SChangpeng Liu 	CU_ASSERT(ret == -ERANGE);
1141b28efb5SChangpeng Liu 
1151b28efb5SChangpeng Liu 	spdk_free(buf);
1161b28efb5SChangpeng Liu 	spdk_free(prps);
1171b28efb5SChangpeng Liu }
1181b28efb5SChangpeng Liu 
1191b28efb5SChangpeng Liu static void
1201b28efb5SChangpeng Liu test_nvme_cmd_map_sgls(void)
1211b28efb5SChangpeng Liu {
1221b28efb5SChangpeng Liu 	struct spdk_nvme_cmd cmd = {};
1231b28efb5SChangpeng Liu 	struct iovec iovs[33];
1241b28efb5SChangpeng Liu 	uint64_t phy_addr;
1251b28efb5SChangpeng Liu 	uint32_t len;
1261b28efb5SChangpeng Liu 	void *buf, *sgls;
1271b28efb5SChangpeng Liu 	struct spdk_nvme_sgl_descriptor *sgl;
1281b28efb5SChangpeng Liu 	int i, ret;
1291b28efb5SChangpeng Liu 	size_t mps = 4096;
1301b28efb5SChangpeng Liu 
1311b28efb5SChangpeng Liu 	buf = spdk_zmalloc(132 * 1024, 4096, &phy_addr, 0, 0);
1321b28efb5SChangpeng Liu 	CU_ASSERT(buf != NULL);
1331b28efb5SChangpeng Liu 	sgls = spdk_zmalloc(4096, 4096, &phy_addr, 0, 0);
1341b28efb5SChangpeng Liu 	CU_ASSERT(sgls != NULL);
1351b28efb5SChangpeng Liu 
1361b28efb5SChangpeng Liu 	/* test case 1: 8KiB with 1 data block */
1371b28efb5SChangpeng Liu 	len = 8192;
1381b28efb5SChangpeng Liu 	cmd.dptr.sgl1.unkeyed.type = SPDK_NVME_SGL_TYPE_DATA_BLOCK;
1391b28efb5SChangpeng Liu 	cmd.dptr.sgl1.unkeyed.length = len;
1401b28efb5SChangpeng Liu 	cmd.dptr.sgl1.address = (uint64_t)(uintptr_t)buf;
1411b28efb5SChangpeng Liu 
1421b28efb5SChangpeng Liu 	ret = nvme_cmd_map_sgls(NULL, &cmd, iovs, 33, len, mps, gpa_to_vva);
1431b28efb5SChangpeng Liu 	CU_ASSERT(ret == 1);
1441b28efb5SChangpeng Liu 	CU_ASSERT(iovs[0].iov_base == buf);
1451b28efb5SChangpeng Liu 	CU_ASSERT(iovs[0].iov_len == 8192);
1461b28efb5SChangpeng Liu 
1471b28efb5SChangpeng Liu 	/* test case 2: 8KiB with 2 data blocks and 1 last segment */
1481b28efb5SChangpeng Liu 	sgl = (struct spdk_nvme_sgl_descriptor *)sgls;
1491b28efb5SChangpeng Liu 	sgl[0].unkeyed.type = SPDK_NVME_SGL_TYPE_DATA_BLOCK;
1501b28efb5SChangpeng Liu 	sgl[0].unkeyed.length = 2048;
1511b28efb5SChangpeng Liu 	sgl[0].address = (uint64_t)(uintptr_t)buf;
1521b28efb5SChangpeng Liu 	sgl[1].unkeyed.type = SPDK_NVME_SGL_TYPE_DATA_BLOCK;
1531b28efb5SChangpeng Liu 	sgl[1].unkeyed.length = len - 2048;
1541b28efb5SChangpeng Liu 	sgl[1].address = (uint64_t)(uintptr_t)buf + 16 * 1024;
1551b28efb5SChangpeng Liu 
1561b28efb5SChangpeng Liu 	cmd.dptr.sgl1.unkeyed.type = SPDK_NVME_SGL_TYPE_LAST_SEGMENT;
1571b28efb5SChangpeng Liu 	cmd.dptr.sgl1.unkeyed.length = 2 * sizeof(*sgl);
1581b28efb5SChangpeng Liu 	cmd.dptr.sgl1.address = (uint64_t)(uintptr_t)sgls;
1591b28efb5SChangpeng Liu 
1601b28efb5SChangpeng Liu 	ret = nvme_cmd_map_sgls(NULL, &cmd, iovs, 33, len, mps, gpa_to_vva);
1611b28efb5SChangpeng Liu 	CU_ASSERT(ret == 2);
1621b28efb5SChangpeng Liu 	CU_ASSERT(iovs[0].iov_base == (void *)(uintptr_t)buf);
1631b28efb5SChangpeng Liu 	CU_ASSERT(iovs[0].iov_len == 2048);
1641b28efb5SChangpeng Liu 	CU_ASSERT(iovs[1].iov_base == (void *)((uintptr_t)buf + 16 * 1024));
1651b28efb5SChangpeng Liu 	CU_ASSERT(iovs[1].iov_len == len - 2048);
1661b28efb5SChangpeng Liu 
1671b28efb5SChangpeng Liu 	/* test case 3: 8KiB with 1 segment, 1 last segment and 3 data blocks */
1681b28efb5SChangpeng Liu 	sgl[0].unkeyed.type = SPDK_NVME_SGL_TYPE_DATA_BLOCK;
1691b28efb5SChangpeng Liu 	sgl[0].unkeyed.length = 2048;
1701b28efb5SChangpeng Liu 	sgl[0].address = (uint64_t)(uintptr_t)buf;
1711b28efb5SChangpeng Liu 	sgl[1].unkeyed.type = SPDK_NVME_SGL_TYPE_LAST_SEGMENT;
1721b28efb5SChangpeng Liu 	sgl[1].unkeyed.length = 2 * sizeof(*sgl);
1731b28efb5SChangpeng Liu 	sgl[1].address = (uint64_t)(uintptr_t)&sgl[9];
1741b28efb5SChangpeng Liu 
1751b28efb5SChangpeng Liu 	sgl[9].unkeyed.type = SPDK_NVME_SGL_TYPE_DATA_BLOCK;
1761b28efb5SChangpeng Liu 	sgl[9].unkeyed.length = 4096;
1771b28efb5SChangpeng Liu 	sgl[9].address = (uint64_t)(uintptr_t)buf + 4 * 1024;
1781b28efb5SChangpeng Liu 	sgl[10].unkeyed.type = SPDK_NVME_SGL_TYPE_DATA_BLOCK;
1791b28efb5SChangpeng Liu 	sgl[10].unkeyed.length = 2048;
1801b28efb5SChangpeng Liu 	sgl[10].address = (uint64_t)(uintptr_t)buf + 16 * 1024;
1811b28efb5SChangpeng Liu 
1821b28efb5SChangpeng Liu 	cmd.dptr.sgl1.unkeyed.type = SPDK_NVME_SGL_TYPE_SEGMENT;
1831b28efb5SChangpeng Liu 	cmd.dptr.sgl1.unkeyed.length = 2 * sizeof(*sgl);
1841b28efb5SChangpeng Liu 	cmd.dptr.sgl1.address = (uint64_t)(uintptr_t)&sgl[0];
1851b28efb5SChangpeng Liu 
1861b28efb5SChangpeng Liu 	ret = nvme_cmd_map_sgls(NULL, &cmd, iovs, 33, len, mps, gpa_to_vva);
1871b28efb5SChangpeng Liu 	CU_ASSERT(ret == 3);
1881b28efb5SChangpeng Liu 	CU_ASSERT(iovs[0].iov_base == (void *)(uintptr_t)buf);
1891b28efb5SChangpeng Liu 	CU_ASSERT(iovs[0].iov_len == 2048);
1901b28efb5SChangpeng Liu 	CU_ASSERT(iovs[1].iov_base == (void *)((uintptr_t)buf + 4 * 1024));
1911b28efb5SChangpeng Liu 	CU_ASSERT(iovs[1].iov_len == 4096);
1921b28efb5SChangpeng Liu 	CU_ASSERT(iovs[2].iov_base == (void *)((uintptr_t)buf + 16 * 1024));
1931b28efb5SChangpeng Liu 	CU_ASSERT(iovs[2].iov_len == 2048);
1941b28efb5SChangpeng Liu 
1951b28efb5SChangpeng Liu 	/* test case 4: not enough iovs */
1961b28efb5SChangpeng Liu 	len = 12 * 1024;
1971b28efb5SChangpeng Liu 	for (i = 0; i < 6; i++) {
1981b28efb5SChangpeng Liu 		sgl[0].unkeyed.type = SPDK_NVME_SGL_TYPE_DATA_BLOCK;
1991b28efb5SChangpeng Liu 		sgl[0].unkeyed.length = 2048;
2001b28efb5SChangpeng Liu 		sgl[0].address = (uint64_t)(uintptr_t)buf + i * 4096;
2011b28efb5SChangpeng Liu 	}
2021b28efb5SChangpeng Liu 
2031b28efb5SChangpeng Liu 	cmd.dptr.sgl1.unkeyed.type = SPDK_NVME_SGL_TYPE_LAST_SEGMENT;
2041b28efb5SChangpeng Liu 	cmd.dptr.sgl1.unkeyed.length = 6 * sizeof(*sgl);
2051b28efb5SChangpeng Liu 	cmd.dptr.sgl1.address = (uint64_t)(uintptr_t)sgls;
2061b28efb5SChangpeng Liu 
2071b28efb5SChangpeng Liu 	ret = nvme_cmd_map_sgls(NULL, &cmd, iovs, 4, len, mps, gpa_to_vva);
2081b28efb5SChangpeng Liu 	CU_ASSERT(ret == -ERANGE);
2091b28efb5SChangpeng Liu 
2101b28efb5SChangpeng Liu 	spdk_free(buf);
2111b28efb5SChangpeng Liu 	spdk_free(sgls);
2121b28efb5SChangpeng Liu }
2131b28efb5SChangpeng Liu 
214a43f891eSMao Jiang static void
215a43f891eSMao Jiang ut_transport_destroy_done_cb(void *cb_arg)
216a43f891eSMao Jiang {
217a43f891eSMao Jiang 	int *done = cb_arg;
218a43f891eSMao Jiang 	*done = 1;
219a43f891eSMao Jiang }
220a43f891eSMao Jiang 
221a43f891eSMao Jiang static void
222a43f891eSMao Jiang test_nvmf_vfio_user_create_destroy(void)
223a43f891eSMao Jiang {
224a43f891eSMao Jiang 	struct spdk_nvmf_transport *transport = NULL;
225a43f891eSMao Jiang 	struct nvmf_vfio_user_transport *vu_transport = NULL;
226a43f891eSMao Jiang 	struct nvmf_vfio_user_endpoint *endpoint = NULL;
227a43f891eSMao Jiang 	struct spdk_nvmf_transport_opts opts = {};
228a43f891eSMao Jiang 	int rc;
229a43f891eSMao Jiang 	int done;
230a43f891eSMao Jiang 
231a43f891eSMao Jiang 	/* Initialize transport_specific NULL to avoid decoding json */
232a43f891eSMao Jiang 	opts.transport_specific = NULL;
233a43f891eSMao Jiang 
234a43f891eSMao Jiang 	transport = nvmf_vfio_user_create(&opts);
235a43f891eSMao Jiang 	CU_ASSERT(transport != NULL);
236a43f891eSMao Jiang 
237a43f891eSMao Jiang 	vu_transport = SPDK_CONTAINEROF(transport, struct nvmf_vfio_user_transport,
238a43f891eSMao Jiang 					transport);
239a43f891eSMao Jiang 	/* Allocate a endpoint for destroy */
240a43f891eSMao Jiang 	endpoint = calloc(1, sizeof(*endpoint));
241a43f891eSMao Jiang 	pthread_mutex_init(&endpoint->lock, NULL);
242a43f891eSMao Jiang 	TAILQ_INSERT_TAIL(&vu_transport->endpoints, endpoint, link);
243a43f891eSMao Jiang 	done = 0;
244a43f891eSMao Jiang 
245a43f891eSMao Jiang 	rc = nvmf_vfio_user_destroy(transport, ut_transport_destroy_done_cb, &done);
246a43f891eSMao Jiang 	CU_ASSERT(rc == 0);
247a43f891eSMao Jiang 	CU_ASSERT(done == 1);
248a43f891eSMao Jiang }
249a43f891eSMao Jiang 
2508dd1cd21SBen Walker int
2518dd1cd21SBen Walker main(int argc, char **argv)
2521b28efb5SChangpeng Liu {
2531b28efb5SChangpeng Liu 	CU_pSuite	suite = NULL;
2541b28efb5SChangpeng Liu 	unsigned int	num_failures;
2551b28efb5SChangpeng Liu 
2561b28efb5SChangpeng Liu 	CU_initialize_registry();
2571b28efb5SChangpeng Liu 
2581b28efb5SChangpeng Liu 	suite = CU_add_suite("vfio_user", NULL, NULL);
2591b28efb5SChangpeng Liu 
2601b28efb5SChangpeng Liu 	CU_ADD_TEST(suite, test_nvme_cmd_map_prps);
2611b28efb5SChangpeng Liu 	CU_ADD_TEST(suite, test_nvme_cmd_map_sgls);
262a43f891eSMao Jiang 	CU_ADD_TEST(suite, test_nvmf_vfio_user_create_destroy);
2631b28efb5SChangpeng Liu 
264ea941caeSKonrad Sztyber 	num_failures = spdk_ut_run_tests(argc, argv, NULL);
2651b28efb5SChangpeng Liu 	CU_cleanup_registry();
2661b28efb5SChangpeng Liu 	return num_failures;
2671b28efb5SChangpeng Liu }
268