Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2017 Intel Corporation.
3 : : * All rights reserved.
4 : : * Copyright (c) 2021 Mellanox Technologies LTD. All rights reserved.
5 : : */
6 : :
7 : : #include "spdk/stdinc.h"
8 : :
9 : : #include "spdk_internal/cunit.h"
10 : :
11 : : #define UNIT_TEST_NO_VTOPHYS
12 : :
13 : : #include "nvme/nvme_pcie.c"
14 : : #include "nvme/nvme_pcie_common.c"
15 : : #include "common/lib/nvme/common_stubs.h"
16 : :
17 : : pid_t g_spdk_nvme_pid;
18 [ - + ]: 6 : DEFINE_STUB(spdk_mem_register, int, (void *vaddr, size_t len), 0);
19 [ - + ]: 3 : DEFINE_STUB(spdk_mem_unregister, int, (void *vaddr, size_t len), 0);
20 : :
21 [ # # ]: 0 : DEFINE_STUB(nvme_get_quirks, uint64_t, (const struct spdk_pci_id *id), 0);
22 : :
23 [ # # ]: 0 : DEFINE_STUB(nvme_wait_for_completion, int,
24 : : (struct spdk_nvme_qpair *qpair,
25 : : struct nvme_completion_poll_status *status), 0);
26 : 0 : DEFINE_STUB_V(nvme_completion_poll_cb, (void *arg, const struct spdk_nvme_cpl *cpl));
27 : :
28 [ # # ]: 0 : DEFINE_STUB(nvme_ctrlr_submit_admin_request, int, (struct spdk_nvme_ctrlr *ctrlr,
29 : : struct nvme_request *req), 0);
30 : :
31 [ # # ]: 0 : DEFINE_STUB(nvme_ctrlr_proc_get_devhandle, struct spdk_pci_device *,
32 : : (struct spdk_nvme_ctrlr *ctrlr), NULL);
33 [ # # ]: 0 : DEFINE_STUB(spdk_nvme_ctrlr_get_numa_id, int32_t, (struct spdk_nvme_ctrlr *ctrlr),
34 : : SPDK_ENV_NUMA_ID_ANY);
35 : :
36 [ - + ]: 6 : DEFINE_STUB(spdk_pci_device_unmap_bar, int, (struct spdk_pci_device *dev, uint32_t bar, void *addr),
37 : : 0);
38 [ # # ]: 0 : DEFINE_STUB(spdk_pci_device_attach, int, (struct spdk_pci_driver *driver, spdk_pci_enum_cb enum_cb,
39 : : void *enum_ctx, struct spdk_pci_addr *pci_address), 0);
40 [ # # ]: 0 : DEFINE_STUB(spdk_pci_device_claim, int, (struct spdk_pci_device *dev), 0);
41 : 0 : DEFINE_STUB_V(spdk_pci_device_unclaim, (struct spdk_pci_device *dev));
42 : 0 : DEFINE_STUB_V(spdk_pci_device_detach, (struct spdk_pci_device *device));
43 [ # # ]: 0 : DEFINE_STUB(spdk_pci_device_cfg_write16, int, (struct spdk_pci_device *dev, uint16_t value,
44 : : uint32_t offset), 0);
45 [ # # ]: 0 : DEFINE_STUB(spdk_pci_device_cfg_read16, int, (struct spdk_pci_device *dev, uint16_t *value,
46 : : uint32_t offset), 0);
47 [ # # ]: 0 : DEFINE_STUB(spdk_pci_device_get_id, struct spdk_pci_id, (struct spdk_pci_device *dev), {0});
48 [ # # ]: 0 : DEFINE_STUB(spdk_pci_event_listen, int, (void), 0);
49 [ # # ]: 0 : DEFINE_STUB(spdk_pci_register_error_handler, int, (spdk_pci_error_handler sighandler, void *ctx),
50 : : 0);
51 : 0 : DEFINE_STUB_V(spdk_pci_unregister_error_handler, (spdk_pci_error_handler sighandler));
52 [ # # ]: 0 : DEFINE_STUB(spdk_pci_enumerate, int,
53 : : (struct spdk_pci_driver *driver, spdk_pci_enum_cb enum_cb, void *enum_ctx),
54 : : -1);
55 : :
56 : 3 : SPDK_LOG_REGISTER_COMPONENT(nvme)
57 : :
58 : : struct dev_mem_resource {
59 : : uint64_t phys_addr;
60 : : uint64_t len;
61 : : void *addr;
62 : : };
63 : :
64 : : struct nvme_pcie_ut_bdev_io {
65 : : struct iovec iovs[NVME_MAX_SGL_DESCRIPTORS];
66 : : int iovpos;
67 : : };
68 : :
69 : : struct nvme_driver *g_spdk_nvme_driver = NULL;
70 : :
71 : : int
72 : 6 : spdk_pci_device_map_bar(struct spdk_pci_device *dev, uint32_t bar,
73 : : void **mapped_addr, uint64_t *phys_addr, uint64_t *size)
74 : : {
75 : 6 : struct dev_mem_resource *dev_mem_res = (void *)dev;
76 : :
77 : 6 : *mapped_addr = dev_mem_res->addr;
78 : 6 : *phys_addr = dev_mem_res->phys_addr;
79 : 6 : *size = dev_mem_res->len;
80 : :
81 : 6 : return 0;
82 : : }
83 : :
84 : : void
85 : 9 : nvme_ctrlr_fail(struct spdk_nvme_ctrlr *ctrlr, bool hot_remove)
86 : : {
87 : 9 : CU_ASSERT(ctrlr != NULL);
88 [ + - ]: 9 : if (hot_remove) {
89 : 9 : ctrlr->is_removed = true;
90 : : }
91 : :
92 : 9 : ctrlr->is_failed = true;
93 : 9 : }
94 : :
95 : : static uint64_t g_vtophys_size = 0;
96 : :
97 [ # # ]: 0 : DEFINE_RETURN_MOCK(spdk_vtophys, uint64_t);
98 : : uint64_t
99 : 6165 : spdk_vtophys(const void *buf, uint64_t *size)
100 : : {
101 [ + + + + ]: 6165 : if (size && g_vtophys_size > 0) {
102 : 30 : *size = g_vtophys_size;
103 : : }
104 : :
105 [ - + + + : 6165 : HANDLE_RETURN_MOCK(spdk_vtophys);
+ + ]
106 : :
107 : 6135 : return (uintptr_t)buf;
108 : : }
109 : :
110 [ # # ]: 0 : DEFINE_STUB(spdk_pci_device_get_addr, struct spdk_pci_addr, (struct spdk_pci_device *dev), {});
111 [ # # ]: 0 : DEFINE_STUB(nvme_ctrlr_probe, int, (const struct spdk_nvme_transport_id *trid,
112 : : struct spdk_nvme_probe_ctx *probe_ctx, void *devhandle), 0);
113 [ - + - + ]: 9 : DEFINE_STUB(spdk_pci_device_is_removed, bool, (struct spdk_pci_device *dev), false);
114 [ - + ]: 3 : DEFINE_STUB(nvme_get_ctrlr_by_trid_unsafe, struct spdk_nvme_ctrlr *,
115 : : (const struct spdk_nvme_transport_id *trid, const char *hostnqn), NULL);
116 [ # # ]: 0 : DEFINE_STUB(spdk_nvme_ctrlr_get_regs_csts, union spdk_nvme_csts_register,
117 : : (struct spdk_nvme_ctrlr *ctrlr), {});
118 [ # # ]: 0 : DEFINE_STUB(nvme_ctrlr_get_process, struct spdk_nvme_ctrlr_process *,
119 : : (struct spdk_nvme_ctrlr *ctrlr, pid_t pid), NULL);
120 [ # # # # ]: 0 : DEFINE_STUB(nvme_completion_is_retry, bool, (const struct spdk_nvme_cpl *cpl), false);
121 : 0 : DEFINE_STUB_V(spdk_nvme_qpair_print_command, (struct spdk_nvme_qpair *qpair,
122 : : struct spdk_nvme_cmd *cmd));
123 : 0 : DEFINE_STUB_V(spdk_nvme_qpair_print_completion, (struct spdk_nvme_qpair *qpair,
124 : : struct spdk_nvme_cpl *cpl));
125 : :
126 : : static void
127 : 63 : prp_list_prep(struct nvme_tracker *tr, struct nvme_request *req, uint32_t *prp_index)
128 : : {
129 [ - + ]: 63 : memset(req, 0, sizeof(*req));
130 [ - + ]: 63 : memset(tr, 0, sizeof(*tr));
131 : 63 : tr->req = req;
132 : 63 : tr->prp_sgl_bus_addr = 0xDEADBEEF;
133 [ + + ]: 63 : if (prp_index) {
134 : 51 : *prp_index = 0;
135 : : }
136 : 63 : }
137 : :
138 : : static void
139 : 3 : test_prp_list_append(void)
140 : : {
141 : 3 : struct nvme_request req;
142 : 3 : struct nvme_tracker tr;
143 : 3 : struct spdk_nvme_ctrlr ctrlr = {};
144 : 3 : uint32_t prp_index;
145 : :
146 : 3 : ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_PCIE;
147 : : /* Non-DWORD-aligned buffer (invalid) */
148 : 3 : prp_list_prep(&tr, &req, &prp_index);
149 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x100001, 0x1000,
150 : : 0x1000) == -EFAULT);
151 : :
152 : : /* 512-byte buffer, 4K aligned */
153 : 3 : prp_list_prep(&tr, &req, &prp_index);
154 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x100000, 0x200, 0x1000) == 0);
155 : 3 : CU_ASSERT(prp_index == 1);
156 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp1 == 0x100000);
157 : :
158 : : /* 512-byte buffer, non-4K-aligned */
159 : 3 : prp_list_prep(&tr, &req, &prp_index);
160 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x108000, 0x200, 0x1000) == 0);
161 : 3 : CU_ASSERT(prp_index == 1);
162 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp1 == 0x108000);
163 : :
164 : : /* 4K buffer, 4K aligned */
165 : 3 : prp_list_prep(&tr, &req, &prp_index);
166 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x100000, 0x1000,
167 : : 0x1000) == 0);
168 : 3 : CU_ASSERT(prp_index == 1);
169 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp1 == 0x100000);
170 : :
171 : : /* 4K buffer, non-4K aligned */
172 : 3 : prp_list_prep(&tr, &req, &prp_index);
173 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x100800, 0x1000,
174 : : 0x1000) == 0);
175 : 3 : CU_ASSERT(prp_index == 2);
176 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp1 == 0x100800);
177 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp2 == 0x101000);
178 : :
179 : : /* 8K buffer, 4K aligned */
180 : 3 : prp_list_prep(&tr, &req, &prp_index);
181 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x100000, 0x2000,
182 : : 0x1000) == 0);
183 : 3 : CU_ASSERT(prp_index == 2);
184 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp1 == 0x100000);
185 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp2 == 0x101000);
186 : :
187 : : /* 8K buffer, non-4K aligned */
188 : 3 : prp_list_prep(&tr, &req, &prp_index);
189 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x100800, 0x2000,
190 : : 0x1000) == 0);
191 : 3 : CU_ASSERT(prp_index == 3);
192 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp1 == 0x100800);
193 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp2 == tr.prp_sgl_bus_addr);
194 : 3 : CU_ASSERT(tr.u.prp[0] == 0x101000);
195 : 3 : CU_ASSERT(tr.u.prp[1] == 0x102000);
196 : :
197 : : /* 12K buffer, 4K aligned */
198 : 3 : prp_list_prep(&tr, &req, &prp_index);
199 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x100000, 0x3000,
200 : : 0x1000) == 0);
201 : 3 : CU_ASSERT(prp_index == 3);
202 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp1 == 0x100000);
203 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp2 == tr.prp_sgl_bus_addr);
204 : 3 : CU_ASSERT(tr.u.prp[0] == 0x101000);
205 : 3 : CU_ASSERT(tr.u.prp[1] == 0x102000);
206 : :
207 : : /* 12K buffer, non-4K aligned */
208 : 3 : prp_list_prep(&tr, &req, &prp_index);
209 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x100800, 0x3000,
210 : : 0x1000) == 0);
211 : 3 : CU_ASSERT(prp_index == 4);
212 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp1 == 0x100800);
213 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp2 == tr.prp_sgl_bus_addr);
214 : 3 : CU_ASSERT(tr.u.prp[0] == 0x101000);
215 : 3 : CU_ASSERT(tr.u.prp[1] == 0x102000);
216 : 3 : CU_ASSERT(tr.u.prp[2] == 0x103000);
217 : :
218 : : /* Two 4K buffers, both 4K aligned */
219 : 3 : prp_list_prep(&tr, &req, &prp_index);
220 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x100000, 0x1000,
221 : : 0x1000) == 0);
222 : 3 : CU_ASSERT(prp_index == 1);
223 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x900000, 0x1000,
224 : : 0x1000) == 0);
225 : 3 : CU_ASSERT(prp_index == 2);
226 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp1 == 0x100000);
227 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp2 == 0x900000);
228 : :
229 : : /* Two 4K buffers, first non-4K aligned, second 4K aligned */
230 : 3 : prp_list_prep(&tr, &req, &prp_index);
231 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x100800, 0x1000,
232 : : 0x1000) == 0);
233 : 3 : CU_ASSERT(prp_index == 2);
234 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x900000, 0x1000,
235 : : 0x1000) == 0);
236 : 3 : CU_ASSERT(prp_index == 3);
237 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp1 == 0x100800);
238 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp2 == tr.prp_sgl_bus_addr);
239 : 3 : CU_ASSERT(tr.u.prp[0] == 0x101000);
240 : 3 : CU_ASSERT(tr.u.prp[1] == 0x900000);
241 : :
242 : : /* Two 4K buffers, both non-4K aligned (invalid) */
243 : 3 : prp_list_prep(&tr, &req, &prp_index);
244 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x100800, 0x1000,
245 : : 0x1000) == 0);
246 : 3 : CU_ASSERT(prp_index == 2);
247 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x900800, 0x1000,
248 : : 0x1000) == -EFAULT);
249 : 3 : CU_ASSERT(prp_index == 2);
250 : :
251 : : /* 4K buffer, 4K aligned, but vtophys fails */
252 : 3 : MOCK_SET(spdk_vtophys, SPDK_VTOPHYS_ERROR);
253 : 3 : prp_list_prep(&tr, &req, &prp_index);
254 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x100000, 0x1000,
255 : : 0x1000) == -EFAULT);
256 [ - - - + ]: 3 : MOCK_CLEAR(spdk_vtophys);
257 : :
258 : : /* Largest aligned buffer that can be described in NVME_MAX_PRP_LIST_ENTRIES (plus PRP1) */
259 : 3 : prp_list_prep(&tr, &req, &prp_index);
260 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x100000,
261 : : (NVME_MAX_PRP_LIST_ENTRIES + 1) * 0x1000, 0x1000) == 0);
262 : 3 : CU_ASSERT(prp_index == NVME_MAX_PRP_LIST_ENTRIES + 1);
263 : :
264 : : /* Largest non-4K-aligned buffer that can be described in NVME_MAX_PRP_LIST_ENTRIES (plus PRP1) */
265 : 3 : prp_list_prep(&tr, &req, &prp_index);
266 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x100800,
267 : : NVME_MAX_PRP_LIST_ENTRIES * 0x1000, 0x1000) == 0);
268 : 3 : CU_ASSERT(prp_index == NVME_MAX_PRP_LIST_ENTRIES + 1);
269 : :
270 : : /* Buffer too large to be described in NVME_MAX_PRP_LIST_ENTRIES */
271 : 3 : prp_list_prep(&tr, &req, &prp_index);
272 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x100000,
273 : : (NVME_MAX_PRP_LIST_ENTRIES + 2) * 0x1000, 0x1000) == -EFAULT);
274 : :
275 : : /* Non-4K-aligned buffer too large to be described in NVME_MAX_PRP_LIST_ENTRIES */
276 : 3 : prp_list_prep(&tr, &req, &prp_index);
277 : 3 : CU_ASSERT(nvme_pcie_prp_list_append(&ctrlr, &tr, &prp_index, (void *)0x100800,
278 : : (NVME_MAX_PRP_LIST_ENTRIES + 1) * 0x1000, 0x1000) == -EFAULT);
279 : 3 : }
280 : :
281 : : struct spdk_event_entry {
282 : : struct spdk_pci_event event;
283 : : STAILQ_ENTRY(spdk_event_entry) link;
284 : : };
285 : :
286 : : static STAILQ_HEAD(, spdk_event_entry) g_events = STAILQ_HEAD_INITIALIZER(g_events);
287 : : static bool g_device_allowed = false;
288 : :
289 : : int
290 : 21 : spdk_pci_get_event(int fd, struct spdk_pci_event *event)
291 : : {
292 : : struct spdk_event_entry *entry;
293 : :
294 [ + + ]: 21 : if (STAILQ_EMPTY(&g_events)) {
295 : 15 : return 0;
296 : : }
297 : :
298 : 6 : entry = STAILQ_FIRST(&g_events);
299 [ + - ]: 6 : STAILQ_REMOVE_HEAD(&g_events, link);
300 : :
301 : 6 : *event = entry->event;
302 : :
303 : 6 : return 1;
304 : : }
305 : :
306 : : int
307 : 3 : spdk_pci_device_allow(struct spdk_pci_addr *pci_addr)
308 : : {
309 : 3 : g_device_allowed = true;
310 : :
311 : 3 : return 0;
312 : : }
313 : :
314 : : static void
315 : 3 : test_nvme_pcie_hotplug_monitor(void)
316 : : {
317 : 3 : struct nvme_pcie_ctrlr pctrlr = {};
318 : 3 : struct spdk_event_entry entry = {};
319 : 3 : struct nvme_driver driver;
320 : 3 : pthread_mutexattr_t attr;
321 : 3 : struct spdk_nvme_probe_ctx test_nvme_probe_ctx = {};
322 : :
323 : : /* Initiate variables and ctrlr */
324 : 3 : driver.initialized = true;
325 : 3 : driver.hotplug_fd = 123;
326 [ - + ]: 3 : CU_ASSERT(pthread_mutexattr_init(&attr) == 0);
327 [ - + ]: 3 : CU_ASSERT(pthread_mutex_init(&pctrlr.ctrlr.ctrlr_lock, &attr) == 0);
328 [ - + ]: 3 : CU_ASSERT(pthread_mutex_init(&driver.lock, &attr) == 0);
329 : 3 : TAILQ_INIT(&driver.shared_attached_ctrlrs);
330 : 3 : g_spdk_nvme_driver = &driver;
331 : :
332 : : /* Case 1: SPDK_NVME_UEVENT_ADD/ NVME_VFIO / NVME_UIO */
333 : 3 : entry.event.action = SPDK_UEVENT_ADD;
334 : 3 : spdk_pci_addr_parse(&entry.event.traddr, "0000:05:00.0");
335 : 3 : CU_ASSERT(STAILQ_EMPTY(&g_events));
336 : 3 : STAILQ_INSERT_TAIL(&g_events, &entry, link);
337 : :
338 : 3 : _nvme_pcie_hotplug_monitor(&test_nvme_probe_ctx);
339 : :
340 : 3 : CU_ASSERT(STAILQ_EMPTY(&g_events));
341 [ - + ]: 3 : CU_ASSERT(g_device_allowed == true);
342 : 3 : g_device_allowed = false;
343 : :
344 : : /* Case 2: SPDK_NVME_UEVENT_REMOVE/ NVME_UIO */
345 : 3 : entry.event.action = SPDK_UEVENT_REMOVE;
346 : 3 : spdk_pci_addr_parse(&entry.event.traddr, "0000:05:00.0");
347 : 3 : CU_ASSERT(STAILQ_EMPTY(&g_events));
348 : 3 : STAILQ_INSERT_TAIL(&g_events, &entry, link);
349 : :
350 : 3 : MOCK_SET(nvme_get_ctrlr_by_trid_unsafe, &pctrlr.ctrlr);
351 : :
352 : 3 : _nvme_pcie_hotplug_monitor(&test_nvme_probe_ctx);
353 : :
354 : 3 : CU_ASSERT(STAILQ_EMPTY(&g_events));
355 [ - + ]: 3 : CU_ASSERT(pctrlr.ctrlr.is_failed == true);
356 [ - + ]: 3 : CU_ASSERT(pctrlr.ctrlr.is_removed == true);
357 : 3 : pctrlr.ctrlr.is_failed = false;
358 : 3 : pctrlr.ctrlr.is_removed = false;
359 [ - - - + ]: 3 : MOCK_CLEAR(nvme_get_ctrlr_by_trid_unsafe);
360 : :
361 : : /* Case 3: SPDK_NVME_UEVENT_REMOVE/ NVME_VFIO without event */
362 : 3 : pctrlr.ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_PCIE;
363 [ - + ]: 3 : snprintf(pctrlr.ctrlr.trid.traddr, sizeof(pctrlr.ctrlr.trid.traddr), "0000:02:00.0");
364 : 3 : pctrlr.ctrlr.remove_cb = NULL;
365 : 3 : pctrlr.ctrlr.is_failed = false;
366 : 3 : pctrlr.ctrlr.is_removed = false;
367 : 3 : TAILQ_INSERT_TAIL(&g_spdk_nvme_driver->shared_attached_ctrlrs, &pctrlr.ctrlr, tailq);
368 : :
369 : : /* This should be set in the vfio req notifier cb */
370 : 3 : MOCK_SET(spdk_pci_device_is_removed, true);
371 : :
372 : 3 : _nvme_pcie_hotplug_monitor(&test_nvme_probe_ctx);
373 : :
374 : 3 : CU_ASSERT(STAILQ_EMPTY(&g_events));
375 [ - + ]: 3 : CU_ASSERT(pctrlr.ctrlr.is_failed == true);
376 [ - + ]: 3 : CU_ASSERT(pctrlr.ctrlr.is_removed == true);
377 : 3 : pctrlr.ctrlr.is_failed = false;
378 : 3 : pctrlr.ctrlr.is_removed = false;
379 [ - - - + ]: 3 : MOCK_CLEAR(spdk_pci_device_is_removed);
380 : :
381 : : /* Case 4: Removed device detected in another process */
382 : 3 : MOCK_SET(spdk_pci_device_is_removed, false);
383 : :
384 : 3 : _nvme_pcie_hotplug_monitor(&test_nvme_probe_ctx);
385 : :
386 [ - + ]: 3 : CU_ASSERT(pctrlr.ctrlr.is_failed == false);
387 : :
388 : 3 : MOCK_SET(spdk_pci_device_is_removed, true);
389 : :
390 : 3 : _nvme_pcie_hotplug_monitor(&test_nvme_probe_ctx);
391 : :
392 [ - + ]: 3 : CU_ASSERT(pctrlr.ctrlr.is_failed == true);
393 : :
394 [ - + ]: 3 : pthread_mutex_destroy(&driver.lock);
395 [ - + ]: 3 : pthread_mutex_destroy(&pctrlr.ctrlr.ctrlr_lock);
396 [ - + ]: 3 : pthread_mutexattr_destroy(&attr);
397 : 3 : g_spdk_nvme_driver = NULL;
398 : 3 : }
399 : :
400 : : static void
401 : 3 : test_shadow_doorbell_update(void)
402 : : {
403 : : bool ret;
404 : :
405 : : /* nvme_pcie_qpair_need_event(uint16_t event_idx, uint16_t new_idx, uint16_t old) */
406 : 3 : ret = nvme_pcie_qpair_need_event(10, 15, 14);
407 : 3 : CU_ASSERT(ret == false);
408 : :
409 : 3 : ret = nvme_pcie_qpair_need_event(14, 15, 14);
410 : 3 : CU_ASSERT(ret == true);
411 : 3 : }
412 : :
413 : : static void
414 : 3 : test_build_contig_hw_sgl_request(void)
415 : : {
416 : 3 : struct spdk_nvme_qpair qpair = {};
417 : 3 : struct nvme_request req = {};
418 : 3 : struct nvme_tracker tr = {};
419 : 3 : struct spdk_nvme_ctrlr ctrlr = {};
420 : : int rc;
421 : :
422 : 3 : ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_PCIE;
423 : 3 : qpair.ctrlr = &ctrlr;
424 : : /* Test 1: Payload covered by a single mapping */
425 : 3 : req.payload_size = 100;
426 : 3 : req.payload = NVME_PAYLOAD_CONTIG((void *)0xbeef0, NULL);
427 : 3 : g_vtophys_size = 100;
428 : 3 : MOCK_SET(spdk_vtophys, 0xDEADBEEF);
429 : :
430 : 3 : rc = nvme_pcie_qpair_build_contig_hw_sgl_request(&qpair, &req, &tr, 0);
431 : 3 : CU_ASSERT(rc == 0);
432 : 3 : CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
433 : 3 : CU_ASSERT(req.cmd.dptr.sgl1.address == 0xDEADBEEF);
434 : 3 : CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.length == 100);
435 : :
436 [ - - - + ]: 3 : MOCK_CLEAR(spdk_vtophys);
437 : 3 : g_vtophys_size = 0;
438 [ - + ]: 3 : memset(&qpair, 0, sizeof(qpair));
439 [ - + ]: 3 : memset(&req, 0, sizeof(req));
440 [ - + ]: 3 : memset(&tr, 0, sizeof(tr));
441 : :
442 : : /* Test 2: Payload covered by a single mapping, but request is at an offset */
443 : 3 : qpair.ctrlr = &ctrlr;
444 : 3 : req.payload_size = 100;
445 : 3 : req.payload_offset = 50;
446 : 3 : req.payload = NVME_PAYLOAD_CONTIG((void *)0xbeef0, NULL);
447 : 3 : g_vtophys_size = 1000;
448 : 3 : MOCK_SET(spdk_vtophys, 0xDEADBEEF);
449 : :
450 : 3 : rc = nvme_pcie_qpair_build_contig_hw_sgl_request(&qpair, &req, &tr, 0);
451 : 3 : CU_ASSERT(rc == 0);
452 : 3 : CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
453 : 3 : CU_ASSERT(req.cmd.dptr.sgl1.address == 0xDEADBEEF);
454 : 3 : CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.length == 100);
455 : :
456 [ - - - + ]: 3 : MOCK_CLEAR(spdk_vtophys);
457 : 3 : g_vtophys_size = 0;
458 [ - + ]: 3 : memset(&qpair, 0, sizeof(qpair));
459 [ - + ]: 3 : memset(&req, 0, sizeof(req));
460 [ - + ]: 3 : memset(&tr, 0, sizeof(tr));
461 : :
462 : : /* Test 3: Payload spans two mappings */
463 : 3 : qpair.ctrlr = &ctrlr;
464 : 3 : req.payload_size = 100;
465 : 3 : req.payload = NVME_PAYLOAD_CONTIG((void *)0xbeef0, NULL);
466 : 3 : g_vtophys_size = 60;
467 : 3 : tr.prp_sgl_bus_addr = 0xFF0FF;
468 : 3 : MOCK_SET(spdk_vtophys, 0xDEADBEEF);
469 : :
470 : 3 : rc = nvme_pcie_qpair_build_contig_hw_sgl_request(&qpair, &req, &tr, 0);
471 : 3 : CU_ASSERT(rc == 0);
472 : 3 : CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.type == SPDK_NVME_SGL_TYPE_LAST_SEGMENT);
473 : 3 : CU_ASSERT(req.cmd.dptr.sgl1.address == tr.prp_sgl_bus_addr);
474 : 3 : CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.length == 2 * sizeof(struct spdk_nvme_sgl_descriptor));
475 : 3 : CU_ASSERT(tr.u.sgl[0].unkeyed.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
476 : 3 : CU_ASSERT(tr.u.sgl[0].unkeyed.length == 60);
477 : 3 : CU_ASSERT(tr.u.sgl[0].address == 0xDEADBEEF);
478 : 3 : CU_ASSERT(tr.u.sgl[1].unkeyed.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
479 : 3 : CU_ASSERT(tr.u.sgl[1].unkeyed.length == 40);
480 : 3 : CU_ASSERT(tr.u.sgl[1].address == 0xDEADBEEF);
481 : :
482 [ - - - + ]: 3 : MOCK_CLEAR(spdk_vtophys);
483 : 3 : g_vtophys_size = 0;
484 [ - + ]: 3 : memset(&qpair, 0, sizeof(qpair));
485 [ - + ]: 3 : memset(&req, 0, sizeof(req));
486 [ - + ]: 3 : memset(&tr, 0, sizeof(tr));
487 : 3 : }
488 : :
489 : : static void
490 : 3 : test_nvme_pcie_qpair_build_metadata(void)
491 : : {
492 : 3 : struct nvme_pcie_qpair pqpair = {};
493 : 3 : struct spdk_nvme_qpair *qpair = &pqpair.qpair;
494 : 3 : struct nvme_tracker tr = {};
495 : 3 : struct nvme_request req = {};
496 : 3 : struct spdk_nvme_ctrlr ctrlr = {};
497 : : int rc;
498 : :
499 : 3 : ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_PCIE;
500 : 3 : tr.req = &req;
501 : 3 : qpair->ctrlr = &ctrlr;
502 : :
503 : 3 : req.payload = NVME_PAYLOAD_CONTIG(NULL, (void *)0xDEADBEE0);
504 : 3 : req.md_offset = 0;
505 : 3 : req.md_size = 4096;
506 : : /* The nvme_pcie_qpair_build_metadata() function expects the cmd.psdt
507 : : * is set to SPDK_NVME_PSDT_SGL_MPTR_CONTIG, and then if metadata is
508 : : * built using SGL, cmd.psdt is changed to SPDK_NVME_PSDT_SGL_MPTR_SGL
509 : : * by this function. We need to verify if this indeed is the case.
510 : : */
511 : 3 : req.cmd.psdt = SPDK_NVME_PSDT_SGL_MPTR_CONTIG;
512 : 3 : tr.prp_sgl_bus_addr = 0xDBADBEEF;
513 : 3 : MOCK_SET(spdk_vtophys, 0xDCADBEE0);
514 : :
515 : 3 : rc = nvme_pcie_qpair_build_metadata(qpair, &tr, true, true, true);
516 : 3 : CU_ASSERT(rc == 0);
517 : 3 : CU_ASSERT(req.cmd.psdt == SPDK_NVME_PSDT_SGL_MPTR_SGL);
518 : 3 : CU_ASSERT(tr.meta_sgl.address == 0xDCADBEE0);
519 : 3 : CU_ASSERT(tr.meta_sgl.unkeyed.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
520 : 3 : CU_ASSERT(tr.meta_sgl.unkeyed.length == 4096);
521 : 3 : CU_ASSERT(tr.meta_sgl.unkeyed.subtype == 0);
522 : 3 : CU_ASSERT(req.cmd.mptr == (0xDBADBEEF - sizeof(struct spdk_nvme_sgl_descriptor)));
523 : :
524 : : /* Non-IOVA contiguous metadata buffers should fail. */
525 : 3 : g_vtophys_size = 1024;
526 : 3 : req.cmd.psdt = SPDK_NVME_PSDT_SGL_MPTR_CONTIG;
527 : 3 : rc = nvme_pcie_qpair_build_metadata(qpair, &tr, true, true, true);
528 : 3 : CU_ASSERT(rc == -EINVAL);
529 : 3 : g_vtophys_size = 0;
530 : :
531 [ - - - + ]: 3 : MOCK_CLEAR(spdk_vtophys);
532 : :
533 : : /* Build non sgl metadata */
534 : 3 : MOCK_SET(spdk_vtophys, 0xDDADBEE0);
535 : :
536 : 3 : rc = nvme_pcie_qpair_build_metadata(qpair, &tr, false, false, true);
537 : 3 : CU_ASSERT(rc == 0);
538 : 3 : CU_ASSERT(req.cmd.mptr == 0xDDADBEE0);
539 : :
540 : : /* Build non sgl metadata while sgls are supported */
541 [ - + ]: 3 : memset(&tr.meta_sgl, 0, sizeof(tr.meta_sgl));
542 : : /* If SGLs are supported, but not in metadata, the cmd.psdt
543 : : * shall not be changed to SPDK_NVME_PSDT_SGL_MPTR_SGL
544 : : */
545 : 3 : req.cmd.psdt = SPDK_NVME_PSDT_SGL_MPTR_CONTIG;
546 : 3 : rc = nvme_pcie_qpair_build_metadata(qpair, &tr, true, false, true);
547 : 3 : CU_ASSERT(rc == 0);
548 : 3 : CU_ASSERT(tr.meta_sgl.address == 0);
549 : 3 : CU_ASSERT(tr.meta_sgl.unkeyed.length == 0);
550 : 3 : CU_ASSERT(req.cmd.psdt == SPDK_NVME_PSDT_SGL_MPTR_CONTIG);
551 : 3 : CU_ASSERT(req.cmd.mptr == 0xDDADBEE0);
552 : :
553 : : /* Non-IOVA contiguous metadata buffers should fail. */
554 : 3 : g_vtophys_size = 1024;
555 : 3 : rc = nvme_pcie_qpair_build_metadata(qpair, &tr, false, false, true);
556 : 3 : CU_ASSERT(rc == -EINVAL);
557 : 3 : g_vtophys_size = 0;
558 : :
559 [ - - - + ]: 3 : MOCK_CLEAR(spdk_vtophys);
560 : 3 : }
561 : :
562 : : static int
563 : 15 : nvme_pcie_ut_next_sge(void *cb_arg, void **address, uint32_t *length)
564 : : {
565 : 15 : struct nvme_pcie_ut_bdev_io *bio = cb_arg;
566 : : struct iovec *iov;
567 : :
568 [ - + ]: 15 : SPDK_CU_ASSERT_FATAL(bio->iovpos < NVME_MAX_SGL_DESCRIPTORS);
569 : :
570 : 15 : iov = &bio->iovs[bio->iovpos];
571 : :
572 : 15 : *address = iov->iov_base;
573 : 15 : *length = iov->iov_len;
574 : 15 : bio->iovpos++;
575 : :
576 : 15 : return 0;
577 : : }
578 : :
579 : : static void
580 : 9 : nvme_pcie_ut_reset_sgl(void *cb_arg, uint32_t offset)
581 : : {
582 : 9 : struct nvme_pcie_ut_bdev_io *bio = cb_arg;
583 : : struct iovec *iov;
584 : :
585 [ + - ]: 9 : for (bio->iovpos = 0; bio->iovpos < NVME_MAX_SGL_DESCRIPTORS; bio->iovpos++) {
586 : 9 : iov = &bio->iovs[bio->iovpos];
587 : : /* Offset must be aligned with the start of any SGL entry */
588 [ + - ]: 9 : if (offset == 0) {
589 : 9 : break;
590 : : }
591 : :
592 [ # # ]: 0 : SPDK_CU_ASSERT_FATAL(offset >= iov->iov_len);
593 : 0 : offset -= iov->iov_len;
594 : : }
595 : :
596 [ - + ]: 9 : SPDK_CU_ASSERT_FATAL(offset == 0);
597 [ - + ]: 9 : SPDK_CU_ASSERT_FATAL(bio->iovpos < NVME_MAX_SGL_DESCRIPTORS);
598 : 9 : }
599 : :
600 : : static void
601 : 3 : test_nvme_pcie_qpair_build_prps_sgl_request(void)
602 : : {
603 : 3 : struct spdk_nvme_qpair qpair = {};
604 : 3 : struct nvme_request req = {};
605 : 3 : struct nvme_tracker tr = {};
606 : 3 : struct spdk_nvme_ctrlr ctrlr = {};
607 : 3 : struct nvme_pcie_ut_bdev_io bio = {};
608 : : int rc;
609 : :
610 : 3 : tr.req = &req;
611 : 3 : qpair.ctrlr = &ctrlr;
612 : 3 : req.payload = NVME_PAYLOAD_SGL(nvme_pcie_ut_reset_sgl, nvme_pcie_ut_next_sge, &bio, NULL);
613 : 3 : req.payload_size = 4096;
614 : 3 : ctrlr.page_size = 4096;
615 : 3 : bio.iovs[0].iov_base = (void *)0x100000;
616 : 3 : bio.iovs[0].iov_len = 4096;
617 : :
618 : 3 : rc = nvme_pcie_qpair_build_prps_sgl_request(&qpair, &req, &tr, NULL);
619 : 3 : CU_ASSERT(rc == 0);
620 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp1 == 0x100000);
621 : 3 : }
622 : :
623 : : static void
624 : 3 : test_nvme_pcie_qpair_build_hw_sgl_request(void)
625 : : {
626 : 3 : struct nvme_pcie_qpair pqpair = {};
627 : 3 : struct spdk_nvme_qpair *qpair = &pqpair.qpair;
628 : 3 : struct nvme_request req = {};
629 : 3 : struct nvme_tracker tr = {};
630 : 3 : struct nvme_pcie_ut_bdev_io bio = {};
631 : 3 : struct spdk_nvme_ctrlr ctrlr = {};
632 : : int rc;
633 : :
634 : 3 : ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_PCIE;
635 : 3 : qpair->ctrlr = &ctrlr;
636 : 3 : req.payload = NVME_PAYLOAD_SGL(nvme_pcie_ut_reset_sgl, nvme_pcie_ut_next_sge, &bio, NULL);
637 : 3 : req.cmd.opc = SPDK_NVME_OPC_WRITE;
638 : 3 : tr.prp_sgl_bus_addr = 0xDAADBEE0;
639 : 3 : g_vtophys_size = 4096;
640 : :
641 : : /* Multiple vectors, 2k + 4k + 2k */
642 : 3 : req.payload_size = 8192;
643 : 3 : bio.iovpos = 3;
644 : 3 : bio.iovs[0].iov_base = (void *)0xDBADBEE0;
645 : 3 : bio.iovs[0].iov_len = 2048;
646 : 3 : bio.iovs[1].iov_base = (void *)0xDCADBEE0;
647 : 3 : bio.iovs[1].iov_len = 4096;
648 : 3 : bio.iovs[2].iov_base = (void *)0xDDADBEE0;
649 : 3 : bio.iovs[2].iov_len = 2048;
650 : :
651 : 3 : rc = nvme_pcie_qpair_build_hw_sgl_request(qpair, &req, &tr, true);
652 : 3 : CU_ASSERT(rc == 0);
653 : 3 : CU_ASSERT(tr.u.sgl[0].unkeyed.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
654 : 3 : CU_ASSERT(tr.u.sgl[0].unkeyed.length == 2048);
655 : 3 : CU_ASSERT(tr.u.sgl[0].address == 0xDBADBEE0);
656 : 3 : CU_ASSERT(tr.u.sgl[0].unkeyed.subtype == 0);
657 : 3 : CU_ASSERT(tr.u.sgl[1].unkeyed.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
658 : 3 : CU_ASSERT(tr.u.sgl[1].unkeyed.length == 4096);
659 : 3 : CU_ASSERT(tr.u.sgl[1].address == 0xDCADBEE0);
660 : 3 : CU_ASSERT(tr.u.sgl[2].unkeyed.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
661 : 3 : CU_ASSERT(tr.u.sgl[2].unkeyed.length == 2048);
662 : 3 : CU_ASSERT(tr.u.sgl[2].unkeyed.length == 2048);
663 : 3 : CU_ASSERT(tr.u.sgl[2].address == 0xDDADBEE0);
664 : 3 : CU_ASSERT(req.cmd.psdt == SPDK_NVME_PSDT_SGL_MPTR_CONTIG);
665 : 3 : CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.subtype == 0);
666 : 3 : CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.type == SPDK_NVME_SGL_TYPE_LAST_SEGMENT);
667 : 3 : CU_ASSERT(req.cmd.dptr.sgl1.address == 0xDAADBEE0);
668 : 3 : CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.length == 48);
669 : :
670 : : /* Single vector */
671 [ - + ]: 3 : memset(&tr, 0, sizeof(tr));
672 [ - + ]: 3 : memset(&bio, 0, sizeof(bio));
673 [ - + ]: 3 : memset(&req, 0, sizeof(req));
674 : 3 : req.payload = NVME_PAYLOAD_SGL(nvme_pcie_ut_reset_sgl, nvme_pcie_ut_next_sge, &bio, NULL);
675 : 3 : req.cmd.opc = SPDK_NVME_OPC_WRITE;
676 : 3 : req.payload_size = 4096;
677 : 3 : bio.iovpos = 1;
678 : 3 : bio.iovs[0].iov_base = (void *)0xDBADBEE0;
679 : 3 : bio.iovs[0].iov_len = 4096;
680 : :
681 : 3 : rc = nvme_pcie_qpair_build_hw_sgl_request(qpair, &req, &tr, true);
682 : 3 : CU_ASSERT(rc == 0);
683 : 3 : CU_ASSERT(tr.u.sgl[0].unkeyed.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
684 : 3 : CU_ASSERT(tr.u.sgl[0].unkeyed.length == 4096);
685 : 3 : CU_ASSERT(tr.u.sgl[0].address == 0xDBADBEE0);
686 : 3 : CU_ASSERT(tr.u.sgl[0].unkeyed.subtype == 0);
687 : 3 : CU_ASSERT(req.cmd.psdt == SPDK_NVME_PSDT_SGL_MPTR_CONTIG);
688 : 3 : CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.subtype == 0);
689 : 3 : CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
690 : 3 : CU_ASSERT(req.cmd.dptr.sgl1.address == 0xDBADBEE0);
691 : 3 : CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.length == 4096);
692 : 3 : }
693 : :
694 : : static void
695 : 3 : test_nvme_pcie_qpair_build_contig_request(void)
696 : : {
697 : 3 : struct nvme_pcie_qpair pqpair = {};
698 : 3 : struct nvme_request req = {};
699 : 3 : struct nvme_tracker tr = {};
700 : 3 : struct spdk_nvme_ctrlr ctrlr = {};
701 : : int rc;
702 : :
703 : 3 : pqpair.qpair.ctrlr = &ctrlr;
704 : 3 : ctrlr.page_size = 0x1000;
705 : :
706 : : /* 1 prp, 4k-aligned */
707 : 3 : prp_list_prep(&tr, &req, NULL);
708 : 3 : req.payload = NVME_PAYLOAD_CONTIG((void *)0x100000, NULL);
709 : 3 : req.payload_size = 0x1000;
710 : :
711 : 3 : rc = nvme_pcie_qpair_build_contig_request(&pqpair.qpair, &req, &tr, true);
712 : 3 : CU_ASSERT(rc == 0);
713 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp1 == 0x100000);
714 : :
715 : : /* 2 prps, non-4K-aligned */
716 : 3 : prp_list_prep(&tr, &req, NULL);
717 : 3 : req.payload = NVME_PAYLOAD_CONTIG((void *)0x100000, NULL);
718 : 3 : req.payload_size = 0x1000;
719 : 3 : req.payload_offset = 0x800;
720 : :
721 : 3 : rc = nvme_pcie_qpair_build_contig_request(&pqpair.qpair, &req, &tr, true);
722 : 3 : CU_ASSERT(rc == 0);
723 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp1 == 0x100800);
724 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp2 == 0x101000);
725 : :
726 : : /* 3 prps, 4k-aligned */
727 : 3 : prp_list_prep(&tr, &req, NULL);
728 : 3 : req.payload = NVME_PAYLOAD_CONTIG((void *)0x100000, NULL);
729 : 3 : req.payload_size = 0x3000;
730 : :
731 : 3 : rc = nvme_pcie_qpair_build_contig_request(&pqpair.qpair, &req, &tr, true);
732 : 3 : CU_ASSERT(rc == 0);
733 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp1 == 0x100000);
734 : 3 : CU_ASSERT(req.cmd.dptr.prp.prp2 == tr.prp_sgl_bus_addr);
735 : 3 : CU_ASSERT(tr.u.prp[0] == 0x101000);
736 : 3 : CU_ASSERT(tr.u.prp[1] == 0x102000);
737 : :
738 : : /* address not dword aligned */
739 : 3 : prp_list_prep(&tr, &req, NULL);
740 : 3 : req.payload = NVME_PAYLOAD_CONTIG((void *)0x100001, NULL);
741 : 3 : req.payload_size = 0x3000;
742 : 3 : req.qpair = &pqpair.qpair;
743 : 3 : TAILQ_INIT(&pqpair.outstanding_tr);
744 : 3 : TAILQ_INSERT_TAIL(&pqpair.outstanding_tr, &tr, tq_list);
745 : :
746 : 3 : rc = nvme_pcie_qpair_build_contig_request(&pqpair.qpair, &req, &tr, true);
747 : 3 : CU_ASSERT(rc == -EFAULT);
748 : 3 : }
749 : :
750 : : static void
751 : 3 : test_nvme_pcie_ctrlr_regs_get_set(void)
752 : : {
753 : 3 : struct nvme_pcie_ctrlr pctrlr = {};
754 : 3 : volatile struct spdk_nvme_registers regs = {};
755 : 3 : uint32_t value_4;
756 : 3 : uint64_t value_8;
757 : : int rc;
758 : :
759 : 3 : pctrlr.regs = ®s;
760 : :
761 : 3 : rc = nvme_pcie_ctrlr_set_reg_4(&pctrlr.ctrlr, 8, 4);
762 : 3 : CU_ASSERT(rc == 0);
763 : :
764 : 3 : rc = nvme_pcie_ctrlr_get_reg_4(&pctrlr.ctrlr, 8, &value_4);
765 : 3 : CU_ASSERT(rc == 0);
766 : 3 : CU_ASSERT(value_4 == 4);
767 : :
768 : 3 : rc = nvme_pcie_ctrlr_set_reg_8(&pctrlr.ctrlr, 0, 0x100000000);
769 : 3 : CU_ASSERT(rc == 0);
770 : :
771 : 3 : rc = nvme_pcie_ctrlr_get_reg_8(&pctrlr.ctrlr, 0, &value_8);
772 : 3 : CU_ASSERT(rc == 0);
773 : 3 : CU_ASSERT(value_8 == 0x100000000);
774 : 3 : }
775 : :
776 : : static void
777 : 3 : test_nvme_pcie_ctrlr_map_unmap_cmb(void)
778 : : {
779 : 3 : struct nvme_pcie_ctrlr pctrlr = {};
780 : 3 : volatile struct spdk_nvme_registers regs = {};
781 : 3 : union spdk_nvme_cmbsz_register cmbsz = {};
782 : 3 : union spdk_nvme_cmbloc_register cmbloc = {};
783 : 3 : struct dev_mem_resource cmd_res = {};
784 : : int rc;
785 : :
786 : 3 : pctrlr.regs = ®s;
787 : 3 : pctrlr.devhandle = (void *)&cmd_res;
788 : 3 : cmd_res.addr = (void *)0x7f7c0080d000;
789 : 3 : cmd_res.len = 0x800000;
790 : 3 : cmd_res.phys_addr = 0xFC800000;
791 : : /* Configure cmb size with unit size 4k, offset 100, unsupported SQ */
792 : 3 : cmbsz.bits.sz = 512;
793 : 3 : cmbsz.bits.szu = 0;
794 : 3 : cmbsz.bits.sqs = 0;
795 : 3 : cmbloc.bits.bir = 0;
796 : 3 : cmbloc.bits.ofst = 100;
797 : :
798 : 3 : nvme_pcie_ctrlr_set_reg_4(&pctrlr.ctrlr, offsetof(struct spdk_nvme_registers, cmbsz.raw),
799 : : cmbsz.raw);
800 : 3 : nvme_pcie_ctrlr_set_reg_4(&pctrlr.ctrlr, offsetof(struct spdk_nvme_registers, cmbloc.raw),
801 : : cmbloc.raw);
802 : :
803 : 3 : nvme_pcie_ctrlr_map_cmb(&pctrlr);
804 : 3 : CU_ASSERT(pctrlr.cmb.bar_va == (void *)0x7f7c0080d000);
805 : 3 : CU_ASSERT(pctrlr.cmb.bar_pa == 0xFC800000);
806 : 3 : CU_ASSERT(pctrlr.cmb.size == 512 * 4096);
807 : 3 : CU_ASSERT(pctrlr.cmb.current_offset == 4096 * 100);
808 [ - + ]: 3 : CU_ASSERT(pctrlr.ctrlr.opts.use_cmb_sqs == false);
809 : :
810 : 3 : rc = nvme_pcie_ctrlr_unmap_cmb(&pctrlr);
811 : 3 : CU_ASSERT(rc == 0);
812 : :
813 : : /* Invalid mapping information */
814 [ - + ]: 3 : memset(&pctrlr.cmb, 0, sizeof(pctrlr.cmb));
815 : 3 : nvme_pcie_ctrlr_set_reg_4(&pctrlr.ctrlr, offsetof(struct spdk_nvme_registers, cmbsz.raw), 0);
816 : 3 : nvme_pcie_ctrlr_set_reg_4(&pctrlr.ctrlr, offsetof(struct spdk_nvme_registers, cmbloc.raw), 0);
817 : :
818 : 3 : nvme_pcie_ctrlr_map_cmb(&pctrlr);
819 : 3 : CU_ASSERT(pctrlr.cmb.bar_va == NULL);
820 : 3 : CU_ASSERT(pctrlr.cmb.bar_pa == 0);
821 : 3 : CU_ASSERT(pctrlr.cmb.size == 0);
822 : 3 : CU_ASSERT(pctrlr.cmb.current_offset == 0);
823 [ - + ]: 3 : CU_ASSERT(pctrlr.ctrlr.opts.use_cmb_sqs == false);
824 : 3 : }
825 : :
826 : :
827 : : static void
828 : 18 : prepare_map_io_cmd(struct nvme_pcie_ctrlr *pctrlr)
829 : : {
830 : 18 : union spdk_nvme_cmbsz_register cmbsz = {};
831 : 18 : union spdk_nvme_cmbloc_register cmbloc = {};
832 : :
833 : 18 : cmbsz.bits.sz = 512;
834 : 18 : cmbsz.bits.wds = 1;
835 : 18 : cmbsz.bits.rds = 1;
836 : :
837 : 18 : nvme_pcie_ctrlr_set_reg_4(&pctrlr->ctrlr, offsetof(struct spdk_nvme_registers, cmbsz.raw),
838 : : cmbsz.raw);
839 : 18 : nvme_pcie_ctrlr_set_reg_4(&pctrlr->ctrlr, offsetof(struct spdk_nvme_registers, cmbloc.raw),
840 : : cmbloc.raw);
841 : :
842 : 18 : pctrlr->cmb.bar_va = (void *)0x7F7C0080D000;
843 : 18 : pctrlr->cmb.bar_pa = 0xFC800000;
844 : 18 : pctrlr->cmb.current_offset = 1ULL << 22;
845 : 18 : pctrlr->cmb.size = (1ULL << 22) * 512;
846 : 18 : pctrlr->cmb.mem_register_addr = NULL;
847 : 18 : pctrlr->ctrlr.opts.use_cmb_sqs = false;
848 : 18 : }
849 : :
850 : : static void
851 : 3 : test_nvme_pcie_ctrlr_map_io_cmb(void)
852 : : {
853 : 3 : struct nvme_pcie_ctrlr pctrlr = {};
854 : 3 : volatile struct spdk_nvme_registers regs = {};
855 : 3 : union spdk_nvme_cmbsz_register cmbsz = {};
856 : 3 : void *mem_reg_addr = NULL;
857 : 3 : size_t size;
858 : : int rc;
859 : :
860 : 3 : pctrlr.regs = ®s;
861 : 3 : prepare_map_io_cmd(&pctrlr);
862 : :
863 : 3 : mem_reg_addr = nvme_pcie_ctrlr_map_io_cmb(&pctrlr.ctrlr, &size);
864 : : /* Ceil the current cmb vaddr and cmb size to 2MB_aligned */
865 : 3 : CU_ASSERT(mem_reg_addr == (void *)0x7F7C00E00000);
866 : 3 : CU_ASSERT(size == 0x7FE00000);
867 : :
868 : 3 : rc = nvme_pcie_ctrlr_unmap_io_cmb(&pctrlr.ctrlr);
869 : 3 : CU_ASSERT(rc == 0);
870 : 3 : CU_ASSERT(pctrlr.cmb.mem_register_addr == NULL);
871 : 3 : CU_ASSERT(pctrlr.cmb.mem_register_size == 0);
872 : :
873 : : /* cmb mem_register_addr not NULL */
874 : 3 : prepare_map_io_cmd(&pctrlr);
875 : 3 : pctrlr.cmb.mem_register_addr = (void *)0xDEADBEEF;
876 : 3 : pctrlr.cmb.mem_register_size = 1024;
877 : :
878 : 3 : mem_reg_addr = nvme_pcie_ctrlr_map_io_cmb(&pctrlr.ctrlr, &size);
879 : 3 : CU_ASSERT(size == 1024);
880 : 3 : CU_ASSERT(mem_reg_addr == (void *)0xDEADBEEF);
881 : :
882 : : /* cmb.bar_va is NULL */
883 : 3 : prepare_map_io_cmd(&pctrlr);
884 : 3 : pctrlr.cmb.bar_va = NULL;
885 : :
886 : 3 : mem_reg_addr = nvme_pcie_ctrlr_map_io_cmb(&pctrlr.ctrlr, &size);
887 : 3 : CU_ASSERT(mem_reg_addr == NULL);
888 : 3 : CU_ASSERT(size == 0);
889 : :
890 : : /* submission queue already used */
891 : 3 : prepare_map_io_cmd(&pctrlr);
892 : 3 : pctrlr.ctrlr.opts.use_cmb_sqs = true;
893 : :
894 : 3 : mem_reg_addr = nvme_pcie_ctrlr_map_io_cmb(&pctrlr.ctrlr, &size);
895 : 3 : CU_ASSERT(mem_reg_addr == NULL);
896 : 3 : CU_ASSERT(size == 0);
897 : :
898 : 3 : pctrlr.ctrlr.opts.use_cmb_sqs = false;
899 : :
900 : : /* Only SQS is supported */
901 : 3 : prepare_map_io_cmd(&pctrlr);
902 : 3 : cmbsz.bits.wds = 0;
903 : 3 : cmbsz.bits.rds = 0;
904 : 3 : nvme_pcie_ctrlr_set_reg_4(&pctrlr.ctrlr, offsetof(struct spdk_nvme_registers, cmbsz.raw),
905 : : cmbsz.raw);
906 : :
907 : 3 : mem_reg_addr = nvme_pcie_ctrlr_map_io_cmb(&pctrlr.ctrlr, &size);
908 : 3 : CU_ASSERT(mem_reg_addr == NULL);
909 : 3 : CU_ASSERT(size == 0);
910 : :
911 : : /* CMB size is less than 4MB */
912 : 3 : prepare_map_io_cmd(&pctrlr);
913 : 3 : pctrlr.cmb.size = 1ULL << 16;
914 : :
915 : 3 : mem_reg_addr = nvme_pcie_ctrlr_map_io_cmb(&pctrlr.ctrlr, &size);
916 : 3 : CU_ASSERT(mem_reg_addr == NULL);
917 : 3 : CU_ASSERT(size == 0);
918 : 3 : }
919 : :
920 : : static void
921 : 3 : test_nvme_pcie_ctrlr_map_unmap_pmr(void)
922 : : {
923 : 3 : struct nvme_pcie_ctrlr pctrlr = {};
924 : 3 : volatile struct spdk_nvme_registers regs = {};
925 : 3 : union spdk_nvme_pmrcap_register pmrcap = {};
926 : 3 : struct dev_mem_resource cmd_res = {};
927 : : int rc;
928 : :
929 : 3 : pctrlr.regs = ®s;
930 : 3 : pctrlr.devhandle = (void *)&cmd_res;
931 : 3 : regs.cap.bits.pmrs = 1;
932 : 3 : cmd_res.addr = (void *)0x7F7C0080d000;
933 : 3 : cmd_res.len = 0x800000;
934 : 3 : cmd_res.phys_addr = 0xFC800000;
935 : 3 : pmrcap.bits.bir = 2;
936 : 3 : pmrcap.bits.cmss = 1;
937 : 3 : nvme_pcie_ctrlr_set_reg_4(&pctrlr.ctrlr,
938 : : offsetof(struct spdk_nvme_registers, pmrcap.raw),
939 : : pmrcap.raw);
940 : :
941 : 3 : nvme_pcie_ctrlr_map_pmr(&pctrlr);
942 : 3 : CU_ASSERT(pctrlr.regs->pmrmscu == 0);
943 : : /* Controller memory space enable, bit 1 */
944 : 3 : CU_ASSERT(pctrlr.regs->pmrmscl.raw == 0xFC800002);
945 : 3 : CU_ASSERT(pctrlr.regs->pmrsts.raw == 0);
946 : 3 : CU_ASSERT(pctrlr.pmr.bar_va == (void *)0x7F7C0080d000);
947 : 3 : CU_ASSERT(pctrlr.pmr.bar_pa == 0xFC800000);
948 : 3 : CU_ASSERT(pctrlr.pmr.size == 0x800000);
949 : :
950 : 3 : rc = nvme_pcie_ctrlr_unmap_pmr(&pctrlr);
951 : 3 : CU_ASSERT(rc == 0);
952 : 3 : CU_ASSERT(pctrlr.regs->pmrmscu == 0);
953 : 3 : CU_ASSERT(pctrlr.regs->pmrmscl.raw == 0);
954 : :
955 : : /* pmrcap value invalid */
956 [ - + ]: 3 : memset(&pctrlr, 0, sizeof(pctrlr));
957 [ - + ]: 3 : memset((void *)®s, 0, sizeof(regs));
958 [ - + ]: 3 : memset(&cmd_res, 0, sizeof(cmd_res));
959 : :
960 : 3 : pctrlr.regs = ®s;
961 : 3 : pctrlr.devhandle = (void *)&cmd_res;
962 : 3 : regs.cap.bits.pmrs = 1;
963 : 3 : cmd_res.addr = (void *)0x7F7C0080d000;
964 : 3 : cmd_res.len = 0x800000;
965 : 3 : cmd_res.phys_addr = 0xFC800000;
966 : 3 : pmrcap.raw = 0;
967 : 3 : nvme_pcie_ctrlr_set_reg_4(&pctrlr.ctrlr,
968 : : offsetof(struct spdk_nvme_registers, pmrcap.raw),
969 : : pmrcap.raw);
970 : :
971 : 3 : nvme_pcie_ctrlr_map_pmr(&pctrlr);
972 : 3 : CU_ASSERT(pctrlr.pmr.bar_va == NULL);
973 : 3 : CU_ASSERT(pctrlr.pmr.bar_pa == 0);
974 : 3 : CU_ASSERT(pctrlr.pmr.size == 0);
975 : 3 : }
976 : :
977 : : static void
978 : 3 : test_nvme_pcie_ctrlr_config_pmr(void)
979 : : {
980 : 3 : struct nvme_pcie_ctrlr pctrlr = {};
981 : 3 : union spdk_nvme_pmrcap_register pmrcap = {};
982 : 3 : union spdk_nvme_pmrsts_register pmrsts = {};
983 : 3 : union spdk_nvme_cap_register cap = {};
984 : 3 : union spdk_nvme_pmrctl_register pmrctl = {};
985 : 3 : volatile struct spdk_nvme_registers regs = {};
986 : : int rc;
987 : :
988 : : /* pmrctl enable */
989 : 3 : pctrlr.regs = ®s;
990 : 3 : pmrcap.bits.pmrtu = 0;
991 : 3 : pmrcap.bits.pmrto = 1;
992 : 3 : pmrsts.bits.nrdy = false;
993 : 3 : pmrctl.bits.en = 0;
994 : 3 : cap.bits.pmrs = 1;
995 : :
996 : 3 : rc = nvme_pcie_ctrlr_set_pmrctl(&pctrlr, &pmrctl);
997 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(rc == 0);
998 : 3 : rc = nvme_pcie_ctrlr_set_reg_8(&pctrlr.ctrlr, offsetof(struct spdk_nvme_registers, cap.raw),
999 : : cap.raw);
1000 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(rc == 0);
1001 : 3 : rc = nvme_pcie_ctrlr_set_reg_4(&pctrlr.ctrlr, offsetof(struct spdk_nvme_registers, pmrcap.raw),
1002 : : pmrcap.raw);
1003 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(rc == 0);
1004 : 3 : rc = nvme_pcie_ctrlr_set_reg_4(&pctrlr.ctrlr, offsetof(struct spdk_nvme_registers, pmrsts.raw),
1005 : : pmrsts.raw);
1006 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(rc == 0);
1007 : :
1008 : 3 : rc = nvme_pcie_ctrlr_config_pmr(&pctrlr.ctrlr, true);
1009 : 3 : CU_ASSERT(rc == 0);
1010 : 3 : rc = nvme_pcie_ctrlr_get_pmrctl(&pctrlr, &pmrctl);
1011 : 3 : CU_ASSERT(rc == 0);
1012 : 3 : CU_ASSERT(pmrctl.bits.en == true);
1013 : :
1014 : : /* pmrctl disable */
1015 : 3 : pmrsts.bits.nrdy = true;
1016 : 3 : rc = nvme_pcie_ctrlr_set_reg_4(&pctrlr.ctrlr, offsetof(struct spdk_nvme_registers, pmrsts.raw),
1017 : : pmrsts.raw);
1018 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(rc == 0);
1019 : 3 : rc = nvme_pcie_ctrlr_set_pmrctl(&pctrlr, &pmrctl);
1020 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(rc == 0);
1021 : :
1022 : 3 : rc = nvme_pcie_ctrlr_config_pmr(&pctrlr.ctrlr, false);
1023 : 3 : CU_ASSERT(rc == 0);
1024 : 3 : rc = nvme_pcie_ctrlr_get_pmrctl(&pctrlr, &pmrctl);
1025 : 3 : CU_ASSERT(rc == 0);
1026 : 3 : CU_ASSERT(pmrctl.bits.en == false);
1027 : :
1028 : : /* configuration exist */
1029 : 3 : rc = nvme_pcie_ctrlr_config_pmr(&pctrlr.ctrlr, false);
1030 : 3 : CU_ASSERT(rc == -EINVAL);
1031 : 3 : }
1032 : :
1033 : : static void
1034 : 18 : map_io_pmr_init(struct nvme_pcie_ctrlr *pctrlr, union spdk_nvme_pmrcap_register *pmrcap)
1035 : : {
1036 : 18 : pmrcap->raw = 0;
1037 : 18 : pmrcap->bits.rds = 1;
1038 : 18 : pmrcap->bits.wds = 1;
1039 : 18 : nvme_pcie_ctrlr_set_reg_4(&pctrlr->ctrlr, offsetof(struct spdk_nvme_registers, pmrcap.raw),
1040 : : pmrcap->raw);
1041 : 18 : pctrlr->regs->cap.bits.pmrs = 1;
1042 : 18 : pctrlr->pmr.mem_register_size = 0;
1043 : 18 : pctrlr->pmr.mem_register_addr = NULL;
1044 : 18 : pctrlr->pmr.bar_va = (void *)0x7F7C00E30000;
1045 : 18 : pctrlr->pmr.size = (1 << 22) * 128;
1046 : 18 : }
1047 : :
1048 : : static void
1049 : 3 : test_nvme_pcie_ctrlr_map_io_pmr(void)
1050 : : {
1051 : 3 : struct nvme_pcie_ctrlr pctrlr = {};
1052 : : struct spdk_nvme_ctrlr *ctrlr;
1053 : 3 : volatile struct spdk_nvme_registers regs = {};
1054 : 3 : union spdk_nvme_pmrcap_register pmrcap;
1055 : 3 : void *mem_reg_addr = NULL;
1056 : 3 : size_t rt_size = 0;
1057 : :
1058 : 3 : ctrlr = &pctrlr.ctrlr;
1059 : 3 : pctrlr.regs = ®s;
1060 : :
1061 : : /* PMR is not supported by the controller */
1062 : 3 : map_io_pmr_init(&pctrlr, &pmrcap);
1063 : 3 : regs.cap.bits.pmrs = 0;
1064 : :
1065 : 3 : mem_reg_addr = nvme_pcie_ctrlr_map_io_pmr(ctrlr, &rt_size);
1066 : 3 : CU_ASSERT(mem_reg_addr == NULL);
1067 : :
1068 : : /* mem_register_addr not NULL. */
1069 : 3 : map_io_pmr_init(&pctrlr, &pmrcap);
1070 : 3 : pctrlr.pmr.mem_register_addr = (void *)0xDEADBEEF;
1071 : 3 : pctrlr.pmr.mem_register_size = 1024;
1072 : :
1073 : 3 : mem_reg_addr = nvme_pcie_ctrlr_map_io_pmr(ctrlr, &rt_size);
1074 : 3 : CU_ASSERT(rt_size == 1024);
1075 : 3 : CU_ASSERT(mem_reg_addr == (void *)0xDEADBEEF);
1076 : :
1077 : : /* PMR not available */
1078 : 3 : map_io_pmr_init(&pctrlr, &pmrcap);
1079 : 3 : pctrlr.pmr.bar_va = NULL;
1080 : 3 : pctrlr.pmr.mem_register_addr = NULL;
1081 : :
1082 : 3 : mem_reg_addr = nvme_pcie_ctrlr_map_io_pmr(ctrlr, &rt_size);
1083 : 3 : CU_ASSERT(mem_reg_addr == NULL);
1084 : 3 : CU_ASSERT(rt_size == 0);
1085 : :
1086 : : /* WDS / RDS is not supported */
1087 : 3 : map_io_pmr_init(&pctrlr, &pmrcap);
1088 : 3 : pmrcap.bits.rds = 0;
1089 : 3 : pmrcap.bits.wds = 0;
1090 : 3 : nvme_pcie_ctrlr_set_reg_4(&pctrlr.ctrlr, offsetof(struct spdk_nvme_registers, pmrcap.raw),
1091 : : pmrcap.raw);
1092 : :
1093 : 3 : mem_reg_addr = nvme_pcie_ctrlr_map_io_pmr(ctrlr, &rt_size);
1094 : 3 : CU_ASSERT(mem_reg_addr == NULL);
1095 : 3 : CU_ASSERT(rt_size == 0);
1096 : :
1097 : : /* PMR is less than 4MiB in size then abort PMR mapping */
1098 : 3 : map_io_pmr_init(&pctrlr, &pmrcap);
1099 : 3 : pctrlr.pmr.size = (1ULL << 20);
1100 : :
1101 : 3 : mem_reg_addr = nvme_pcie_ctrlr_map_io_pmr(ctrlr, &rt_size);
1102 : 3 : CU_ASSERT(mem_reg_addr == NULL);
1103 : 3 : CU_ASSERT(rt_size == 0);
1104 : :
1105 : : /* All parameters success */
1106 : 3 : map_io_pmr_init(&pctrlr, &pmrcap);
1107 : :
1108 : 3 : mem_reg_addr = nvme_pcie_ctrlr_map_io_pmr(ctrlr, &rt_size);
1109 : 3 : CU_ASSERT(mem_reg_addr == (void *)0x7F7C01000000);
1110 : 3 : CU_ASSERT(rt_size == 0x1FE00000);
1111 : 3 : }
1112 : :
1113 : : int
1114 : 3 : main(int argc, char **argv)
1115 : : {
1116 : 3 : CU_pSuite suite = NULL;
1117 : : unsigned int num_failures;
1118 : :
1119 : 3 : CU_initialize_registry();
1120 : :
1121 : 3 : suite = CU_add_suite("nvme_pcie", NULL, NULL);
1122 : 3 : CU_ADD_TEST(suite, test_prp_list_append);
1123 : 3 : CU_ADD_TEST(suite, test_nvme_pcie_hotplug_monitor);
1124 : 3 : CU_ADD_TEST(suite, test_shadow_doorbell_update);
1125 : 3 : CU_ADD_TEST(suite, test_build_contig_hw_sgl_request);
1126 : 3 : CU_ADD_TEST(suite, test_nvme_pcie_qpair_build_metadata);
1127 : 3 : CU_ADD_TEST(suite, test_nvme_pcie_qpair_build_prps_sgl_request);
1128 : 3 : CU_ADD_TEST(suite, test_nvme_pcie_qpair_build_hw_sgl_request);
1129 : 3 : CU_ADD_TEST(suite, test_nvme_pcie_qpair_build_contig_request);
1130 : 3 : CU_ADD_TEST(suite, test_nvme_pcie_ctrlr_regs_get_set);
1131 : 3 : CU_ADD_TEST(suite, test_nvme_pcie_ctrlr_map_unmap_cmb);
1132 : 3 : CU_ADD_TEST(suite, test_nvme_pcie_ctrlr_map_io_cmb);
1133 : 3 : CU_ADD_TEST(suite, test_nvme_pcie_ctrlr_map_unmap_pmr);
1134 : 3 : CU_ADD_TEST(suite, test_nvme_pcie_ctrlr_config_pmr);
1135 : 3 : CU_ADD_TEST(suite, test_nvme_pcie_ctrlr_map_io_pmr);
1136 : :
1137 : 3 : num_failures = spdk_ut_run_tests(argc, argv, NULL);
1138 : 3 : CU_cleanup_registry();
1139 : 3 : return num_failures;
1140 : : }
|