1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2017 Shunsuke Mie
5 * Copyright (c) 2018 Leon Dang
6 * Copyright (c) 2020 Chuck Tuffli
7 *
8 * Function crc16 Copyright (c) 2017, Fedor Uporov
9 * Obtained from function ext2_crc16() in sys/fs/ext2fs/ext2_csum.c
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33 /*
34 * bhyve PCIe-NVMe device emulation.
35 *
36 * options:
37 * -s <n>,nvme,devpath,maxq=#,qsz=#,ioslots=#,sectsz=#,ser=A-Z,eui64=#,dsm=<opt>
38 *
39 * accepted devpath:
40 * /dev/blockdev
41 * /path/to/image
42 * ram=size_in_MiB
43 *
44 * maxq = max number of queues
45 * qsz = max elements in each queue
46 * ioslots = max number of concurrent io requests
47 * sectsz = sector size (defaults to blockif sector size)
48 * ser = serial number (20-chars max)
49 * eui64 = IEEE Extended Unique Identifier (8 byte value)
50 * dsm = DataSet Management support. Option is one of auto, enable,disable
51 *
52 */
53
54 /* TODO:
55 - create async event for smart and log
56 - intr coalesce
57 */
58
59 #include <sys/cdefs.h>
60 #include <sys/errno.h>
61 #include <sys/types.h>
62 #include <net/ieee_oui.h>
63
64 #include <assert.h>
65 #include <pthread.h>
66 #include <pthread_np.h>
67 #include <semaphore.h>
68 #include <stdbool.h>
69 #include <stddef.h>
70 #include <stdint.h>
71 #include <stdio.h>
72 #include <stdlib.h>
73 #include <string.h>
74
75 #include <machine/atomic.h>
76 #include <machine/vmm.h>
77 #include <vmmapi.h>
78
79 #include <dev/nvme/nvme.h>
80
81 #include "bhyverun.h"
82 #include "block_if.h"
83 #include "config.h"
84 #include "debug.h"
85 #include "pci_emul.h"
86
87
88 static int nvme_debug = 0;
89 #define DPRINTF(fmt, args...) if (nvme_debug) PRINTLN(fmt, ##args)
90 #define WPRINTF(fmt, args...) PRINTLN(fmt, ##args)
91
92 /* defaults; can be overridden */
93 #define NVME_MSIX_BAR 4
94
95 #define NVME_IOSLOTS 8
96
97 /* The NVMe spec defines bits 13:4 in BAR0 as reserved */
98 #define NVME_MMIO_SPACE_MIN (1 << 14)
99
100 #define NVME_QUEUES 16
101 #define NVME_MAX_QENTRIES 2048
102 /* Memory Page size Minimum reported in CAP register */
103 #define NVME_MPSMIN 0
104 /* MPSMIN converted to bytes */
105 #define NVME_MPSMIN_BYTES (1 << (12 + NVME_MPSMIN))
106
107 #define NVME_PRP2_ITEMS (PAGE_SIZE/sizeof(uint64_t))
108 #define NVME_MDTS 9
109 /* Note the + 1 allows for the initial descriptor to not be page aligned */
110 #define NVME_MAX_IOVEC ((1 << NVME_MDTS) + 1)
111 #define NVME_MAX_DATA_SIZE ((1 << NVME_MDTS) * NVME_MPSMIN_BYTES)
112
113 /* This is a synthetic status code to indicate there is no status */
114 #define NVME_NO_STATUS 0xffff
115 #define NVME_COMPLETION_VALID(c) ((c).status != NVME_NO_STATUS)
116
117 /* Reported temperature in Kelvin (i.e. room temperature) */
118 #define NVME_TEMPERATURE 296
119
120 /* helpers */
121
122 /* Convert a zero-based value into a one-based value */
123 #define ONE_BASED(zero) ((zero) + 1)
124 /* Convert a one-based value into a zero-based value */
125 #define ZERO_BASED(one) ((one) - 1)
126
127 /* Encode number of SQ's and CQ's for Set/Get Features */
128 #define NVME_FEATURE_NUM_QUEUES(sc) \
129 (ZERO_BASED((sc)->num_squeues) & 0xffff) | \
130 (ZERO_BASED((sc)->num_cqueues) & 0xffff) << 16;
131
132 #define NVME_DOORBELL_OFFSET offsetof(struct nvme_registers, doorbell)
133
134 enum nvme_controller_register_offsets {
135 NVME_CR_CAP_LOW = 0x00,
136 NVME_CR_CAP_HI = 0x04,
137 NVME_CR_VS = 0x08,
138 NVME_CR_INTMS = 0x0c,
139 NVME_CR_INTMC = 0x10,
140 NVME_CR_CC = 0x14,
141 NVME_CR_CSTS = 0x1c,
142 NVME_CR_NSSR = 0x20,
143 NVME_CR_AQA = 0x24,
144 NVME_CR_ASQ_LOW = 0x28,
145 NVME_CR_ASQ_HI = 0x2c,
146 NVME_CR_ACQ_LOW = 0x30,
147 NVME_CR_ACQ_HI = 0x34,
148 };
149
150 enum nvme_cmd_cdw11 {
151 NVME_CMD_CDW11_PC = 0x0001,
152 NVME_CMD_CDW11_IEN = 0x0002,
153 NVME_CMD_CDW11_IV = 0xFFFF0000,
154 };
155
156 enum nvme_copy_dir {
157 NVME_COPY_TO_PRP,
158 NVME_COPY_FROM_PRP,
159 };
160
161 #define NVME_CQ_INTEN 0x01
162 #define NVME_CQ_INTCOAL 0x02
163
164 struct nvme_completion_queue {
165 struct nvme_completion *qbase;
166 pthread_mutex_t mtx;
167 uint32_t size;
168 uint16_t tail; /* nvme progress */
169 uint16_t head; /* guest progress */
170 uint16_t intr_vec;
171 uint32_t intr_en;
172 };
173
174 struct nvme_submission_queue {
175 struct nvme_command *qbase;
176 pthread_mutex_t mtx;
177 uint32_t size;
178 uint16_t head; /* nvme progress */
179 uint16_t tail; /* guest progress */
180 uint16_t cqid; /* completion queue id */
181 int qpriority;
182 };
183
184 enum nvme_storage_type {
185 NVME_STOR_BLOCKIF = 0,
186 NVME_STOR_RAM = 1,
187 };
188
189 struct pci_nvme_blockstore {
190 enum nvme_storage_type type;
191 void *ctx;
192 uint64_t size;
193 uint32_t sectsz;
194 uint32_t sectsz_bits;
195 uint64_t eui64;
196 uint32_t deallocate:1;
197 };
198
199 /*
200 * Calculate the number of additional page descriptors for guest IO requests
201 * based on the advertised Max Data Transfer (MDTS) and given the number of
202 * default iovec's in a struct blockif_req.
203 */
204 #define MDTS_PAD_SIZE \
205 ( NVME_MAX_IOVEC > BLOCKIF_IOV_MAX ? \
206 NVME_MAX_IOVEC - BLOCKIF_IOV_MAX : \
207 0 )
208
209 struct pci_nvme_ioreq {
210 struct pci_nvme_softc *sc;
211 STAILQ_ENTRY(pci_nvme_ioreq) link;
212 struct nvme_submission_queue *nvme_sq;
213 uint16_t sqid;
214
215 /* command information */
216 uint16_t opc;
217 uint16_t cid;
218 uint32_t nsid;
219
220 uint64_t prev_gpaddr;
221 size_t prev_size;
222 size_t bytes;
223
224 struct blockif_req io_req;
225
226 struct iovec iovpadding[MDTS_PAD_SIZE];
227 };
228
229 enum nvme_dsm_type {
230 /* Dataset Management bit in ONCS reflects backing storage capability */
231 NVME_DATASET_MANAGEMENT_AUTO,
232 /* Unconditionally set Dataset Management bit in ONCS */
233 NVME_DATASET_MANAGEMENT_ENABLE,
234 /* Unconditionally clear Dataset Management bit in ONCS */
235 NVME_DATASET_MANAGEMENT_DISABLE,
236 };
237
238 struct pci_nvme_softc;
239 struct nvme_feature_obj;
240
241 typedef void (*nvme_feature_cb)(struct pci_nvme_softc *,
242 struct nvme_feature_obj *,
243 struct nvme_command *,
244 struct nvme_completion *);
245
246 struct nvme_feature_obj {
247 uint32_t cdw11;
248 nvme_feature_cb set;
249 nvme_feature_cb get;
250 bool namespace_specific;
251 };
252
253 #define NVME_FID_MAX (NVME_FEAT_ENDURANCE_GROUP_EVENT_CONFIGURATION + 1)
254
255 typedef enum {
256 PCI_NVME_AE_TYPE_ERROR = 0,
257 PCI_NVME_AE_TYPE_SMART,
258 PCI_NVME_AE_TYPE_NOTICE,
259 PCI_NVME_AE_TYPE_IO_CMD = 6,
260 PCI_NVME_AE_TYPE_VENDOR = 7,
261 PCI_NVME_AE_TYPE_MAX /* Must be last */
262 } pci_nvme_async_type;
263
264 /* Asynchronous Event Requests */
265 struct pci_nvme_aer {
266 STAILQ_ENTRY(pci_nvme_aer) link;
267 uint16_t cid; /* Command ID of the submitted AER */
268 };
269
270 /** Asynchronous Event Information - Error */
271 typedef enum {
272 PCI_NVME_AEI_ERROR_INVALID_DB,
273 PCI_NVME_AEI_ERROR_INVALID_DB_VALUE,
274 PCI_NVME_AEI_ERROR_DIAG_FAILURE,
275 PCI_NVME_AEI_ERROR_PERSISTANT_ERR,
276 PCI_NVME_AEI_ERROR_TRANSIENT_ERR,
277 PCI_NVME_AEI_ERROR_FIRMWARE_LOAD_ERR,
278 PCI_NVME_AEI_ERROR_MAX,
279 } pci_nvme_async_event_info_error;
280
281 /** Asynchronous Event Information - Notice */
282 typedef enum {
283 PCI_NVME_AEI_NOTICE_NS_ATTR_CHANGED = 0,
284 PCI_NVME_AEI_NOTICE_FW_ACTIVATION,
285 PCI_NVME_AEI_NOTICE_TELEMETRY_CHANGE,
286 PCI_NVME_AEI_NOTICE_ANA_CHANGE,
287 PCI_NVME_AEI_NOTICE_PREDICT_LATENCY_CHANGE,
288 PCI_NVME_AEI_NOTICE_LBA_STATUS_ALERT,
289 PCI_NVME_AEI_NOTICE_ENDURANCE_GROUP_CHANGE,
290 PCI_NVME_AEI_NOTICE_MAX,
291 } pci_nvme_async_event_info_notice;
292
293 #define PCI_NVME_AEI_NOTICE_SHIFT 8
294 #define PCI_NVME_AEI_NOTICE_MASK(event) (1 << (event + PCI_NVME_AEI_NOTICE_SHIFT))
295
296 /* Asynchronous Event Notifications */
297 struct pci_nvme_aen {
298 pci_nvme_async_type atype;
299 uint32_t event_data;
300 bool posted;
301 };
302
303 /*
304 * By default, enable all Asynchrnous Event Notifications:
305 * SMART / Health Critical Warnings
306 * Namespace Attribute Notices
307 */
308 #define PCI_NVME_AEN_DEFAULT_MASK 0x11f
309
310 typedef enum {
311 NVME_CNTRLTYPE_IO = 1,
312 NVME_CNTRLTYPE_DISCOVERY = 2,
313 NVME_CNTRLTYPE_ADMIN = 3,
314 } pci_nvme_cntrl_type;
315
316 struct pci_nvme_softc {
317 struct pci_devinst *nsc_pi;
318
319 pthread_mutex_t mtx;
320
321 struct nvme_registers regs;
322
323 struct nvme_namespace_data nsdata;
324 struct nvme_controller_data ctrldata;
325 struct nvme_error_information_entry err_log;
326 struct nvme_health_information_page health_log;
327 struct nvme_firmware_page fw_log;
328 struct nvme_ns_list ns_log;
329
330 struct pci_nvme_blockstore nvstore;
331
332 uint16_t max_qentries; /* max entries per queue */
333 uint32_t max_queues; /* max number of IO SQ's or CQ's */
334 uint32_t num_cqueues;
335 uint32_t num_squeues;
336 bool num_q_is_set; /* Has host set Number of Queues */
337
338 struct pci_nvme_ioreq *ioreqs;
339 STAILQ_HEAD(, pci_nvme_ioreq) ioreqs_free; /* free list of ioreqs */
340 uint32_t pending_ios;
341 uint32_t ioslots;
342 sem_t iosemlock;
343
344 /*
345 * Memory mapped Submission and Completion queues
346 * Each array includes both Admin and IO queues
347 */
348 struct nvme_completion_queue *compl_queues;
349 struct nvme_submission_queue *submit_queues;
350
351 struct nvme_feature_obj feat[NVME_FID_MAX];
352
353 enum nvme_dsm_type dataset_management;
354
355 /* Accounting for SMART data */
356 __uint128_t read_data_units;
357 __uint128_t write_data_units;
358 __uint128_t read_commands;
359 __uint128_t write_commands;
360 uint32_t read_dunits_remainder;
361 uint32_t write_dunits_remainder;
362
363 STAILQ_HEAD(, pci_nvme_aer) aer_list;
364 pthread_mutex_t aer_mtx;
365 uint32_t aer_count;
366 struct pci_nvme_aen aen[PCI_NVME_AE_TYPE_MAX];
367 pthread_t aen_tid;
368 pthread_mutex_t aen_mtx;
369 pthread_cond_t aen_cond;
370 };
371
372
373 static void pci_nvme_cq_update(struct pci_nvme_softc *sc,
374 struct nvme_completion_queue *cq,
375 uint32_t cdw0,
376 uint16_t cid,
377 uint16_t sqid,
378 uint16_t status);
379 static struct pci_nvme_ioreq *pci_nvme_get_ioreq(struct pci_nvme_softc *);
380 static void pci_nvme_release_ioreq(struct pci_nvme_softc *, struct pci_nvme_ioreq *);
381 static void pci_nvme_io_done(struct blockif_req *, int);
382
383 /* Controller Configuration utils */
384 #define NVME_CC_GET_EN(cc) \
385 ((cc) >> NVME_CC_REG_EN_SHIFT & NVME_CC_REG_EN_MASK)
386 #define NVME_CC_GET_CSS(cc) \
387 ((cc) >> NVME_CC_REG_CSS_SHIFT & NVME_CC_REG_CSS_MASK)
388 #define NVME_CC_GET_SHN(cc) \
389 ((cc) >> NVME_CC_REG_SHN_SHIFT & NVME_CC_REG_SHN_MASK)
390 #define NVME_CC_GET_IOSQES(cc) \
391 ((cc) >> NVME_CC_REG_IOSQES_SHIFT & NVME_CC_REG_IOSQES_MASK)
392 #define NVME_CC_GET_IOCQES(cc) \
393 ((cc) >> NVME_CC_REG_IOCQES_SHIFT & NVME_CC_REG_IOCQES_MASK)
394
395 #define NVME_CC_WRITE_MASK \
396 ((NVME_CC_REG_EN_MASK << NVME_CC_REG_EN_SHIFT) | \
397 (NVME_CC_REG_IOSQES_MASK << NVME_CC_REG_IOSQES_SHIFT) | \
398 (NVME_CC_REG_IOCQES_MASK << NVME_CC_REG_IOCQES_SHIFT))
399
400 #define NVME_CC_NEN_WRITE_MASK \
401 ((NVME_CC_REG_CSS_MASK << NVME_CC_REG_CSS_SHIFT) | \
402 (NVME_CC_REG_MPS_MASK << NVME_CC_REG_MPS_SHIFT) | \
403 (NVME_CC_REG_AMS_MASK << NVME_CC_REG_AMS_SHIFT))
404
405 /* Controller Status utils */
406 #define NVME_CSTS_GET_RDY(sts) \
407 ((sts) >> NVME_CSTS_REG_RDY_SHIFT & NVME_CSTS_REG_RDY_MASK)
408
409 #define NVME_CSTS_RDY (1 << NVME_CSTS_REG_RDY_SHIFT)
410 #define NVME_CSTS_CFS (1 << NVME_CSTS_REG_CFS_SHIFT)
411
412 /* Completion Queue status word utils */
413 #define NVME_STATUS_P (1 << NVME_STATUS_P_SHIFT)
414 #define NVME_STATUS_MASK \
415 ((NVME_STATUS_SCT_MASK << NVME_STATUS_SCT_SHIFT) |\
416 (NVME_STATUS_SC_MASK << NVME_STATUS_SC_SHIFT))
417
418 #define NVME_ONCS_DSM (NVME_CTRLR_DATA_ONCS_DSM_MASK << \
419 NVME_CTRLR_DATA_ONCS_DSM_SHIFT)
420
421 static void nvme_feature_invalid_cb(struct pci_nvme_softc *,
422 struct nvme_feature_obj *,
423 struct nvme_command *,
424 struct nvme_completion *);
425 static void nvme_feature_temperature(struct pci_nvme_softc *,
426 struct nvme_feature_obj *,
427 struct nvme_command *,
428 struct nvme_completion *);
429 static void nvme_feature_num_queues(struct pci_nvme_softc *,
430 struct nvme_feature_obj *,
431 struct nvme_command *,
432 struct nvme_completion *);
433 static void nvme_feature_iv_config(struct pci_nvme_softc *,
434 struct nvme_feature_obj *,
435 struct nvme_command *,
436 struct nvme_completion *);
437 static void nvme_feature_async_event(struct pci_nvme_softc *,
438 struct nvme_feature_obj *,
439 struct nvme_command *,
440 struct nvme_completion *);
441
442 static void *aen_thr(void *arg);
443
444 static __inline void
cpywithpad(char * dst,size_t dst_size,const char * src,char pad)445 cpywithpad(char *dst, size_t dst_size, const char *src, char pad)
446 {
447 size_t len;
448
449 len = strnlen(src, dst_size);
450 memset(dst, pad, dst_size);
451 memcpy(dst, src, len);
452 }
453
454 static __inline void
pci_nvme_status_tc(uint16_t * status,uint16_t type,uint16_t code)455 pci_nvme_status_tc(uint16_t *status, uint16_t type, uint16_t code)
456 {
457
458 *status &= ~NVME_STATUS_MASK;
459 *status |= (type & NVME_STATUS_SCT_MASK) << NVME_STATUS_SCT_SHIFT |
460 (code & NVME_STATUS_SC_MASK) << NVME_STATUS_SC_SHIFT;
461 }
462
463 static __inline void
pci_nvme_status_genc(uint16_t * status,uint16_t code)464 pci_nvme_status_genc(uint16_t *status, uint16_t code)
465 {
466
467 pci_nvme_status_tc(status, NVME_SCT_GENERIC, code);
468 }
469
470 /*
471 * Initialize the requested number or IO Submission and Completion Queues.
472 * Admin queues are allocated implicitly.
473 */
474 static void
pci_nvme_init_queues(struct pci_nvme_softc * sc,uint32_t nsq,uint32_t ncq)475 pci_nvme_init_queues(struct pci_nvme_softc *sc, uint32_t nsq, uint32_t ncq)
476 {
477 uint32_t i;
478
479 /*
480 * Allocate and initialize the Submission Queues
481 */
482 if (nsq > NVME_QUEUES) {
483 WPRINTF("%s: clamping number of SQ from %u to %u",
484 __func__, nsq, NVME_QUEUES);
485 nsq = NVME_QUEUES;
486 }
487
488 sc->num_squeues = nsq;
489
490 sc->submit_queues = calloc(sc->num_squeues + 1,
491 sizeof(struct nvme_submission_queue));
492 if (sc->submit_queues == NULL) {
493 WPRINTF("%s: SQ allocation failed", __func__);
494 sc->num_squeues = 0;
495 } else {
496 struct nvme_submission_queue *sq = sc->submit_queues;
497
498 for (i = 0; i < sc->num_squeues + 1; i++)
499 pthread_mutex_init(&sq[i].mtx, NULL);
500 }
501
502 /*
503 * Allocate and initialize the Completion Queues
504 */
505 if (ncq > NVME_QUEUES) {
506 WPRINTF("%s: clamping number of CQ from %u to %u",
507 __func__, ncq, NVME_QUEUES);
508 ncq = NVME_QUEUES;
509 }
510
511 sc->num_cqueues = ncq;
512
513 sc->compl_queues = calloc(sc->num_cqueues + 1,
514 sizeof(struct nvme_completion_queue));
515 if (sc->compl_queues == NULL) {
516 WPRINTF("%s: CQ allocation failed", __func__);
517 sc->num_cqueues = 0;
518 } else {
519 struct nvme_completion_queue *cq = sc->compl_queues;
520
521 for (i = 0; i < sc->num_cqueues + 1; i++)
522 pthread_mutex_init(&cq[i].mtx, NULL);
523 }
524 }
525
526 static void
pci_nvme_init_ctrldata(struct pci_nvme_softc * sc)527 pci_nvme_init_ctrldata(struct pci_nvme_softc *sc)
528 {
529 struct nvme_controller_data *cd = &sc->ctrldata;
530 int ret;
531
532 cd->vid = 0xFB5D;
533 cd->ssvid = 0x0000;
534
535 cpywithpad((char *)cd->mn, sizeof(cd->mn), "bhyve-NVMe", ' ');
536 cpywithpad((char *)cd->fr, sizeof(cd->fr), "1.0", ' ');
537
538 /* Num of submission commands that we can handle at a time (2^rab) */
539 cd->rab = 4;
540
541 /* FreeBSD OUI */
542 cd->ieee[0] = 0xfc;
543 cd->ieee[1] = 0x9c;
544 cd->ieee[2] = 0x58;
545
546 cd->mic = 0;
547
548 cd->mdts = NVME_MDTS; /* max data transfer size (2^mdts * CAP.MPSMIN) */
549
550 cd->ver = NVME_REV(1,4);
551
552 cd->cntrltype = NVME_CNTRLTYPE_IO;
553 cd->oacs = 1 << NVME_CTRLR_DATA_OACS_FORMAT_SHIFT;
554 cd->oaes = NVMEB(NVME_CTRLR_DATA_OAES_NS_ATTR);
555 cd->acl = 2;
556 cd->aerl = 4;
557
558 /* Advertise 1, Read-only firmware slot */
559 cd->frmw = NVMEB(NVME_CTRLR_DATA_FRMW_SLOT1_RO) |
560 (1 << NVME_CTRLR_DATA_FRMW_NUM_SLOTS_SHIFT);
561 cd->lpa = 0; /* TODO: support some simple things like SMART */
562 cd->elpe = 0; /* max error log page entries */
563 /*
564 * Report a single power state (zero-based value)
565 * power_state[] values are left as zero to indicate "Not reported"
566 */
567 cd->npss = 0;
568
569 /* Warning Composite Temperature Threshold */
570 cd->wctemp = 0x0157;
571 cd->cctemp = 0x0157;
572
573 /* SANICAP must not be 0 for Revision 1.4 and later NVMe Controllers */
574 cd->sanicap = (NVME_CTRLR_DATA_SANICAP_NODMMAS_NO <<
575 NVME_CTRLR_DATA_SANICAP_NODMMAS_SHIFT);
576
577 cd->sqes = (6 << NVME_CTRLR_DATA_SQES_MAX_SHIFT) |
578 (6 << NVME_CTRLR_DATA_SQES_MIN_SHIFT);
579 cd->cqes = (4 << NVME_CTRLR_DATA_CQES_MAX_SHIFT) |
580 (4 << NVME_CTRLR_DATA_CQES_MIN_SHIFT);
581 cd->nn = 1; /* number of namespaces */
582
583 cd->oncs = 0;
584 switch (sc->dataset_management) {
585 case NVME_DATASET_MANAGEMENT_AUTO:
586 if (sc->nvstore.deallocate)
587 cd->oncs |= NVME_ONCS_DSM;
588 break;
589 case NVME_DATASET_MANAGEMENT_ENABLE:
590 cd->oncs |= NVME_ONCS_DSM;
591 break;
592 default:
593 break;
594 }
595
596 cd->fna = NVME_CTRLR_DATA_FNA_FORMAT_ALL_MASK <<
597 NVME_CTRLR_DATA_FNA_FORMAT_ALL_SHIFT;
598
599 cd->vwc = NVME_CTRLR_DATA_VWC_ALL_NO << NVME_CTRLR_DATA_VWC_ALL_SHIFT;
600
601 ret = snprintf(cd->subnqn, sizeof(cd->subnqn),
602 "nqn.2013-12.org.freebsd:bhyve-%s-%u-%u-%u",
603 get_config_value("name"), sc->nsc_pi->pi_bus,
604 sc->nsc_pi->pi_slot, sc->nsc_pi->pi_func);
605 if ((ret < 0) || ((unsigned)ret > sizeof(cd->subnqn)))
606 EPRINTLN("%s: error setting subnqn (%d)", __func__, ret);
607 }
608
609 /*
610 * Calculate the CRC-16 of the given buffer
611 * See copyright attribution at top of file
612 */
613 static uint16_t
crc16(uint16_t crc,const void * buffer,unsigned int len)614 crc16(uint16_t crc, const void *buffer, unsigned int len)
615 {
616 const unsigned char *cp = buffer;
617 /* CRC table for the CRC-16. The poly is 0x8005 (x16 + x15 + x2 + 1). */
618 static uint16_t const crc16_table[256] = {
619 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
620 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
621 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
622 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
623 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
624 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
625 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
626 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
627 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
628 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
629 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
630 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
631 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
632 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
633 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
634 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
635 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
636 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
637 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
638 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
639 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
640 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
641 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
642 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
643 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
644 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
645 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
646 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
647 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
648 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
649 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
650 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
651 };
652
653 while (len--)
654 crc = (((crc >> 8) & 0xffU) ^
655 crc16_table[(crc ^ *cp++) & 0xffU]) & 0x0000ffffU;
656 return crc;
657 }
658
659 static void
pci_nvme_init_nsdata_size(struct pci_nvme_blockstore * nvstore,struct nvme_namespace_data * nd)660 pci_nvme_init_nsdata_size(struct pci_nvme_blockstore *nvstore,
661 struct nvme_namespace_data *nd)
662 {
663
664 /* Get capacity and block size information from backing store */
665 nd->nsze = nvstore->size / nvstore->sectsz;
666 nd->ncap = nd->nsze;
667 nd->nuse = nd->nsze;
668 }
669
670 static void
pci_nvme_init_nsdata(struct pci_nvme_softc * sc,struct nvme_namespace_data * nd,uint32_t nsid,struct pci_nvme_blockstore * nvstore)671 pci_nvme_init_nsdata(struct pci_nvme_softc *sc,
672 struct nvme_namespace_data *nd, uint32_t nsid,
673 struct pci_nvme_blockstore *nvstore)
674 {
675
676 pci_nvme_init_nsdata_size(nvstore, nd);
677
678 if (nvstore->type == NVME_STOR_BLOCKIF)
679 nvstore->deallocate = blockif_candelete(nvstore->ctx);
680
681 nd->nlbaf = 0; /* NLBAF is a 0's based value (i.e. 1 LBA Format) */
682 nd->flbas = 0;
683
684 /* Create an EUI-64 if user did not provide one */
685 if (nvstore->eui64 == 0) {
686 char *data = NULL;
687 uint64_t eui64 = nvstore->eui64;
688
689 asprintf(&data, "%s%u%u%u", get_config_value("name"),
690 sc->nsc_pi->pi_bus, sc->nsc_pi->pi_slot,
691 sc->nsc_pi->pi_func);
692
693 if (data != NULL) {
694 eui64 = OUI_FREEBSD_NVME_LOW | crc16(0, data, strlen(data));
695 free(data);
696 }
697 nvstore->eui64 = (eui64 << 16) | (nsid & 0xffff);
698 }
699 be64enc(nd->eui64, nvstore->eui64);
700
701 /* LBA data-sz = 2^lbads */
702 nd->lbaf[0] = nvstore->sectsz_bits << NVME_NS_DATA_LBAF_LBADS_SHIFT;
703 }
704
705 static void
pci_nvme_init_logpages(struct pci_nvme_softc * sc)706 pci_nvme_init_logpages(struct pci_nvme_softc *sc)
707 {
708 __uint128_t power_cycles = 1;
709
710 memset(&sc->err_log, 0, sizeof(sc->err_log));
711 memset(&sc->health_log, 0, sizeof(sc->health_log));
712 memset(&sc->fw_log, 0, sizeof(sc->fw_log));
713 memset(&sc->ns_log, 0, sizeof(sc->ns_log));
714
715 /* Set read/write remainder to round up according to spec */
716 sc->read_dunits_remainder = 999;
717 sc->write_dunits_remainder = 999;
718
719 /* Set nominal Health values checked by implementations */
720 sc->health_log.temperature = NVME_TEMPERATURE;
721 sc->health_log.available_spare = 100;
722 sc->health_log.available_spare_threshold = 10;
723
724 /* Set Active Firmware Info to slot 1 */
725 sc->fw_log.afi = (1 << NVME_FIRMWARE_PAGE_AFI_SLOT_SHIFT);
726 memcpy(&sc->fw_log.revision[0], sc->ctrldata.fr,
727 sizeof(sc->fw_log.revision[0]));
728
729 memcpy(&sc->health_log.power_cycles, &power_cycles,
730 sizeof(sc->health_log.power_cycles));
731 }
732
733 static void
pci_nvme_init_features(struct pci_nvme_softc * sc)734 pci_nvme_init_features(struct pci_nvme_softc *sc)
735 {
736 enum nvme_feature fid;
737
738 for (fid = 0; fid < NVME_FID_MAX; fid++) {
739 switch (fid) {
740 case NVME_FEAT_ARBITRATION:
741 case NVME_FEAT_POWER_MANAGEMENT:
742 case NVME_FEAT_INTERRUPT_COALESCING: //XXX
743 case NVME_FEAT_WRITE_ATOMICITY:
744 /* Mandatory but no special handling required */
745 //XXX hang - case NVME_FEAT_PREDICTABLE_LATENCY_MODE_CONFIG:
746 //XXX hang - case NVME_FEAT_HOST_BEHAVIOR_SUPPORT:
747 // this returns a data buffer
748 break;
749 case NVME_FEAT_TEMPERATURE_THRESHOLD:
750 sc->feat[fid].set = nvme_feature_temperature;
751 break;
752 case NVME_FEAT_ERROR_RECOVERY:
753 sc->feat[fid].namespace_specific = true;
754 break;
755 case NVME_FEAT_NUMBER_OF_QUEUES:
756 sc->feat[fid].set = nvme_feature_num_queues;
757 break;
758 case NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION:
759 sc->feat[fid].set = nvme_feature_iv_config;
760 break;
761 case NVME_FEAT_ASYNC_EVENT_CONFIGURATION:
762 sc->feat[fid].set = nvme_feature_async_event;
763 /* Enable all AENs by default */
764 sc->feat[fid].cdw11 = PCI_NVME_AEN_DEFAULT_MASK;
765 break;
766 default:
767 sc->feat[fid].set = nvme_feature_invalid_cb;
768 sc->feat[fid].get = nvme_feature_invalid_cb;
769 }
770 }
771 }
772
773 static void
pci_nvme_aer_reset(struct pci_nvme_softc * sc)774 pci_nvme_aer_reset(struct pci_nvme_softc *sc)
775 {
776
777 STAILQ_INIT(&sc->aer_list);
778 sc->aer_count = 0;
779 }
780
781 static void
pci_nvme_aer_init(struct pci_nvme_softc * sc)782 pci_nvme_aer_init(struct pci_nvme_softc *sc)
783 {
784
785 pthread_mutex_init(&sc->aer_mtx, NULL);
786 pci_nvme_aer_reset(sc);
787 }
788
789 static void
pci_nvme_aer_destroy(struct pci_nvme_softc * sc)790 pci_nvme_aer_destroy(struct pci_nvme_softc *sc)
791 {
792 struct pci_nvme_aer *aer = NULL;
793
794 pthread_mutex_lock(&sc->aer_mtx);
795 while (!STAILQ_EMPTY(&sc->aer_list)) {
796 aer = STAILQ_FIRST(&sc->aer_list);
797 STAILQ_REMOVE_HEAD(&sc->aer_list, link);
798 free(aer);
799 }
800 pthread_mutex_unlock(&sc->aer_mtx);
801
802 pci_nvme_aer_reset(sc);
803 }
804
805 static bool
pci_nvme_aer_available(struct pci_nvme_softc * sc)806 pci_nvme_aer_available(struct pci_nvme_softc *sc)
807 {
808
809 return (sc->aer_count != 0);
810 }
811
812 static bool
pci_nvme_aer_limit_reached(struct pci_nvme_softc * sc)813 pci_nvme_aer_limit_reached(struct pci_nvme_softc *sc)
814 {
815 struct nvme_controller_data *cd = &sc->ctrldata;
816
817 /* AERL is a zero based value while aer_count is one's based */
818 return (sc->aer_count == (cd->aerl + 1U));
819 }
820
821 /*
822 * Add an Async Event Request
823 *
824 * Stores an AER to be returned later if the Controller needs to notify the
825 * host of an event.
826 * Note that while the NVMe spec doesn't require Controllers to return AER's
827 * in order, this implementation does preserve the order.
828 */
829 static int
pci_nvme_aer_add(struct pci_nvme_softc * sc,uint16_t cid)830 pci_nvme_aer_add(struct pci_nvme_softc *sc, uint16_t cid)
831 {
832 struct pci_nvme_aer *aer = NULL;
833
834 aer = calloc(1, sizeof(struct pci_nvme_aer));
835 if (aer == NULL)
836 return (-1);
837
838 /* Save the Command ID for use in the completion message */
839 aer->cid = cid;
840
841 pthread_mutex_lock(&sc->aer_mtx);
842 sc->aer_count++;
843 STAILQ_INSERT_TAIL(&sc->aer_list, aer, link);
844 pthread_mutex_unlock(&sc->aer_mtx);
845
846 return (0);
847 }
848
849 /*
850 * Get an Async Event Request structure
851 *
852 * Returns a pointer to an AER previously submitted by the host or NULL if
853 * no AER's exist. Caller is responsible for freeing the returned struct.
854 */
855 static struct pci_nvme_aer *
pci_nvme_aer_get(struct pci_nvme_softc * sc)856 pci_nvme_aer_get(struct pci_nvme_softc *sc)
857 {
858 struct pci_nvme_aer *aer = NULL;
859
860 pthread_mutex_lock(&sc->aer_mtx);
861 aer = STAILQ_FIRST(&sc->aer_list);
862 if (aer != NULL) {
863 STAILQ_REMOVE_HEAD(&sc->aer_list, link);
864 sc->aer_count--;
865 }
866 pthread_mutex_unlock(&sc->aer_mtx);
867
868 return (aer);
869 }
870
871 static void
pci_nvme_aen_reset(struct pci_nvme_softc * sc)872 pci_nvme_aen_reset(struct pci_nvme_softc *sc)
873 {
874 uint32_t atype;
875
876 memset(sc->aen, 0, PCI_NVME_AE_TYPE_MAX * sizeof(struct pci_nvme_aen));
877
878 for (atype = 0; atype < PCI_NVME_AE_TYPE_MAX; atype++) {
879 sc->aen[atype].atype = atype;
880 }
881 }
882
883 static void
pci_nvme_aen_init(struct pci_nvme_softc * sc)884 pci_nvme_aen_init(struct pci_nvme_softc *sc)
885 {
886 char nstr[80];
887
888 pci_nvme_aen_reset(sc);
889
890 pthread_mutex_init(&sc->aen_mtx, NULL);
891 pthread_create(&sc->aen_tid, NULL, aen_thr, sc);
892 snprintf(nstr, sizeof(nstr), "nvme-aen-%d:%d", sc->nsc_pi->pi_slot,
893 sc->nsc_pi->pi_func);
894 pthread_set_name_np(sc->aen_tid, nstr);
895 }
896
897 static void
pci_nvme_aen_destroy(struct pci_nvme_softc * sc)898 pci_nvme_aen_destroy(struct pci_nvme_softc *sc)
899 {
900
901 pci_nvme_aen_reset(sc);
902 }
903
904 /* Notify the AEN thread of pending work */
905 static void
pci_nvme_aen_notify(struct pci_nvme_softc * sc)906 pci_nvme_aen_notify(struct pci_nvme_softc *sc)
907 {
908
909 pthread_cond_signal(&sc->aen_cond);
910 }
911
912 /*
913 * Post an Asynchronous Event Notification
914 */
915 static int32_t
pci_nvme_aen_post(struct pci_nvme_softc * sc,pci_nvme_async_type atype,uint32_t event_data)916 pci_nvme_aen_post(struct pci_nvme_softc *sc, pci_nvme_async_type atype,
917 uint32_t event_data)
918 {
919 struct pci_nvme_aen *aen;
920
921 if (atype >= PCI_NVME_AE_TYPE_MAX) {
922 return(EINVAL);
923 }
924
925 pthread_mutex_lock(&sc->aen_mtx);
926 aen = &sc->aen[atype];
927
928 /* Has the controller already posted an event of this type? */
929 if (aen->posted) {
930 pthread_mutex_unlock(&sc->aen_mtx);
931 return(EALREADY);
932 }
933
934 aen->event_data = event_data;
935 aen->posted = true;
936 pthread_mutex_unlock(&sc->aen_mtx);
937
938 pci_nvme_aen_notify(sc);
939
940 return(0);
941 }
942
943 static void
pci_nvme_aen_process(struct pci_nvme_softc * sc)944 pci_nvme_aen_process(struct pci_nvme_softc *sc)
945 {
946 struct pci_nvme_aer *aer;
947 struct pci_nvme_aen *aen;
948 pci_nvme_async_type atype;
949 uint32_t mask;
950 uint16_t status;
951 uint8_t lid;
952
953 assert(pthread_mutex_isowned_np(&sc->aen_mtx));
954 for (atype = 0; atype < PCI_NVME_AE_TYPE_MAX; atype++) {
955 aen = &sc->aen[atype];
956 /* Previous iterations may have depleted the available AER's */
957 if (!pci_nvme_aer_available(sc)) {
958 DPRINTF("%s: no AER", __func__);
959 break;
960 }
961
962 if (!aen->posted) {
963 DPRINTF("%s: no AEN posted for atype=%#x", __func__, atype);
964 continue;
965 }
966
967 status = NVME_SC_SUCCESS;
968
969 /* Is the event masked? */
970 mask =
971 sc->feat[NVME_FEAT_ASYNC_EVENT_CONFIGURATION].cdw11;
972
973 DPRINTF("%s: atype=%#x mask=%#x event_data=%#x", __func__, atype, mask, aen->event_data);
974 switch (atype) {
975 case PCI_NVME_AE_TYPE_ERROR:
976 lid = NVME_LOG_ERROR;
977 break;
978 case PCI_NVME_AE_TYPE_SMART:
979 mask &= 0xff;
980 if ((mask & aen->event_data) == 0)
981 continue;
982 lid = NVME_LOG_HEALTH_INFORMATION;
983 break;
984 case PCI_NVME_AE_TYPE_NOTICE:
985 if (aen->event_data >= PCI_NVME_AEI_NOTICE_MAX) {
986 EPRINTLN("%s unknown AEN notice type %u",
987 __func__, aen->event_data);
988 status = NVME_SC_INTERNAL_DEVICE_ERROR;
989 lid = 0;
990 break;
991 }
992 if ((PCI_NVME_AEI_NOTICE_MASK(aen->event_data) & mask) == 0)
993 continue;
994 switch (aen->event_data) {
995 case PCI_NVME_AEI_NOTICE_NS_ATTR_CHANGED:
996 lid = NVME_LOG_CHANGED_NAMESPACE;
997 break;
998 case PCI_NVME_AEI_NOTICE_FW_ACTIVATION:
999 lid = NVME_LOG_FIRMWARE_SLOT;
1000 break;
1001 case PCI_NVME_AEI_NOTICE_TELEMETRY_CHANGE:
1002 lid = NVME_LOG_TELEMETRY_CONTROLLER_INITIATED;
1003 break;
1004 case PCI_NVME_AEI_NOTICE_ANA_CHANGE:
1005 lid = NVME_LOG_ASYMMETRIC_NAMESPACE_ACCESS;
1006 break;
1007 case PCI_NVME_AEI_NOTICE_PREDICT_LATENCY_CHANGE:
1008 lid = NVME_LOG_PREDICTABLE_LATENCY_EVENT_AGGREGATE;
1009 break;
1010 case PCI_NVME_AEI_NOTICE_LBA_STATUS_ALERT:
1011 lid = NVME_LOG_LBA_STATUS_INFORMATION;
1012 break;
1013 case PCI_NVME_AEI_NOTICE_ENDURANCE_GROUP_CHANGE:
1014 lid = NVME_LOG_ENDURANCE_GROUP_EVENT_AGGREGATE;
1015 break;
1016 default:
1017 lid = 0;
1018 }
1019 break;
1020 default:
1021 /* bad type?!? */
1022 EPRINTLN("%s unknown AEN type %u", __func__, atype);
1023 status = NVME_SC_INTERNAL_DEVICE_ERROR;
1024 lid = 0;
1025 break;
1026 }
1027
1028 aer = pci_nvme_aer_get(sc);
1029 assert(aer != NULL);
1030
1031 DPRINTF("%s: CID=%#x CDW0=%#x", __func__, aer->cid, (lid << 16) | (aen->event_data << 8) | atype);
1032 pci_nvme_cq_update(sc, &sc->compl_queues[0],
1033 (lid << 16) | (aen->event_data << 8) | atype, /* cdw0 */
1034 aer->cid,
1035 0, /* SQID */
1036 status);
1037
1038 aen->event_data = 0;
1039 aen->posted = false;
1040
1041 pci_generate_msix(sc->nsc_pi, 0);
1042 }
1043 }
1044
1045 static void *
aen_thr(void * arg)1046 aen_thr(void *arg)
1047 {
1048 struct pci_nvme_softc *sc;
1049
1050 sc = arg;
1051
1052 pthread_mutex_lock(&sc->aen_mtx);
1053 for (;;) {
1054 pci_nvme_aen_process(sc);
1055 pthread_cond_wait(&sc->aen_cond, &sc->aen_mtx);
1056 }
1057 pthread_mutex_unlock(&sc->aen_mtx);
1058
1059 pthread_exit(NULL);
1060 return (NULL);
1061 }
1062
1063 static void
pci_nvme_reset_locked(struct pci_nvme_softc * sc)1064 pci_nvme_reset_locked(struct pci_nvme_softc *sc)
1065 {
1066 uint32_t i;
1067
1068 DPRINTF("%s", __func__);
1069
1070 sc->regs.cap_lo = (ZERO_BASED(sc->max_qentries) & NVME_CAP_LO_REG_MQES_MASK) |
1071 (1 << NVME_CAP_LO_REG_CQR_SHIFT) |
1072 (60 << NVME_CAP_LO_REG_TO_SHIFT);
1073
1074 sc->regs.cap_hi = 1 << NVME_CAP_HI_REG_CSS_NVM_SHIFT;
1075
1076 sc->regs.vs = NVME_REV(1,4); /* NVMe v1.4 */
1077
1078 sc->regs.cc = 0;
1079
1080 assert(sc->submit_queues != NULL);
1081
1082 for (i = 0; i < sc->num_squeues + 1; i++) {
1083 sc->submit_queues[i].qbase = NULL;
1084 sc->submit_queues[i].size = 0;
1085 sc->submit_queues[i].cqid = 0;
1086 sc->submit_queues[i].tail = 0;
1087 sc->submit_queues[i].head = 0;
1088 }
1089
1090 assert(sc->compl_queues != NULL);
1091
1092 for (i = 0; i < sc->num_cqueues + 1; i++) {
1093 sc->compl_queues[i].qbase = NULL;
1094 sc->compl_queues[i].size = 0;
1095 sc->compl_queues[i].tail = 0;
1096 sc->compl_queues[i].head = 0;
1097 }
1098
1099 sc->num_q_is_set = false;
1100
1101 pci_nvme_aer_destroy(sc);
1102 pci_nvme_aen_destroy(sc);
1103
1104 /*
1105 * Clear CSTS.RDY last to prevent the host from enabling Controller
1106 * before cleanup completes
1107 */
1108 sc->regs.csts = 0;
1109 }
1110
1111 static void
pci_nvme_reset(struct pci_nvme_softc * sc)1112 pci_nvme_reset(struct pci_nvme_softc *sc)
1113 {
1114 pthread_mutex_lock(&sc->mtx);
1115 pci_nvme_reset_locked(sc);
1116 pthread_mutex_unlock(&sc->mtx);
1117 }
1118
1119 static int
pci_nvme_init_controller(struct pci_nvme_softc * sc)1120 pci_nvme_init_controller(struct pci_nvme_softc *sc)
1121 {
1122 uint16_t acqs, asqs;
1123
1124 DPRINTF("%s", __func__);
1125
1126 /*
1127 * NVMe 2.0 states that "enabling a controller while this field is
1128 * cleared to 0h produces undefined results" for both ACQS and
1129 * ASQS. If zero, set CFS and do not become ready.
1130 */
1131 asqs = ONE_BASED(sc->regs.aqa & NVME_AQA_REG_ASQS_MASK);
1132 if (asqs < 2) {
1133 EPRINTLN("%s: illegal ASQS value %#x (aqa=%#x)", __func__,
1134 asqs - 1, sc->regs.aqa);
1135 sc->regs.csts |= NVME_CSTS_CFS;
1136 return (-1);
1137 }
1138 sc->submit_queues[0].size = asqs;
1139 sc->submit_queues[0].qbase = vm_map_gpa(sc->nsc_pi->pi_vmctx,
1140 sc->regs.asq, sizeof(struct nvme_command) * asqs);
1141 if (sc->submit_queues[0].qbase == NULL) {
1142 EPRINTLN("%s: ASQ vm_map_gpa(%lx) failed", __func__,
1143 sc->regs.asq);
1144 sc->regs.csts |= NVME_CSTS_CFS;
1145 return (-1);
1146 }
1147
1148 DPRINTF("%s mapping Admin-SQ guest 0x%lx, host: %p",
1149 __func__, sc->regs.asq, sc->submit_queues[0].qbase);
1150
1151 acqs = ONE_BASED((sc->regs.aqa >> NVME_AQA_REG_ACQS_SHIFT) &
1152 NVME_AQA_REG_ACQS_MASK);
1153 if (acqs < 2) {
1154 EPRINTLN("%s: illegal ACQS value %#x (aqa=%#x)", __func__,
1155 acqs - 1, sc->regs.aqa);
1156 sc->regs.csts |= NVME_CSTS_CFS;
1157 return (-1);
1158 }
1159 sc->compl_queues[0].size = acqs;
1160 sc->compl_queues[0].qbase = vm_map_gpa(sc->nsc_pi->pi_vmctx,
1161 sc->regs.acq, sizeof(struct nvme_completion) * acqs);
1162 if (sc->compl_queues[0].qbase == NULL) {
1163 EPRINTLN("%s: ACQ vm_map_gpa(%lx) failed", __func__,
1164 sc->regs.acq);
1165 sc->regs.csts |= NVME_CSTS_CFS;
1166 return (-1);
1167 }
1168 sc->compl_queues[0].intr_en = NVME_CQ_INTEN;
1169
1170 DPRINTF("%s mapping Admin-CQ guest 0x%lx, host: %p",
1171 __func__, sc->regs.acq, sc->compl_queues[0].qbase);
1172
1173 return (0);
1174 }
1175
1176 static int
nvme_prp_memcpy(struct vmctx * ctx,uint64_t prp1,uint64_t prp2,uint8_t * b,size_t len,enum nvme_copy_dir dir)1177 nvme_prp_memcpy(struct vmctx *ctx, uint64_t prp1, uint64_t prp2, uint8_t *b,
1178 size_t len, enum nvme_copy_dir dir)
1179 {
1180 uint8_t *p;
1181 size_t bytes;
1182
1183 if (len > (8 * 1024)) {
1184 return (-1);
1185 }
1186
1187 /* Copy from the start of prp1 to the end of the physical page */
1188 bytes = PAGE_SIZE - (prp1 & PAGE_MASK);
1189 bytes = MIN(bytes, len);
1190
1191 p = vm_map_gpa(ctx, prp1, bytes);
1192 if (p == NULL) {
1193 return (-1);
1194 }
1195
1196 if (dir == NVME_COPY_TO_PRP)
1197 memcpy(p, b, bytes);
1198 else
1199 memcpy(b, p, bytes);
1200
1201 b += bytes;
1202
1203 len -= bytes;
1204 if (len == 0) {
1205 return (0);
1206 }
1207
1208 len = MIN(len, PAGE_SIZE);
1209
1210 p = vm_map_gpa(ctx, prp2, len);
1211 if (p == NULL) {
1212 return (-1);
1213 }
1214
1215 if (dir == NVME_COPY_TO_PRP)
1216 memcpy(p, b, len);
1217 else
1218 memcpy(b, p, len);
1219
1220 return (0);
1221 }
1222
1223 /*
1224 * Write a Completion Queue Entry update
1225 *
1226 * Write the completion and update the doorbell value
1227 */
1228 static void
pci_nvme_cq_update(struct pci_nvme_softc * sc,struct nvme_completion_queue * cq,uint32_t cdw0,uint16_t cid,uint16_t sqid,uint16_t status)1229 pci_nvme_cq_update(struct pci_nvme_softc *sc,
1230 struct nvme_completion_queue *cq,
1231 uint32_t cdw0,
1232 uint16_t cid,
1233 uint16_t sqid,
1234 uint16_t status)
1235 {
1236 struct nvme_submission_queue *sq = &sc->submit_queues[sqid];
1237 struct nvme_completion *cqe;
1238
1239 assert(cq->qbase != NULL);
1240
1241 pthread_mutex_lock(&cq->mtx);
1242
1243 cqe = &cq->qbase[cq->tail];
1244
1245 /* Flip the phase bit */
1246 status |= (cqe->status ^ NVME_STATUS_P) & NVME_STATUS_P_MASK;
1247
1248 cqe->cdw0 = cdw0;
1249 cqe->sqhd = sq->head;
1250 cqe->sqid = sqid;
1251 cqe->cid = cid;
1252 cqe->status = status;
1253
1254 cq->tail++;
1255 if (cq->tail >= cq->size) {
1256 cq->tail = 0;
1257 }
1258
1259 pthread_mutex_unlock(&cq->mtx);
1260 }
1261
1262 static int
nvme_opc_delete_io_sq(struct pci_nvme_softc * sc,struct nvme_command * command,struct nvme_completion * compl)1263 nvme_opc_delete_io_sq(struct pci_nvme_softc* sc, struct nvme_command* command,
1264 struct nvme_completion* compl)
1265 {
1266 uint16_t qid = command->cdw10 & 0xffff;
1267
1268 DPRINTF("%s DELETE_IO_SQ %u", __func__, qid);
1269 if (qid == 0 || qid > sc->num_squeues ||
1270 (sc->submit_queues[qid].qbase == NULL)) {
1271 WPRINTF("%s NOT PERMITTED queue id %u / num_squeues %u",
1272 __func__, qid, sc->num_squeues);
1273 pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC,
1274 NVME_SC_INVALID_QUEUE_IDENTIFIER);
1275 return (1);
1276 }
1277
1278 sc->submit_queues[qid].qbase = NULL;
1279 sc->submit_queues[qid].cqid = 0;
1280 pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS);
1281 return (1);
1282 }
1283
1284 static int
nvme_opc_create_io_sq(struct pci_nvme_softc * sc,struct nvme_command * command,struct nvme_completion * compl)1285 nvme_opc_create_io_sq(struct pci_nvme_softc* sc, struct nvme_command* command,
1286 struct nvme_completion* compl)
1287 {
1288 if (command->cdw11 & NVME_CMD_CDW11_PC) {
1289 uint16_t qid = command->cdw10 & 0xffff;
1290 struct nvme_submission_queue *nsq;
1291
1292 if ((qid == 0) || (qid > sc->num_squeues) ||
1293 (sc->submit_queues[qid].qbase != NULL)) {
1294 WPRINTF("%s queue index %u > num_squeues %u",
1295 __func__, qid, sc->num_squeues);
1296 pci_nvme_status_tc(&compl->status,
1297 NVME_SCT_COMMAND_SPECIFIC,
1298 NVME_SC_INVALID_QUEUE_IDENTIFIER);
1299 return (1);
1300 }
1301
1302 nsq = &sc->submit_queues[qid];
1303 nsq->size = ONE_BASED((command->cdw10 >> 16) & 0xffff);
1304 DPRINTF("%s size=%u (max=%u)", __func__, nsq->size, sc->max_qentries);
1305 if ((nsq->size < 2) || (nsq->size > sc->max_qentries)) {
1306 /*
1307 * Queues must specify at least two entries
1308 * NOTE: "MAXIMUM QUEUE SIZE EXCEEDED" was renamed to
1309 * "INVALID QUEUE SIZE" in the NVM Express 1.3 Spec
1310 */
1311 pci_nvme_status_tc(&compl->status,
1312 NVME_SCT_COMMAND_SPECIFIC,
1313 NVME_SC_MAXIMUM_QUEUE_SIZE_EXCEEDED);
1314 return (1);
1315 }
1316 nsq->head = nsq->tail = 0;
1317
1318 nsq->cqid = (command->cdw11 >> 16) & 0xffff;
1319 if ((nsq->cqid == 0) || (nsq->cqid > sc->num_cqueues)) {
1320 pci_nvme_status_tc(&compl->status,
1321 NVME_SCT_COMMAND_SPECIFIC,
1322 NVME_SC_INVALID_QUEUE_IDENTIFIER);
1323 return (1);
1324 }
1325
1326 if (sc->compl_queues[nsq->cqid].qbase == NULL) {
1327 pci_nvme_status_tc(&compl->status,
1328 NVME_SCT_COMMAND_SPECIFIC,
1329 NVME_SC_COMPLETION_QUEUE_INVALID);
1330 return (1);
1331 }
1332
1333 nsq->qpriority = (command->cdw11 >> 1) & 0x03;
1334
1335 nsq->qbase = vm_map_gpa(sc->nsc_pi->pi_vmctx, command->prp1,
1336 sizeof(struct nvme_command) * (size_t)nsq->size);
1337
1338 DPRINTF("%s sq %u size %u gaddr %p cqid %u", __func__,
1339 qid, nsq->size, nsq->qbase, nsq->cqid);
1340
1341 pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS);
1342
1343 DPRINTF("%s completed creating IOSQ qid %u",
1344 __func__, qid);
1345 } else {
1346 /*
1347 * Guest sent non-cont submission queue request.
1348 * This setting is unsupported by this emulation.
1349 */
1350 WPRINTF("%s unsupported non-contig (list-based) "
1351 "create i/o submission queue", __func__);
1352
1353 pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
1354 }
1355 return (1);
1356 }
1357
1358 static int
nvme_opc_delete_io_cq(struct pci_nvme_softc * sc,struct nvme_command * command,struct nvme_completion * compl)1359 nvme_opc_delete_io_cq(struct pci_nvme_softc* sc, struct nvme_command* command,
1360 struct nvme_completion* compl)
1361 {
1362 uint16_t qid = command->cdw10 & 0xffff;
1363 uint16_t sqid;
1364
1365 DPRINTF("%s DELETE_IO_CQ %u", __func__, qid);
1366 if (qid == 0 || qid > sc->num_cqueues ||
1367 (sc->compl_queues[qid].qbase == NULL)) {
1368 WPRINTF("%s queue index %u / num_cqueues %u",
1369 __func__, qid, sc->num_cqueues);
1370 pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC,
1371 NVME_SC_INVALID_QUEUE_IDENTIFIER);
1372 return (1);
1373 }
1374
1375 /* Deleting an Active CQ is an error */
1376 for (sqid = 1; sqid < sc->num_squeues + 1; sqid++)
1377 if (sc->submit_queues[sqid].cqid == qid) {
1378 pci_nvme_status_tc(&compl->status,
1379 NVME_SCT_COMMAND_SPECIFIC,
1380 NVME_SC_INVALID_QUEUE_DELETION);
1381 return (1);
1382 }
1383
1384 sc->compl_queues[qid].qbase = NULL;
1385 pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS);
1386 return (1);
1387 }
1388
1389 static int
nvme_opc_create_io_cq(struct pci_nvme_softc * sc,struct nvme_command * command,struct nvme_completion * compl)1390 nvme_opc_create_io_cq(struct pci_nvme_softc* sc, struct nvme_command* command,
1391 struct nvme_completion* compl)
1392 {
1393 struct nvme_completion_queue *ncq;
1394 uint16_t qid = command->cdw10 & 0xffff;
1395
1396 /* Only support Physically Contiguous queues */
1397 if ((command->cdw11 & NVME_CMD_CDW11_PC) == 0) {
1398 WPRINTF("%s unsupported non-contig (list-based) "
1399 "create i/o completion queue",
1400 __func__);
1401
1402 pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
1403 return (1);
1404 }
1405
1406 if ((qid == 0) || (qid > sc->num_cqueues) ||
1407 (sc->compl_queues[qid].qbase != NULL)) {
1408 WPRINTF("%s queue index %u > num_cqueues %u",
1409 __func__, qid, sc->num_cqueues);
1410 pci_nvme_status_tc(&compl->status,
1411 NVME_SCT_COMMAND_SPECIFIC,
1412 NVME_SC_INVALID_QUEUE_IDENTIFIER);
1413 return (1);
1414 }
1415
1416 ncq = &sc->compl_queues[qid];
1417 ncq->intr_en = (command->cdw11 & NVME_CMD_CDW11_IEN) >> 1;
1418 ncq->intr_vec = (command->cdw11 >> 16) & 0xffff;
1419 if (ncq->intr_vec > (sc->max_queues + 1)) {
1420 pci_nvme_status_tc(&compl->status,
1421 NVME_SCT_COMMAND_SPECIFIC,
1422 NVME_SC_INVALID_INTERRUPT_VECTOR);
1423 return (1);
1424 }
1425
1426 ncq->size = ONE_BASED((command->cdw10 >> 16) & 0xffff);
1427 if ((ncq->size < 2) || (ncq->size > sc->max_qentries)) {
1428 /*
1429 * Queues must specify at least two entries
1430 * NOTE: "MAXIMUM QUEUE SIZE EXCEEDED" was renamed to
1431 * "INVALID QUEUE SIZE" in the NVM Express 1.3 Spec
1432 */
1433 pci_nvme_status_tc(&compl->status,
1434 NVME_SCT_COMMAND_SPECIFIC,
1435 NVME_SC_MAXIMUM_QUEUE_SIZE_EXCEEDED);
1436 return (1);
1437 }
1438 ncq->head = ncq->tail = 0;
1439 ncq->qbase = vm_map_gpa(sc->nsc_pi->pi_vmctx,
1440 command->prp1,
1441 sizeof(struct nvme_command) * (size_t)ncq->size);
1442
1443 pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS);
1444
1445
1446 return (1);
1447 }
1448
1449 static int
nvme_opc_get_log_page(struct pci_nvme_softc * sc,struct nvme_command * command,struct nvme_completion * compl)1450 nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command,
1451 struct nvme_completion* compl)
1452 {
1453 uint64_t logoff;
1454 uint32_t logsize;
1455 uint8_t logpage;
1456
1457 pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS);
1458
1459 /*
1460 * Command specifies the number of dwords to return in fields NUMDU
1461 * and NUMDL. This is a zero-based value.
1462 */
1463 logpage = command->cdw10 & 0xFF;
1464 logsize = ((command->cdw11 << 16) | (command->cdw10 >> 16)) + 1;
1465 logsize *= sizeof(uint32_t);
1466 logoff = ((uint64_t)(command->cdw13) << 32) | command->cdw12;
1467
1468 DPRINTF("%s log page %u offset %lu len %u", __func__, logpage, logoff, logsize);
1469
1470 switch (logpage) {
1471 case NVME_LOG_ERROR:
1472 if (logoff >= sizeof(sc->err_log)) {
1473 pci_nvme_status_genc(&compl->status,
1474 NVME_SC_INVALID_FIELD);
1475 break;
1476 }
1477
1478 nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1,
1479 command->prp2, (uint8_t *)&sc->err_log + logoff,
1480 MIN(logsize, sizeof(sc->err_log) - logoff),
1481 NVME_COPY_TO_PRP);
1482 break;
1483 case NVME_LOG_HEALTH_INFORMATION:
1484 if (logoff >= sizeof(sc->health_log)) {
1485 pci_nvme_status_genc(&compl->status,
1486 NVME_SC_INVALID_FIELD);
1487 break;
1488 }
1489
1490 pthread_mutex_lock(&sc->mtx);
1491 memcpy(&sc->health_log.data_units_read, &sc->read_data_units,
1492 sizeof(sc->health_log.data_units_read));
1493 memcpy(&sc->health_log.data_units_written, &sc->write_data_units,
1494 sizeof(sc->health_log.data_units_written));
1495 memcpy(&sc->health_log.host_read_commands, &sc->read_commands,
1496 sizeof(sc->health_log.host_read_commands));
1497 memcpy(&sc->health_log.host_write_commands, &sc->write_commands,
1498 sizeof(sc->health_log.host_write_commands));
1499 pthread_mutex_unlock(&sc->mtx);
1500
1501 nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1,
1502 command->prp2, (uint8_t *)&sc->health_log + logoff,
1503 MIN(logsize, sizeof(sc->health_log) - logoff),
1504 NVME_COPY_TO_PRP);
1505 break;
1506 case NVME_LOG_FIRMWARE_SLOT:
1507 if (logoff >= sizeof(sc->fw_log)) {
1508 pci_nvme_status_genc(&compl->status,
1509 NVME_SC_INVALID_FIELD);
1510 break;
1511 }
1512
1513 nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1,
1514 command->prp2, (uint8_t *)&sc->fw_log + logoff,
1515 MIN(logsize, sizeof(sc->fw_log) - logoff),
1516 NVME_COPY_TO_PRP);
1517 break;
1518 case NVME_LOG_CHANGED_NAMESPACE:
1519 if (logoff >= sizeof(sc->ns_log)) {
1520 pci_nvme_status_genc(&compl->status,
1521 NVME_SC_INVALID_FIELD);
1522 break;
1523 }
1524
1525 nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1,
1526 command->prp2, (uint8_t *)&sc->ns_log + logoff,
1527 MIN(logsize, sizeof(sc->ns_log) - logoff),
1528 NVME_COPY_TO_PRP);
1529 memset(&sc->ns_log, 0, sizeof(sc->ns_log));
1530 break;
1531 default:
1532 DPRINTF("%s get log page %x command not supported",
1533 __func__, logpage);
1534
1535 pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC,
1536 NVME_SC_INVALID_LOG_PAGE);
1537 }
1538
1539 return (1);
1540 }
1541
1542 static int
nvme_opc_identify(struct pci_nvme_softc * sc,struct nvme_command * command,struct nvme_completion * compl)1543 nvme_opc_identify(struct pci_nvme_softc* sc, struct nvme_command* command,
1544 struct nvme_completion* compl)
1545 {
1546 void *dest;
1547 uint16_t status;
1548
1549 DPRINTF("%s identify 0x%x nsid 0x%x", __func__,
1550 command->cdw10 & 0xFF, command->nsid);
1551
1552 status = 0;
1553 pci_nvme_status_genc(&status, NVME_SC_SUCCESS);
1554
1555 switch (command->cdw10 & 0xFF) {
1556 case 0x00: /* return Identify Namespace data structure */
1557 /* Global NS only valid with NS Management */
1558 if (command->nsid == NVME_GLOBAL_NAMESPACE_TAG) {
1559 pci_nvme_status_genc(&status,
1560 NVME_SC_INVALID_NAMESPACE_OR_FORMAT);
1561 break;
1562 }
1563 nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1,
1564 command->prp2, (uint8_t *)&sc->nsdata, sizeof(sc->nsdata),
1565 NVME_COPY_TO_PRP);
1566 break;
1567 case 0x01: /* return Identify Controller data structure */
1568 nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1,
1569 command->prp2, (uint8_t *)&sc->ctrldata,
1570 sizeof(sc->ctrldata),
1571 NVME_COPY_TO_PRP);
1572 break;
1573 case 0x02: /* list of 1024 active NSIDs > CDW1.NSID */
1574 dest = vm_map_gpa(sc->nsc_pi->pi_vmctx, command->prp1,
1575 sizeof(uint32_t) * 1024);
1576 /* All unused entries shall be zero */
1577 memset(dest, 0, sizeof(uint32_t) * 1024);
1578 ((uint32_t *)dest)[0] = 1;
1579 break;
1580 case 0x03: /* list of NSID structures in CDW1.NSID, 4096 bytes */
1581 if (command->nsid != 1) {
1582 pci_nvme_status_genc(&status,
1583 NVME_SC_INVALID_NAMESPACE_OR_FORMAT);
1584 break;
1585 }
1586 dest = vm_map_gpa(sc->nsc_pi->pi_vmctx, command->prp1,
1587 sizeof(uint32_t) * 1024);
1588 /* All bytes after the descriptor shall be zero */
1589 memset(dest, 0, sizeof(uint32_t) * 1024);
1590
1591 /* Return NIDT=1 (i.e. EUI64) descriptor */
1592 ((uint8_t *)dest)[0] = 1;
1593 ((uint8_t *)dest)[1] = sizeof(uint64_t);
1594 memcpy(((uint8_t *)dest) + 4, sc->nsdata.eui64, sizeof(uint64_t));
1595 break;
1596 case 0x13:
1597 /*
1598 * Controller list is optional but used by UNH tests. Return
1599 * a valid but empty list.
1600 */
1601 dest = vm_map_gpa(sc->nsc_pi->pi_vmctx, command->prp1,
1602 sizeof(uint16_t) * 2048);
1603 memset(dest, 0, sizeof(uint16_t) * 2048);
1604 break;
1605 default:
1606 DPRINTF("%s unsupported identify command requested 0x%x",
1607 __func__, command->cdw10 & 0xFF);
1608 pci_nvme_status_genc(&status, NVME_SC_INVALID_FIELD);
1609 break;
1610 }
1611
1612 compl->status = status;
1613 return (1);
1614 }
1615
1616 static const char *
nvme_fid_to_name(uint8_t fid)1617 nvme_fid_to_name(uint8_t fid)
1618 {
1619 const char *name;
1620
1621 switch (fid) {
1622 case NVME_FEAT_ARBITRATION:
1623 name = "Arbitration";
1624 break;
1625 case NVME_FEAT_POWER_MANAGEMENT:
1626 name = "Power Management";
1627 break;
1628 case NVME_FEAT_LBA_RANGE_TYPE:
1629 name = "LBA Range Type";
1630 break;
1631 case NVME_FEAT_TEMPERATURE_THRESHOLD:
1632 name = "Temperature Threshold";
1633 break;
1634 case NVME_FEAT_ERROR_RECOVERY:
1635 name = "Error Recovery";
1636 break;
1637 case NVME_FEAT_VOLATILE_WRITE_CACHE:
1638 name = "Volatile Write Cache";
1639 break;
1640 case NVME_FEAT_NUMBER_OF_QUEUES:
1641 name = "Number of Queues";
1642 break;
1643 case NVME_FEAT_INTERRUPT_COALESCING:
1644 name = "Interrupt Coalescing";
1645 break;
1646 case NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION:
1647 name = "Interrupt Vector Configuration";
1648 break;
1649 case NVME_FEAT_WRITE_ATOMICITY:
1650 name = "Write Atomicity Normal";
1651 break;
1652 case NVME_FEAT_ASYNC_EVENT_CONFIGURATION:
1653 name = "Asynchronous Event Configuration";
1654 break;
1655 case NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION:
1656 name = "Autonomous Power State Transition";
1657 break;
1658 case NVME_FEAT_HOST_MEMORY_BUFFER:
1659 name = "Host Memory Buffer";
1660 break;
1661 case NVME_FEAT_TIMESTAMP:
1662 name = "Timestamp";
1663 break;
1664 case NVME_FEAT_KEEP_ALIVE_TIMER:
1665 name = "Keep Alive Timer";
1666 break;
1667 case NVME_FEAT_HOST_CONTROLLED_THERMAL_MGMT:
1668 name = "Host Controlled Thermal Management";
1669 break;
1670 case NVME_FEAT_NON_OP_POWER_STATE_CONFIG:
1671 name = "Non-Operation Power State Config";
1672 break;
1673 case NVME_FEAT_READ_RECOVERY_LEVEL_CONFIG:
1674 name = "Read Recovery Level Config";
1675 break;
1676 case NVME_FEAT_PREDICTABLE_LATENCY_MODE_CONFIG:
1677 name = "Predictable Latency Mode Config";
1678 break;
1679 case NVME_FEAT_PREDICTABLE_LATENCY_MODE_WINDOW:
1680 name = "Predictable Latency Mode Window";
1681 break;
1682 case NVME_FEAT_LBA_STATUS_INFORMATION_ATTRIBUTES:
1683 name = "LBA Status Information Report Interval";
1684 break;
1685 case NVME_FEAT_HOST_BEHAVIOR_SUPPORT:
1686 name = "Host Behavior Support";
1687 break;
1688 case NVME_FEAT_SANITIZE_CONFIG:
1689 name = "Sanitize Config";
1690 break;
1691 case NVME_FEAT_ENDURANCE_GROUP_EVENT_CONFIGURATION:
1692 name = "Endurance Group Event Configuration";
1693 break;
1694 case NVME_FEAT_SOFTWARE_PROGRESS_MARKER:
1695 name = "Software Progress Marker";
1696 break;
1697 case NVME_FEAT_HOST_IDENTIFIER:
1698 name = "Host Identifier";
1699 break;
1700 case NVME_FEAT_RESERVATION_NOTIFICATION_MASK:
1701 name = "Reservation Notification Mask";
1702 break;
1703 case NVME_FEAT_RESERVATION_PERSISTENCE:
1704 name = "Reservation Persistence";
1705 break;
1706 case NVME_FEAT_NAMESPACE_WRITE_PROTECTION_CONFIG:
1707 name = "Namespace Write Protection Config";
1708 break;
1709 default:
1710 name = "Unknown";
1711 break;
1712 }
1713
1714 return (name);
1715 }
1716
1717 static void
nvme_feature_invalid_cb(struct pci_nvme_softc * sc __unused,struct nvme_feature_obj * feat __unused,struct nvme_command * command __unused,struct nvme_completion * compl)1718 nvme_feature_invalid_cb(struct pci_nvme_softc *sc __unused,
1719 struct nvme_feature_obj *feat __unused,
1720 struct nvme_command *command __unused,
1721 struct nvme_completion *compl)
1722 {
1723 pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
1724 }
1725
1726 static void
nvme_feature_iv_config(struct pci_nvme_softc * sc,struct nvme_feature_obj * feat __unused,struct nvme_command * command,struct nvme_completion * compl)1727 nvme_feature_iv_config(struct pci_nvme_softc *sc,
1728 struct nvme_feature_obj *feat __unused,
1729 struct nvme_command *command,
1730 struct nvme_completion *compl)
1731 {
1732 uint32_t i;
1733 uint32_t cdw11 = command->cdw11;
1734 uint16_t iv;
1735 bool cd;
1736
1737 pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
1738
1739 iv = cdw11 & 0xffff;
1740 cd = cdw11 & (1 << 16);
1741
1742 if (iv > (sc->max_queues + 1)) {
1743 return;
1744 }
1745
1746 /* No Interrupt Coalescing (i.e. not Coalescing Disable) for Admin Q */
1747 if ((iv == 0) && !cd)
1748 return;
1749
1750 /* Requested Interrupt Vector must be used by a CQ */
1751 for (i = 0; i < sc->num_cqueues + 1; i++) {
1752 if (sc->compl_queues[i].intr_vec == iv) {
1753 pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS);
1754 }
1755 }
1756 }
1757
1758 #define NVME_ASYNC_EVENT_ENDURANCE_GROUP (0x4000)
1759 static void
nvme_feature_async_event(struct pci_nvme_softc * sc __unused,struct nvme_feature_obj * feat __unused,struct nvme_command * command,struct nvme_completion * compl)1760 nvme_feature_async_event(struct pci_nvme_softc *sc __unused,
1761 struct nvme_feature_obj *feat __unused,
1762 struct nvme_command *command,
1763 struct nvme_completion *compl)
1764 {
1765 if (command->cdw11 & NVME_ASYNC_EVENT_ENDURANCE_GROUP)
1766 pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
1767 }
1768
1769 #define NVME_TEMP_THRESH_OVER 0
1770 #define NVME_TEMP_THRESH_UNDER 1
1771 static void
nvme_feature_temperature(struct pci_nvme_softc * sc,struct nvme_feature_obj * feat __unused,struct nvme_command * command,struct nvme_completion * compl)1772 nvme_feature_temperature(struct pci_nvme_softc *sc,
1773 struct nvme_feature_obj *feat __unused,
1774 struct nvme_command *command,
1775 struct nvme_completion *compl)
1776 {
1777 uint16_t tmpth; /* Temperature Threshold */
1778 uint8_t tmpsel; /* Threshold Temperature Select */
1779 uint8_t thsel; /* Threshold Type Select */
1780 bool set_crit = false;
1781 bool report_crit;
1782
1783 tmpth = command->cdw11 & 0xffff;
1784 tmpsel = (command->cdw11 >> 16) & 0xf;
1785 thsel = (command->cdw11 >> 20) & 0x3;
1786
1787 DPRINTF("%s: tmpth=%#x tmpsel=%#x thsel=%#x", __func__, tmpth, tmpsel, thsel);
1788
1789 /* Check for unsupported values */
1790 if (((tmpsel != 0) && (tmpsel != 0xf)) ||
1791 (thsel > NVME_TEMP_THRESH_UNDER)) {
1792 pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
1793 return;
1794 }
1795
1796 if (((thsel == NVME_TEMP_THRESH_OVER) && (NVME_TEMPERATURE >= tmpth)) ||
1797 ((thsel == NVME_TEMP_THRESH_UNDER) && (NVME_TEMPERATURE <= tmpth)))
1798 set_crit = true;
1799
1800 pthread_mutex_lock(&sc->mtx);
1801 if (set_crit)
1802 sc->health_log.critical_warning |=
1803 NVME_CRIT_WARN_ST_TEMPERATURE;
1804 else
1805 sc->health_log.critical_warning &=
1806 ~NVME_CRIT_WARN_ST_TEMPERATURE;
1807 pthread_mutex_unlock(&sc->mtx);
1808
1809 report_crit = sc->feat[NVME_FEAT_ASYNC_EVENT_CONFIGURATION].cdw11 &
1810 NVME_CRIT_WARN_ST_TEMPERATURE;
1811
1812 if (set_crit && report_crit)
1813 pci_nvme_aen_post(sc, PCI_NVME_AE_TYPE_SMART,
1814 sc->health_log.critical_warning);
1815
1816 DPRINTF("%s: set_crit=%c critical_warning=%#x status=%#x", __func__, set_crit ? 'T':'F', sc->health_log.critical_warning, compl->status);
1817 }
1818
1819 static void
nvme_feature_num_queues(struct pci_nvme_softc * sc,struct nvme_feature_obj * feat __unused,struct nvme_command * command,struct nvme_completion * compl)1820 nvme_feature_num_queues(struct pci_nvme_softc *sc,
1821 struct nvme_feature_obj *feat __unused,
1822 struct nvme_command *command,
1823 struct nvme_completion *compl)
1824 {
1825 uint16_t nqr; /* Number of Queues Requested */
1826
1827 if (sc->num_q_is_set) {
1828 WPRINTF("%s: Number of Queues already set", __func__);
1829 pci_nvme_status_genc(&compl->status,
1830 NVME_SC_COMMAND_SEQUENCE_ERROR);
1831 return;
1832 }
1833
1834 nqr = command->cdw11 & 0xFFFF;
1835 if (nqr == 0xffff) {
1836 WPRINTF("%s: Illegal NSQR value %#x", __func__, nqr);
1837 pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
1838 return;
1839 }
1840
1841 sc->num_squeues = ONE_BASED(nqr);
1842 if (sc->num_squeues > sc->max_queues) {
1843 DPRINTF("NSQR=%u is greater than max %u", sc->num_squeues,
1844 sc->max_queues);
1845 sc->num_squeues = sc->max_queues;
1846 }
1847
1848 nqr = (command->cdw11 >> 16) & 0xFFFF;
1849 if (nqr == 0xffff) {
1850 WPRINTF("%s: Illegal NCQR value %#x", __func__, nqr);
1851 pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
1852 return;
1853 }
1854
1855 sc->num_cqueues = ONE_BASED(nqr);
1856 if (sc->num_cqueues > sc->max_queues) {
1857 DPRINTF("NCQR=%u is greater than max %u", sc->num_cqueues,
1858 sc->max_queues);
1859 sc->num_cqueues = sc->max_queues;
1860 }
1861
1862 /* Patch the command value which will be saved on callback's return */
1863 command->cdw11 = NVME_FEATURE_NUM_QUEUES(sc);
1864 compl->cdw0 = NVME_FEATURE_NUM_QUEUES(sc);
1865
1866 sc->num_q_is_set = true;
1867 }
1868
1869 static int
nvme_opc_set_features(struct pci_nvme_softc * sc,struct nvme_command * command,struct nvme_completion * compl)1870 nvme_opc_set_features(struct pci_nvme_softc *sc, struct nvme_command *command,
1871 struct nvme_completion *compl)
1872 {
1873 struct nvme_feature_obj *feat;
1874 uint32_t nsid = command->nsid;
1875 uint8_t fid = NVMEV(NVME_FEAT_SET_FID, command->cdw10);
1876 bool sv = NVMEV(NVME_FEAT_SET_SV, command->cdw10);
1877
1878 DPRINTF("%s: Feature ID 0x%x (%s)", __func__, fid, nvme_fid_to_name(fid));
1879
1880 if (fid >= NVME_FID_MAX) {
1881 DPRINTF("%s invalid feature 0x%x", __func__, fid);
1882 pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
1883 return (1);
1884 }
1885
1886 if (sv) {
1887 pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC,
1888 NVME_SC_FEATURE_NOT_SAVEABLE);
1889 return (1);
1890 }
1891
1892 feat = &sc->feat[fid];
1893
1894 if (feat->namespace_specific && (nsid == NVME_GLOBAL_NAMESPACE_TAG)) {
1895 pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
1896 return (1);
1897 }
1898
1899 if (!feat->namespace_specific &&
1900 !((nsid == 0) || (nsid == NVME_GLOBAL_NAMESPACE_TAG))) {
1901 pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC,
1902 NVME_SC_FEATURE_NOT_NS_SPECIFIC);
1903 return (1);
1904 }
1905
1906 compl->cdw0 = 0;
1907 pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS);
1908
1909 if (feat->set)
1910 feat->set(sc, feat, command, compl);
1911 else {
1912 pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC,
1913 NVME_SC_FEATURE_NOT_CHANGEABLE);
1914 return (1);
1915 }
1916
1917 DPRINTF("%s: status=%#x cdw11=%#x", __func__, compl->status, command->cdw11);
1918 if (compl->status == NVME_SC_SUCCESS) {
1919 feat->cdw11 = command->cdw11;
1920 if ((fid == NVME_FEAT_ASYNC_EVENT_CONFIGURATION) &&
1921 (command->cdw11 != 0))
1922 pci_nvme_aen_notify(sc);
1923 }
1924
1925 return (0);
1926 }
1927
1928 #define NVME_FEATURES_SEL_SUPPORTED 0x3
1929 #define NVME_FEATURES_NS_SPECIFIC (1 << 1)
1930
1931 static int
nvme_opc_get_features(struct pci_nvme_softc * sc,struct nvme_command * command,struct nvme_completion * compl)1932 nvme_opc_get_features(struct pci_nvme_softc* sc, struct nvme_command* command,
1933 struct nvme_completion* compl)
1934 {
1935 struct nvme_feature_obj *feat;
1936 uint8_t fid = command->cdw10 & 0xFF;
1937 uint8_t sel = (command->cdw10 >> 8) & 0x7;
1938
1939 DPRINTF("%s: Feature ID 0x%x (%s)", __func__, fid, nvme_fid_to_name(fid));
1940
1941 if (fid >= NVME_FID_MAX) {
1942 DPRINTF("%s invalid feature 0x%x", __func__, fid);
1943 pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
1944 return (1);
1945 }
1946
1947 compl->cdw0 = 0;
1948 pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS);
1949
1950 feat = &sc->feat[fid];
1951 if (feat->get) {
1952 feat->get(sc, feat, command, compl);
1953 }
1954
1955 if (compl->status == NVME_SC_SUCCESS) {
1956 if ((sel == NVME_FEATURES_SEL_SUPPORTED) && feat->namespace_specific)
1957 compl->cdw0 = NVME_FEATURES_NS_SPECIFIC;
1958 else
1959 compl->cdw0 = feat->cdw11;
1960 }
1961
1962 return (0);
1963 }
1964
1965 static int
nvme_opc_format_nvm(struct pci_nvme_softc * sc,struct nvme_command * command,struct nvme_completion * compl)1966 nvme_opc_format_nvm(struct pci_nvme_softc* sc, struct nvme_command* command,
1967 struct nvme_completion* compl)
1968 {
1969 uint8_t ses, lbaf, pi;
1970
1971 /* Only supports Secure Erase Setting - User Data Erase */
1972 ses = (command->cdw10 >> 9) & 0x7;
1973 if (ses > 0x1) {
1974 pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
1975 return (1);
1976 }
1977
1978 /* Only supports a single LBA Format */
1979 lbaf = command->cdw10 & 0xf;
1980 if (lbaf != 0) {
1981 pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC,
1982 NVME_SC_INVALID_FORMAT);
1983 return (1);
1984 }
1985
1986 /* Doesn't support Protection Infomation */
1987 pi = (command->cdw10 >> 5) & 0x7;
1988 if (pi != 0) {
1989 pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
1990 return (1);
1991 }
1992
1993 if (sc->nvstore.type == NVME_STOR_RAM) {
1994 if (sc->nvstore.ctx)
1995 free(sc->nvstore.ctx);
1996 sc->nvstore.ctx = calloc(1, sc->nvstore.size);
1997 pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS);
1998 } else {
1999 struct pci_nvme_ioreq *req;
2000 int err;
2001
2002 req = pci_nvme_get_ioreq(sc);
2003 if (req == NULL) {
2004 pci_nvme_status_genc(&compl->status,
2005 NVME_SC_INTERNAL_DEVICE_ERROR);
2006 WPRINTF("%s: unable to allocate IO req", __func__);
2007 return (1);
2008 }
2009 req->nvme_sq = &sc->submit_queues[0];
2010 req->sqid = 0;
2011 req->opc = command->opc;
2012 req->cid = command->cid;
2013 req->nsid = command->nsid;
2014
2015 req->io_req.br_offset = 0;
2016 req->io_req.br_resid = sc->nvstore.size;
2017 req->io_req.br_callback = pci_nvme_io_done;
2018
2019 err = blockif_delete(sc->nvstore.ctx, &req->io_req);
2020 if (err) {
2021 pci_nvme_status_genc(&compl->status,
2022 NVME_SC_INTERNAL_DEVICE_ERROR);
2023 pci_nvme_release_ioreq(sc, req);
2024 } else
2025 compl->status = NVME_NO_STATUS;
2026 }
2027
2028 return (1);
2029 }
2030
2031 static int
nvme_opc_abort(struct pci_nvme_softc * sc __unused,struct nvme_command * command,struct nvme_completion * compl)2032 nvme_opc_abort(struct pci_nvme_softc *sc __unused, struct nvme_command *command,
2033 struct nvme_completion *compl)
2034 {
2035 DPRINTF("%s submission queue %u, command ID 0x%x", __func__,
2036 command->cdw10 & 0xFFFF, (command->cdw10 >> 16) & 0xFFFF);
2037
2038 /* TODO: search for the command ID and abort it */
2039
2040 compl->cdw0 = 1;
2041 pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS);
2042 return (1);
2043 }
2044
2045 static int
nvme_opc_async_event_req(struct pci_nvme_softc * sc,struct nvme_command * command,struct nvme_completion * compl)2046 nvme_opc_async_event_req(struct pci_nvme_softc* sc,
2047 struct nvme_command* command, struct nvme_completion* compl)
2048 {
2049 DPRINTF("%s async event request count=%u aerl=%u cid=%#x", __func__,
2050 sc->aer_count, sc->ctrldata.aerl, command->cid);
2051
2052 /* Don't exceed the Async Event Request Limit (AERL). */
2053 if (pci_nvme_aer_limit_reached(sc)) {
2054 pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC,
2055 NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED);
2056 return (1);
2057 }
2058
2059 if (pci_nvme_aer_add(sc, command->cid)) {
2060 pci_nvme_status_tc(&compl->status, NVME_SCT_GENERIC,
2061 NVME_SC_INTERNAL_DEVICE_ERROR);
2062 return (1);
2063 }
2064
2065 /*
2066 * Raise events when they happen based on the Set Features cmd.
2067 * These events happen async, so only set completion successful if
2068 * there is an event reflective of the request to get event.
2069 */
2070 compl->status = NVME_NO_STATUS;
2071 pci_nvme_aen_notify(sc);
2072
2073 return (0);
2074 }
2075
2076 static void
pci_nvme_handle_admin_cmd(struct pci_nvme_softc * sc,uint64_t value)2077 pci_nvme_handle_admin_cmd(struct pci_nvme_softc* sc, uint64_t value)
2078 {
2079 struct nvme_completion compl;
2080 struct nvme_command *cmd;
2081 struct nvme_submission_queue *sq;
2082 struct nvme_completion_queue *cq;
2083 uint16_t sqhead;
2084
2085 DPRINTF("%s index %u", __func__, (uint32_t)value);
2086
2087 sq = &sc->submit_queues[0];
2088 cq = &sc->compl_queues[0];
2089
2090 pthread_mutex_lock(&sq->mtx);
2091
2092 sqhead = sq->head;
2093 DPRINTF("sqhead %u, tail %u", sqhead, sq->tail);
2094
2095 while (sqhead != atomic_load_acq_short(&sq->tail)) {
2096 cmd = &(sq->qbase)[sqhead];
2097 compl.cdw0 = 0;
2098 compl.status = 0;
2099
2100 switch (cmd->opc) {
2101 case NVME_OPC_DELETE_IO_SQ:
2102 DPRINTF("%s command DELETE_IO_SQ", __func__);
2103 nvme_opc_delete_io_sq(sc, cmd, &compl);
2104 break;
2105 case NVME_OPC_CREATE_IO_SQ:
2106 DPRINTF("%s command CREATE_IO_SQ", __func__);
2107 nvme_opc_create_io_sq(sc, cmd, &compl);
2108 break;
2109 case NVME_OPC_DELETE_IO_CQ:
2110 DPRINTF("%s command DELETE_IO_CQ", __func__);
2111 nvme_opc_delete_io_cq(sc, cmd, &compl);
2112 break;
2113 case NVME_OPC_CREATE_IO_CQ:
2114 DPRINTF("%s command CREATE_IO_CQ", __func__);
2115 nvme_opc_create_io_cq(sc, cmd, &compl);
2116 break;
2117 case NVME_OPC_GET_LOG_PAGE:
2118 DPRINTF("%s command GET_LOG_PAGE", __func__);
2119 nvme_opc_get_log_page(sc, cmd, &compl);
2120 break;
2121 case NVME_OPC_IDENTIFY:
2122 DPRINTF("%s command IDENTIFY", __func__);
2123 nvme_opc_identify(sc, cmd, &compl);
2124 break;
2125 case NVME_OPC_ABORT:
2126 DPRINTF("%s command ABORT", __func__);
2127 nvme_opc_abort(sc, cmd, &compl);
2128 break;
2129 case NVME_OPC_SET_FEATURES:
2130 DPRINTF("%s command SET_FEATURES", __func__);
2131 nvme_opc_set_features(sc, cmd, &compl);
2132 break;
2133 case NVME_OPC_GET_FEATURES:
2134 DPRINTF("%s command GET_FEATURES", __func__);
2135 nvme_opc_get_features(sc, cmd, &compl);
2136 break;
2137 case NVME_OPC_FIRMWARE_ACTIVATE:
2138 DPRINTF("%s command FIRMWARE_ACTIVATE", __func__);
2139 pci_nvme_status_tc(&compl.status,
2140 NVME_SCT_COMMAND_SPECIFIC,
2141 NVME_SC_INVALID_FIRMWARE_SLOT);
2142 break;
2143 case NVME_OPC_ASYNC_EVENT_REQUEST:
2144 DPRINTF("%s command ASYNC_EVENT_REQ", __func__);
2145 nvme_opc_async_event_req(sc, cmd, &compl);
2146 break;
2147 case NVME_OPC_FORMAT_NVM:
2148 DPRINTF("%s command FORMAT_NVM", __func__);
2149 if ((sc->ctrldata.oacs &
2150 (1 << NVME_CTRLR_DATA_OACS_FORMAT_SHIFT)) == 0) {
2151 pci_nvme_status_genc(&compl.status, NVME_SC_INVALID_OPCODE);
2152 break;
2153 }
2154 nvme_opc_format_nvm(sc, cmd, &compl);
2155 break;
2156 case NVME_OPC_SECURITY_SEND:
2157 case NVME_OPC_SECURITY_RECEIVE:
2158 case NVME_OPC_SANITIZE:
2159 case NVME_OPC_GET_LBA_STATUS:
2160 DPRINTF("%s command OPC=%#x (unsupported)", __func__,
2161 cmd->opc);
2162 /* Valid but unsupported opcodes */
2163 pci_nvme_status_genc(&compl.status, NVME_SC_INVALID_FIELD);
2164 break;
2165 default:
2166 DPRINTF("%s command OPC=%#X (not implemented)",
2167 __func__,
2168 cmd->opc);
2169 pci_nvme_status_genc(&compl.status, NVME_SC_INVALID_OPCODE);
2170 }
2171 sqhead = (sqhead + 1) % sq->size;
2172
2173 if (NVME_COMPLETION_VALID(compl)) {
2174 pci_nvme_cq_update(sc, &sc->compl_queues[0],
2175 compl.cdw0,
2176 cmd->cid,
2177 0, /* SQID */
2178 compl.status);
2179 }
2180 }
2181
2182 DPRINTF("setting sqhead %u", sqhead);
2183 sq->head = sqhead;
2184
2185 if (cq->head != cq->tail)
2186 pci_generate_msix(sc->nsc_pi, 0);
2187
2188 pthread_mutex_unlock(&sq->mtx);
2189 }
2190
2191 /*
2192 * Update the Write and Read statistics reported in SMART data
2193 *
2194 * NVMe defines "data unit" as thousand's of 512 byte blocks and is rounded up.
2195 * E.g. 1 data unit is 1 - 1,000 512 byte blocks. 3 data units are 2,001 - 3,000
2196 * 512 byte blocks. Rounding up is acheived by initializing the remainder to 999.
2197 */
2198 static void
pci_nvme_stats_write_read_update(struct pci_nvme_softc * sc,uint8_t opc,size_t bytes,uint16_t status)2199 pci_nvme_stats_write_read_update(struct pci_nvme_softc *sc, uint8_t opc,
2200 size_t bytes, uint16_t status)
2201 {
2202
2203 pthread_mutex_lock(&sc->mtx);
2204 switch (opc) {
2205 case NVME_OPC_WRITE:
2206 sc->write_commands++;
2207 if (status != NVME_SC_SUCCESS)
2208 break;
2209 sc->write_dunits_remainder += (bytes / 512);
2210 while (sc->write_dunits_remainder >= 1000) {
2211 sc->write_data_units++;
2212 sc->write_dunits_remainder -= 1000;
2213 }
2214 break;
2215 case NVME_OPC_READ:
2216 sc->read_commands++;
2217 if (status != NVME_SC_SUCCESS)
2218 break;
2219 sc->read_dunits_remainder += (bytes / 512);
2220 while (sc->read_dunits_remainder >= 1000) {
2221 sc->read_data_units++;
2222 sc->read_dunits_remainder -= 1000;
2223 }
2224 break;
2225 default:
2226 DPRINTF("%s: Invalid OPC 0x%02x for stats", __func__, opc);
2227 break;
2228 }
2229 pthread_mutex_unlock(&sc->mtx);
2230 }
2231
2232 /*
2233 * Check if the combination of Starting LBA (slba) and number of blocks
2234 * exceeds the range of the underlying storage.
2235 *
2236 * Because NVMe specifies the SLBA in blocks as a uint64_t and blockif stores
2237 * the capacity in bytes as a uint64_t, care must be taken to avoid integer
2238 * overflow.
2239 */
2240 static bool
pci_nvme_out_of_range(struct pci_nvme_blockstore * nvstore,uint64_t slba,uint32_t nblocks)2241 pci_nvme_out_of_range(struct pci_nvme_blockstore *nvstore, uint64_t slba,
2242 uint32_t nblocks)
2243 {
2244 size_t offset, bytes;
2245
2246 /* Overflow check of multiplying Starting LBA by the sector size */
2247 if (slba >> (64 - nvstore->sectsz_bits))
2248 return (true);
2249
2250 offset = slba << nvstore->sectsz_bits;
2251 bytes = nblocks << nvstore->sectsz_bits;
2252
2253 /* Overflow check of Number of Logical Blocks */
2254 if ((nvstore->size <= offset) || ((nvstore->size - offset) < bytes))
2255 return (true);
2256
2257 return (false);
2258 }
2259
2260 static int
pci_nvme_append_iov_req(struct pci_nvme_softc * sc __unused,struct pci_nvme_ioreq * req,uint64_t gpaddr,size_t size,uint64_t offset)2261 pci_nvme_append_iov_req(struct pci_nvme_softc *sc __unused,
2262 struct pci_nvme_ioreq *req, uint64_t gpaddr, size_t size, uint64_t offset)
2263 {
2264 int iovidx;
2265 bool range_is_contiguous;
2266
2267 if (req == NULL)
2268 return (-1);
2269
2270 if (req->io_req.br_iovcnt == NVME_MAX_IOVEC) {
2271 return (-1);
2272 }
2273
2274 /*
2275 * Minimize the number of IOVs by concatenating contiguous address
2276 * ranges. If the IOV count is zero, there is no previous range to
2277 * concatenate.
2278 */
2279 if (req->io_req.br_iovcnt == 0)
2280 range_is_contiguous = false;
2281 else
2282 range_is_contiguous = (req->prev_gpaddr + req->prev_size) == gpaddr;
2283
2284 if (range_is_contiguous) {
2285 iovidx = req->io_req.br_iovcnt - 1;
2286
2287 req->io_req.br_iov[iovidx].iov_base =
2288 paddr_guest2host(req->sc->nsc_pi->pi_vmctx,
2289 req->prev_gpaddr, size);
2290 if (req->io_req.br_iov[iovidx].iov_base == NULL)
2291 return (-1);
2292
2293 req->prev_size += size;
2294 req->io_req.br_resid += size;
2295
2296 req->io_req.br_iov[iovidx].iov_len = req->prev_size;
2297 } else {
2298 iovidx = req->io_req.br_iovcnt;
2299 if (iovidx == 0) {
2300 req->io_req.br_offset = offset;
2301 req->io_req.br_resid = 0;
2302 req->io_req.br_param = req;
2303 }
2304
2305 req->io_req.br_iov[iovidx].iov_base =
2306 paddr_guest2host(req->sc->nsc_pi->pi_vmctx,
2307 gpaddr, size);
2308 if (req->io_req.br_iov[iovidx].iov_base == NULL)
2309 return (-1);
2310
2311 req->io_req.br_iov[iovidx].iov_len = size;
2312
2313 req->prev_gpaddr = gpaddr;
2314 req->prev_size = size;
2315 req->io_req.br_resid += size;
2316
2317 req->io_req.br_iovcnt++;
2318 }
2319
2320 return (0);
2321 }
2322
2323 static void
pci_nvme_set_completion(struct pci_nvme_softc * sc,struct nvme_submission_queue * sq,int sqid,uint16_t cid,uint16_t status)2324 pci_nvme_set_completion(struct pci_nvme_softc *sc,
2325 struct nvme_submission_queue *sq, int sqid, uint16_t cid, uint16_t status)
2326 {
2327 struct nvme_completion_queue *cq = &sc->compl_queues[sq->cqid];
2328
2329 DPRINTF("%s sqid %d cqid %u cid %u status: 0x%x 0x%x",
2330 __func__, sqid, sq->cqid, cid, NVME_STATUS_GET_SCT(status),
2331 NVME_STATUS_GET_SC(status));
2332
2333 pci_nvme_cq_update(sc, cq, 0, cid, sqid, status);
2334
2335 if (cq->head != cq->tail) {
2336 if (cq->intr_en & NVME_CQ_INTEN) {
2337 pci_generate_msix(sc->nsc_pi, cq->intr_vec);
2338 } else {
2339 DPRINTF("%s: CQ%u interrupt disabled",
2340 __func__, sq->cqid);
2341 }
2342 }
2343 }
2344
2345 static void
pci_nvme_release_ioreq(struct pci_nvme_softc * sc,struct pci_nvme_ioreq * req)2346 pci_nvme_release_ioreq(struct pci_nvme_softc *sc, struct pci_nvme_ioreq *req)
2347 {
2348 req->sc = NULL;
2349 req->nvme_sq = NULL;
2350 req->sqid = 0;
2351
2352 pthread_mutex_lock(&sc->mtx);
2353
2354 STAILQ_INSERT_TAIL(&sc->ioreqs_free, req, link);
2355 sc->pending_ios--;
2356
2357 /* when no more IO pending, can set to ready if device reset/enabled */
2358 if (sc->pending_ios == 0 &&
2359 NVME_CC_GET_EN(sc->regs.cc) && !(NVME_CSTS_GET_RDY(sc->regs.csts)))
2360 sc->regs.csts |= NVME_CSTS_RDY;
2361
2362 pthread_mutex_unlock(&sc->mtx);
2363
2364 sem_post(&sc->iosemlock);
2365 }
2366
2367 static struct pci_nvme_ioreq *
pci_nvme_get_ioreq(struct pci_nvme_softc * sc)2368 pci_nvme_get_ioreq(struct pci_nvme_softc *sc)
2369 {
2370 struct pci_nvme_ioreq *req = NULL;
2371
2372 sem_wait(&sc->iosemlock);
2373 pthread_mutex_lock(&sc->mtx);
2374
2375 req = STAILQ_FIRST(&sc->ioreqs_free);
2376 assert(req != NULL);
2377 STAILQ_REMOVE_HEAD(&sc->ioreqs_free, link);
2378
2379 req->sc = sc;
2380
2381 sc->pending_ios++;
2382
2383 pthread_mutex_unlock(&sc->mtx);
2384
2385 req->io_req.br_iovcnt = 0;
2386 req->io_req.br_offset = 0;
2387 req->io_req.br_resid = 0;
2388 req->io_req.br_param = req;
2389 req->prev_gpaddr = 0;
2390 req->prev_size = 0;
2391
2392 return req;
2393 }
2394
2395 static void
pci_nvme_io_done(struct blockif_req * br,int err)2396 pci_nvme_io_done(struct blockif_req *br, int err)
2397 {
2398 struct pci_nvme_ioreq *req = br->br_param;
2399 struct nvme_submission_queue *sq = req->nvme_sq;
2400 uint16_t code, status;
2401
2402 DPRINTF("%s error %d %s", __func__, err, strerror(err));
2403
2404 /* TODO return correct error */
2405 code = err ? NVME_SC_DATA_TRANSFER_ERROR : NVME_SC_SUCCESS;
2406 status = 0;
2407 pci_nvme_status_genc(&status, code);
2408
2409 pci_nvme_set_completion(req->sc, sq, req->sqid, req->cid, status);
2410 pci_nvme_stats_write_read_update(req->sc, req->opc,
2411 req->bytes, status);
2412 pci_nvme_release_ioreq(req->sc, req);
2413 }
2414
2415 /*
2416 * Implements the Flush command. The specification states:
2417 * If a volatile write cache is not present, Flush commands complete
2418 * successfully and have no effect
2419 * in the description of the Volatile Write Cache (VWC) field of the Identify
2420 * Controller data. Therefore, set status to Success if the command is
2421 * not supported (i.e. RAM or as indicated by the blockif).
2422 */
2423 static bool
nvme_opc_flush(struct pci_nvme_softc * sc __unused,struct nvme_command * cmd __unused,struct pci_nvme_blockstore * nvstore,struct pci_nvme_ioreq * req,uint16_t * status)2424 nvme_opc_flush(struct pci_nvme_softc *sc __unused,
2425 struct nvme_command *cmd __unused,
2426 struct pci_nvme_blockstore *nvstore,
2427 struct pci_nvme_ioreq *req,
2428 uint16_t *status)
2429 {
2430 bool pending = false;
2431
2432 if (nvstore->type == NVME_STOR_RAM) {
2433 pci_nvme_status_genc(status, NVME_SC_SUCCESS);
2434 } else {
2435 int err;
2436
2437 req->io_req.br_callback = pci_nvme_io_done;
2438
2439 err = blockif_flush(nvstore->ctx, &req->io_req);
2440 switch (err) {
2441 case 0:
2442 pending = true;
2443 break;
2444 case EOPNOTSUPP:
2445 pci_nvme_status_genc(status, NVME_SC_SUCCESS);
2446 break;
2447 default:
2448 pci_nvme_status_genc(status, NVME_SC_INTERNAL_DEVICE_ERROR);
2449 }
2450 }
2451
2452 return (pending);
2453 }
2454
2455 static uint16_t
nvme_write_read_ram(struct pci_nvme_softc * sc,struct pci_nvme_blockstore * nvstore,uint64_t prp1,uint64_t prp2,size_t offset,uint64_t bytes,bool is_write)2456 nvme_write_read_ram(struct pci_nvme_softc *sc,
2457 struct pci_nvme_blockstore *nvstore,
2458 uint64_t prp1, uint64_t prp2,
2459 size_t offset, uint64_t bytes,
2460 bool is_write)
2461 {
2462 uint8_t *buf = nvstore->ctx;
2463 enum nvme_copy_dir dir;
2464 uint16_t status;
2465
2466 if (is_write)
2467 dir = NVME_COPY_TO_PRP;
2468 else
2469 dir = NVME_COPY_FROM_PRP;
2470
2471 status = 0;
2472 if (nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, prp1, prp2,
2473 buf + offset, bytes, dir))
2474 pci_nvme_status_genc(&status,
2475 NVME_SC_DATA_TRANSFER_ERROR);
2476 else
2477 pci_nvme_status_genc(&status, NVME_SC_SUCCESS);
2478
2479 return (status);
2480 }
2481
2482 static uint16_t
nvme_write_read_blockif(struct pci_nvme_softc * sc,struct pci_nvme_blockstore * nvstore,struct pci_nvme_ioreq * req,uint64_t prp1,uint64_t prp2,size_t offset,uint64_t bytes,bool is_write)2483 nvme_write_read_blockif(struct pci_nvme_softc *sc,
2484 struct pci_nvme_blockstore *nvstore,
2485 struct pci_nvme_ioreq *req,
2486 uint64_t prp1, uint64_t prp2,
2487 size_t offset, uint64_t bytes,
2488 bool is_write)
2489 {
2490 uint64_t size;
2491 int err;
2492 uint16_t status = NVME_NO_STATUS;
2493
2494 size = MIN(PAGE_SIZE - (prp1 % PAGE_SIZE), bytes);
2495 if (pci_nvme_append_iov_req(sc, req, prp1, size, offset)) {
2496 err = -1;
2497 goto out;
2498 }
2499
2500 offset += size;
2501 bytes -= size;
2502
2503 if (bytes == 0) {
2504 ;
2505 } else if (bytes <= PAGE_SIZE) {
2506 size = bytes;
2507 if (pci_nvme_append_iov_req(sc, req, prp2, size, offset)) {
2508 err = -1;
2509 goto out;
2510 }
2511 } else {
2512 void *vmctx = sc->nsc_pi->pi_vmctx;
2513 uint64_t *prp_list = &prp2;
2514 uint64_t *last = prp_list;
2515
2516 /* PRP2 is pointer to a physical region page list */
2517 while (bytes) {
2518 /* Last entry in list points to the next list */
2519 if ((prp_list == last) && (bytes > PAGE_SIZE)) {
2520 uint64_t prp = *prp_list;
2521
2522 prp_list = paddr_guest2host(vmctx, prp,
2523 PAGE_SIZE - (prp % PAGE_SIZE));
2524 if (prp_list == NULL) {
2525 err = -1;
2526 goto out;
2527 }
2528 last = prp_list + (NVME_PRP2_ITEMS - 1);
2529 }
2530
2531 size = MIN(bytes, PAGE_SIZE);
2532
2533 if (pci_nvme_append_iov_req(sc, req, *prp_list, size,
2534 offset)) {
2535 err = -1;
2536 goto out;
2537 }
2538
2539 offset += size;
2540 bytes -= size;
2541
2542 prp_list++;
2543 }
2544 }
2545 req->io_req.br_callback = pci_nvme_io_done;
2546 if (is_write)
2547 err = blockif_write(nvstore->ctx, &req->io_req);
2548 else
2549 err = blockif_read(nvstore->ctx, &req->io_req);
2550 out:
2551 if (err)
2552 pci_nvme_status_genc(&status, NVME_SC_DATA_TRANSFER_ERROR);
2553
2554 return (status);
2555 }
2556
2557 static bool
nvme_opc_write_read(struct pci_nvme_softc * sc,struct nvme_command * cmd,struct pci_nvme_blockstore * nvstore,struct pci_nvme_ioreq * req,uint16_t * status)2558 nvme_opc_write_read(struct pci_nvme_softc *sc,
2559 struct nvme_command *cmd,
2560 struct pci_nvme_blockstore *nvstore,
2561 struct pci_nvme_ioreq *req,
2562 uint16_t *status)
2563 {
2564 uint64_t lba, nblocks, bytes;
2565 size_t offset;
2566 bool is_write = cmd->opc == NVME_OPC_WRITE;
2567 bool pending = false;
2568
2569 lba = ((uint64_t)cmd->cdw11 << 32) | cmd->cdw10;
2570 nblocks = (cmd->cdw12 & 0xFFFF) + 1;
2571 bytes = nblocks << nvstore->sectsz_bits;
2572 if (bytes > NVME_MAX_DATA_SIZE) {
2573 WPRINTF("%s command would exceed MDTS", __func__);
2574 pci_nvme_status_genc(status, NVME_SC_INVALID_FIELD);
2575 goto out;
2576 }
2577
2578 if (pci_nvme_out_of_range(nvstore, lba, nblocks)) {
2579 WPRINTF("%s command would exceed LBA range(slba=%#lx nblocks=%#lx)",
2580 __func__, lba, nblocks);
2581 pci_nvme_status_genc(status, NVME_SC_LBA_OUT_OF_RANGE);
2582 goto out;
2583 }
2584
2585 offset = lba << nvstore->sectsz_bits;
2586
2587 req->bytes = bytes;
2588 req->io_req.br_offset = lba;
2589
2590 /* PRP bits 1:0 must be zero */
2591 cmd->prp1 &= ~0x3UL;
2592 cmd->prp2 &= ~0x3UL;
2593
2594 if (nvstore->type == NVME_STOR_RAM) {
2595 *status = nvme_write_read_ram(sc, nvstore, cmd->prp1,
2596 cmd->prp2, offset, bytes, is_write);
2597 } else {
2598 *status = nvme_write_read_blockif(sc, nvstore, req,
2599 cmd->prp1, cmd->prp2, offset, bytes, is_write);
2600
2601 if (*status == NVME_NO_STATUS)
2602 pending = true;
2603 }
2604 out:
2605 if (!pending)
2606 pci_nvme_stats_write_read_update(sc, cmd->opc, bytes, *status);
2607
2608 return (pending);
2609 }
2610
2611 static void
pci_nvme_dealloc_sm(struct blockif_req * br,int err)2612 pci_nvme_dealloc_sm(struct blockif_req *br, int err)
2613 {
2614 struct pci_nvme_ioreq *req = br->br_param;
2615 struct pci_nvme_softc *sc = req->sc;
2616 bool done = true;
2617 uint16_t status;
2618
2619 status = 0;
2620 if (err) {
2621 pci_nvme_status_genc(&status, NVME_SC_INTERNAL_DEVICE_ERROR);
2622 } else if ((req->prev_gpaddr + 1) == (req->prev_size)) {
2623 pci_nvme_status_genc(&status, NVME_SC_SUCCESS);
2624 } else {
2625 struct iovec *iov = req->io_req.br_iov;
2626
2627 req->prev_gpaddr++;
2628 iov += req->prev_gpaddr;
2629
2630 /* The iov_* values already include the sector size */
2631 req->io_req.br_offset = (off_t)iov->iov_base;
2632 req->io_req.br_resid = iov->iov_len;
2633 if (blockif_delete(sc->nvstore.ctx, &req->io_req)) {
2634 pci_nvme_status_genc(&status,
2635 NVME_SC_INTERNAL_DEVICE_ERROR);
2636 } else
2637 done = false;
2638 }
2639
2640 if (done) {
2641 pci_nvme_set_completion(sc, req->nvme_sq, req->sqid, req->cid,
2642 status);
2643 pci_nvme_release_ioreq(sc, req);
2644 }
2645 }
2646
2647 static bool
nvme_opc_dataset_mgmt(struct pci_nvme_softc * sc,struct nvme_command * cmd,struct pci_nvme_blockstore * nvstore,struct pci_nvme_ioreq * req,uint16_t * status)2648 nvme_opc_dataset_mgmt(struct pci_nvme_softc *sc,
2649 struct nvme_command *cmd,
2650 struct pci_nvme_blockstore *nvstore,
2651 struct pci_nvme_ioreq *req,
2652 uint16_t *status)
2653 {
2654 struct nvme_dsm_range *range = NULL;
2655 uint32_t nr, r, non_zero, dr;
2656 int err;
2657 bool pending = false;
2658
2659 if ((sc->ctrldata.oncs & NVME_ONCS_DSM) == 0) {
2660 pci_nvme_status_genc(status, NVME_SC_INVALID_OPCODE);
2661 goto out;
2662 }
2663
2664 nr = cmd->cdw10 & 0xff;
2665
2666 /* copy locally because a range entry could straddle PRPs */
2667 range = calloc(1, NVME_MAX_DSM_TRIM);
2668 if (range == NULL) {
2669 pci_nvme_status_genc(status, NVME_SC_INTERNAL_DEVICE_ERROR);
2670 goto out;
2671 }
2672 nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, cmd->prp1, cmd->prp2,
2673 (uint8_t *)range, NVME_MAX_DSM_TRIM, NVME_COPY_FROM_PRP);
2674
2675 /* Check for invalid ranges and the number of non-zero lengths */
2676 non_zero = 0;
2677 for (r = 0; r <= nr; r++) {
2678 if (pci_nvme_out_of_range(nvstore,
2679 range[r].starting_lba, range[r].length)) {
2680 pci_nvme_status_genc(status, NVME_SC_LBA_OUT_OF_RANGE);
2681 goto out;
2682 }
2683 if (range[r].length != 0)
2684 non_zero++;
2685 }
2686
2687 if (cmd->cdw11 & NVME_DSM_ATTR_DEALLOCATE) {
2688 size_t offset, bytes;
2689 int sectsz_bits = sc->nvstore.sectsz_bits;
2690
2691 /*
2692 * DSM calls are advisory only, and compliant controllers
2693 * may choose to take no actions (i.e. return Success).
2694 */
2695 if (!nvstore->deallocate) {
2696 pci_nvme_status_genc(status, NVME_SC_SUCCESS);
2697 goto out;
2698 }
2699
2700 /* If all ranges have a zero length, return Success */
2701 if (non_zero == 0) {
2702 pci_nvme_status_genc(status, NVME_SC_SUCCESS);
2703 goto out;
2704 }
2705
2706 if (req == NULL) {
2707 pci_nvme_status_genc(status, NVME_SC_INTERNAL_DEVICE_ERROR);
2708 goto out;
2709 }
2710
2711 offset = range[0].starting_lba << sectsz_bits;
2712 bytes = range[0].length << sectsz_bits;
2713
2714 /*
2715 * If the request is for more than a single range, store
2716 * the ranges in the br_iov. Optimize for the common case
2717 * of a single range.
2718 *
2719 * Note that NVMe Number of Ranges is a zero based value
2720 */
2721 req->io_req.br_iovcnt = 0;
2722 req->io_req.br_offset = offset;
2723 req->io_req.br_resid = bytes;
2724
2725 if (nr == 0) {
2726 req->io_req.br_callback = pci_nvme_io_done;
2727 } else {
2728 struct iovec *iov = req->io_req.br_iov;
2729
2730 for (r = 0, dr = 0; r <= nr; r++) {
2731 offset = range[r].starting_lba << sectsz_bits;
2732 bytes = range[r].length << sectsz_bits;
2733 if (bytes == 0)
2734 continue;
2735
2736 if ((nvstore->size - offset) < bytes) {
2737 pci_nvme_status_genc(status,
2738 NVME_SC_LBA_OUT_OF_RANGE);
2739 goto out;
2740 }
2741 iov[dr].iov_base = (void *)offset;
2742 iov[dr].iov_len = bytes;
2743 dr++;
2744 }
2745 req->io_req.br_callback = pci_nvme_dealloc_sm;
2746
2747 /*
2748 * Use prev_gpaddr to track the current entry and
2749 * prev_size to track the number of entries
2750 */
2751 req->prev_gpaddr = 0;
2752 req->prev_size = dr;
2753 }
2754
2755 err = blockif_delete(nvstore->ctx, &req->io_req);
2756 if (err)
2757 pci_nvme_status_genc(status, NVME_SC_INTERNAL_DEVICE_ERROR);
2758 else
2759 pending = true;
2760 }
2761 out:
2762 free(range);
2763 return (pending);
2764 }
2765
2766 static void
pci_nvme_handle_io_cmd(struct pci_nvme_softc * sc,uint16_t idx)2767 pci_nvme_handle_io_cmd(struct pci_nvme_softc* sc, uint16_t idx)
2768 {
2769 struct nvme_submission_queue *sq;
2770 uint16_t status;
2771 uint16_t sqhead;
2772
2773 /* handle all submissions up to sq->tail index */
2774 sq = &sc->submit_queues[idx];
2775
2776 pthread_mutex_lock(&sq->mtx);
2777
2778 sqhead = sq->head;
2779 DPRINTF("nvme_handle_io qid %u head %u tail %u cmdlist %p",
2780 idx, sqhead, sq->tail, sq->qbase);
2781
2782 while (sqhead != atomic_load_acq_short(&sq->tail)) {
2783 struct nvme_command *cmd;
2784 struct pci_nvme_ioreq *req;
2785 uint32_t nsid;
2786 bool pending;
2787
2788 pending = false;
2789 req = NULL;
2790 status = 0;
2791
2792 cmd = &sq->qbase[sqhead];
2793 sqhead = (sqhead + 1) % sq->size;
2794
2795 nsid = le32toh(cmd->nsid);
2796 if ((nsid == 0) || (nsid > sc->ctrldata.nn)) {
2797 pci_nvme_status_genc(&status,
2798 NVME_SC_INVALID_NAMESPACE_OR_FORMAT);
2799 status |=
2800 NVME_STATUS_DNR_MASK << NVME_STATUS_DNR_SHIFT;
2801 goto complete;
2802 }
2803
2804 req = pci_nvme_get_ioreq(sc);
2805 if (req == NULL) {
2806 pci_nvme_status_genc(&status,
2807 NVME_SC_INTERNAL_DEVICE_ERROR);
2808 WPRINTF("%s: unable to allocate IO req", __func__);
2809 goto complete;
2810 }
2811 req->nvme_sq = sq;
2812 req->sqid = idx;
2813 req->opc = cmd->opc;
2814 req->cid = cmd->cid;
2815 req->nsid = cmd->nsid;
2816
2817 switch (cmd->opc) {
2818 case NVME_OPC_FLUSH:
2819 pending = nvme_opc_flush(sc, cmd, &sc->nvstore,
2820 req, &status);
2821 break;
2822 case NVME_OPC_WRITE:
2823 case NVME_OPC_READ:
2824 pending = nvme_opc_write_read(sc, cmd, &sc->nvstore,
2825 req, &status);
2826 break;
2827 case NVME_OPC_WRITE_ZEROES:
2828 /* TODO: write zeroes
2829 WPRINTF("%s write zeroes lba 0x%lx blocks %u",
2830 __func__, lba, cmd->cdw12 & 0xFFFF); */
2831 pci_nvme_status_genc(&status, NVME_SC_SUCCESS);
2832 break;
2833 case NVME_OPC_DATASET_MANAGEMENT:
2834 pending = nvme_opc_dataset_mgmt(sc, cmd, &sc->nvstore,
2835 req, &status);
2836 break;
2837 default:
2838 WPRINTF("%s unhandled io command 0x%x",
2839 __func__, cmd->opc);
2840 pci_nvme_status_genc(&status, NVME_SC_INVALID_OPCODE);
2841 }
2842 complete:
2843 if (!pending) {
2844 pci_nvme_set_completion(sc, sq, idx, cmd->cid, status);
2845 if (req != NULL)
2846 pci_nvme_release_ioreq(sc, req);
2847 }
2848 }
2849
2850 sq->head = sqhead;
2851
2852 pthread_mutex_unlock(&sq->mtx);
2853 }
2854
2855 /*
2856 * Check for invalid doorbell write values
2857 * See NVM Express Base Specification, revision 2.0
2858 * "Asynchronous Event Information - Error Status" for details
2859 */
2860 static bool
pci_nvme_sq_doorbell_valid(struct nvme_submission_queue * sq,uint64_t value)2861 pci_nvme_sq_doorbell_valid(struct nvme_submission_queue *sq, uint64_t value)
2862 {
2863 uint64_t capacity;
2864
2865 /*
2866 * Queue empty : head == tail
2867 * Queue full : head is one more than tail accounting for wrap
2868 * Therefore, can never have more than (size - 1) entries
2869 */
2870 if (sq->head == sq->tail)
2871 capacity = sq->size - 1;
2872 else if (sq->head > sq->tail)
2873 capacity = sq->size - (sq->head - sq->tail) - 1;
2874 else
2875 capacity = sq->tail - sq->head - 1;
2876
2877 if ((value == sq->tail) || /* same as previous */
2878 (value > capacity)) { /* exceeds queue capacity */
2879 EPRINTLN("%s: SQ size=%u head=%u tail=%u capacity=%lu value=%lu",
2880 __func__, sq->size, sq->head, sq->tail, capacity, value);
2881 return false;
2882 }
2883
2884 return true;
2885 }
2886
2887 static void
pci_nvme_handle_doorbell(struct pci_nvme_softc * sc,uint64_t idx,int is_sq,uint64_t value)2888 pci_nvme_handle_doorbell(struct pci_nvme_softc* sc,
2889 uint64_t idx, int is_sq, uint64_t value)
2890 {
2891 DPRINTF("nvme doorbell %lu, %s, val 0x%lx",
2892 idx, is_sq ? "SQ" : "CQ", value & 0xFFFF);
2893
2894 if (is_sq) {
2895 if (idx > sc->num_squeues) {
2896 WPRINTF("%s queue index %lu overflow from "
2897 "guest (max %u)",
2898 __func__, idx, sc->num_squeues);
2899 pci_nvme_aen_post(sc, PCI_NVME_AE_TYPE_ERROR,
2900 PCI_NVME_AEI_ERROR_INVALID_DB);
2901 return;
2902 }
2903
2904 if (sc->submit_queues[idx].qbase == NULL) {
2905 WPRINTF("%s write to SQ %lu before created", __func__,
2906 idx);
2907 pci_nvme_aen_post(sc, PCI_NVME_AE_TYPE_ERROR,
2908 PCI_NVME_AEI_ERROR_INVALID_DB);
2909 return;
2910 }
2911
2912 if (!pci_nvme_sq_doorbell_valid(&sc->submit_queues[idx], value)) {
2913 EPRINTLN("%s write to SQ %lu of %lu invalid", __func__,
2914 idx, value);
2915 pci_nvme_aen_post(sc, PCI_NVME_AE_TYPE_ERROR,
2916 PCI_NVME_AEI_ERROR_INVALID_DB_VALUE);
2917 return;
2918 }
2919
2920 atomic_store_short(&sc->submit_queues[idx].tail,
2921 (uint16_t)value);
2922
2923 if (idx == 0)
2924 pci_nvme_handle_admin_cmd(sc, value);
2925 else {
2926 /* submission queue; handle new entries in SQ */
2927 pci_nvme_handle_io_cmd(sc, (uint16_t)idx);
2928 }
2929 } else {
2930 if (idx > sc->num_cqueues) {
2931 WPRINTF("%s queue index %lu overflow from "
2932 "guest (max %u)",
2933 __func__, idx, sc->num_cqueues);
2934 pci_nvme_aen_post(sc, PCI_NVME_AE_TYPE_ERROR,
2935 PCI_NVME_AEI_ERROR_INVALID_DB);
2936 return;
2937 }
2938
2939 if (sc->compl_queues[idx].qbase == NULL) {
2940 WPRINTF("%s write to CQ %lu before created", __func__,
2941 idx);
2942 pci_nvme_aen_post(sc, PCI_NVME_AE_TYPE_ERROR,
2943 PCI_NVME_AEI_ERROR_INVALID_DB);
2944 return;
2945 }
2946
2947 atomic_store_short(&sc->compl_queues[idx].head,
2948 (uint16_t)value);
2949 }
2950 }
2951
2952 static void
pci_nvme_bar0_reg_dumps(const char * func,uint64_t offset,int iswrite)2953 pci_nvme_bar0_reg_dumps(const char *func, uint64_t offset, int iswrite)
2954 {
2955 const char *s = iswrite ? "WRITE" : "READ";
2956
2957 switch (offset) {
2958 case NVME_CR_CAP_LOW:
2959 DPRINTF("%s %s NVME_CR_CAP_LOW", func, s);
2960 break;
2961 case NVME_CR_CAP_HI:
2962 DPRINTF("%s %s NVME_CR_CAP_HI", func, s);
2963 break;
2964 case NVME_CR_VS:
2965 DPRINTF("%s %s NVME_CR_VS", func, s);
2966 break;
2967 case NVME_CR_INTMS:
2968 DPRINTF("%s %s NVME_CR_INTMS", func, s);
2969 break;
2970 case NVME_CR_INTMC:
2971 DPRINTF("%s %s NVME_CR_INTMC", func, s);
2972 break;
2973 case NVME_CR_CC:
2974 DPRINTF("%s %s NVME_CR_CC", func, s);
2975 break;
2976 case NVME_CR_CSTS:
2977 DPRINTF("%s %s NVME_CR_CSTS", func, s);
2978 break;
2979 case NVME_CR_NSSR:
2980 DPRINTF("%s %s NVME_CR_NSSR", func, s);
2981 break;
2982 case NVME_CR_AQA:
2983 DPRINTF("%s %s NVME_CR_AQA", func, s);
2984 break;
2985 case NVME_CR_ASQ_LOW:
2986 DPRINTF("%s %s NVME_CR_ASQ_LOW", func, s);
2987 break;
2988 case NVME_CR_ASQ_HI:
2989 DPRINTF("%s %s NVME_CR_ASQ_HI", func, s);
2990 break;
2991 case NVME_CR_ACQ_LOW:
2992 DPRINTF("%s %s NVME_CR_ACQ_LOW", func, s);
2993 break;
2994 case NVME_CR_ACQ_HI:
2995 DPRINTF("%s %s NVME_CR_ACQ_HI", func, s);
2996 break;
2997 default:
2998 DPRINTF("unknown nvme bar-0 offset 0x%lx", offset);
2999 }
3000
3001 }
3002
3003 static void
pci_nvme_write_bar_0(struct pci_nvme_softc * sc,uint64_t offset,int size,uint64_t value)3004 pci_nvme_write_bar_0(struct pci_nvme_softc *sc, uint64_t offset, int size,
3005 uint64_t value)
3006 {
3007 uint32_t ccreg;
3008
3009 if (offset >= NVME_DOORBELL_OFFSET) {
3010 uint64_t belloffset = offset - NVME_DOORBELL_OFFSET;
3011 uint64_t idx = belloffset / 8; /* door bell size = 2*int */
3012 int is_sq = (belloffset % 8) < 4;
3013
3014 if ((sc->regs.csts & NVME_CSTS_RDY) == 0) {
3015 WPRINTF("doorbell write prior to RDY (offset=%#lx)\n",
3016 offset);
3017 return;
3018 }
3019
3020 if (belloffset > ((sc->max_queues+1) * 8 - 4)) {
3021 WPRINTF("guest attempted an overflow write offset "
3022 "0x%lx, val 0x%lx in %s",
3023 offset, value, __func__);
3024 return;
3025 }
3026
3027 if (is_sq) {
3028 if (sc->submit_queues[idx].qbase == NULL)
3029 return;
3030 } else if (sc->compl_queues[idx].qbase == NULL)
3031 return;
3032
3033 pci_nvme_handle_doorbell(sc, idx, is_sq, value);
3034 return;
3035 }
3036
3037 DPRINTF("nvme-write offset 0x%lx, size %d, value 0x%lx",
3038 offset, size, value);
3039
3040 if (size != 4) {
3041 WPRINTF("guest wrote invalid size %d (offset 0x%lx, "
3042 "val 0x%lx) to bar0 in %s",
3043 size, offset, value, __func__);
3044 /* TODO: shutdown device */
3045 return;
3046 }
3047
3048 pci_nvme_bar0_reg_dumps(__func__, offset, 1);
3049
3050 pthread_mutex_lock(&sc->mtx);
3051
3052 switch (offset) {
3053 case NVME_CR_CAP_LOW:
3054 case NVME_CR_CAP_HI:
3055 /* readonly */
3056 break;
3057 case NVME_CR_VS:
3058 /* readonly */
3059 break;
3060 case NVME_CR_INTMS:
3061 /* MSI-X, so ignore */
3062 break;
3063 case NVME_CR_INTMC:
3064 /* MSI-X, so ignore */
3065 break;
3066 case NVME_CR_CC:
3067 ccreg = (uint32_t)value;
3068
3069 DPRINTF("%s NVME_CR_CC en %x css %x shn %x iosqes %u "
3070 "iocqes %u",
3071 __func__,
3072 NVME_CC_GET_EN(ccreg), NVME_CC_GET_CSS(ccreg),
3073 NVME_CC_GET_SHN(ccreg), NVME_CC_GET_IOSQES(ccreg),
3074 NVME_CC_GET_IOCQES(ccreg));
3075
3076 if (NVME_CC_GET_SHN(ccreg)) {
3077 /* perform shutdown - flush out data to backend */
3078 sc->regs.csts &= ~(NVME_CSTS_REG_SHST_MASK <<
3079 NVME_CSTS_REG_SHST_SHIFT);
3080 sc->regs.csts |= NVME_SHST_COMPLETE <<
3081 NVME_CSTS_REG_SHST_SHIFT;
3082 }
3083 if (NVME_CC_GET_EN(ccreg) != NVME_CC_GET_EN(sc->regs.cc)) {
3084 if (NVME_CC_GET_EN(ccreg) == 0)
3085 /* transition 1-> causes controller reset */
3086 pci_nvme_reset_locked(sc);
3087 else
3088 pci_nvme_init_controller(sc);
3089 }
3090
3091 /* Insert the iocqes, iosqes and en bits from the write */
3092 sc->regs.cc &= ~NVME_CC_WRITE_MASK;
3093 sc->regs.cc |= ccreg & NVME_CC_WRITE_MASK;
3094 if (NVME_CC_GET_EN(ccreg) == 0) {
3095 /* Insert the ams, mps and css bit fields */
3096 sc->regs.cc &= ~NVME_CC_NEN_WRITE_MASK;
3097 sc->regs.cc |= ccreg & NVME_CC_NEN_WRITE_MASK;
3098 sc->regs.csts &= ~NVME_CSTS_RDY;
3099 } else if ((sc->pending_ios == 0) &&
3100 !(sc->regs.csts & NVME_CSTS_CFS)) {
3101 sc->regs.csts |= NVME_CSTS_RDY;
3102 }
3103 break;
3104 case NVME_CR_CSTS:
3105 break;
3106 case NVME_CR_NSSR:
3107 /* ignore writes; don't support subsystem reset */
3108 break;
3109 case NVME_CR_AQA:
3110 sc->regs.aqa = (uint32_t)value;
3111 break;
3112 case NVME_CR_ASQ_LOW:
3113 sc->regs.asq = (sc->regs.asq & (0xFFFFFFFF00000000)) |
3114 (0xFFFFF000 & value);
3115 break;
3116 case NVME_CR_ASQ_HI:
3117 sc->regs.asq = (sc->regs.asq & (0x00000000FFFFFFFF)) |
3118 (value << 32);
3119 break;
3120 case NVME_CR_ACQ_LOW:
3121 sc->regs.acq = (sc->regs.acq & (0xFFFFFFFF00000000)) |
3122 (0xFFFFF000 & value);
3123 break;
3124 case NVME_CR_ACQ_HI:
3125 sc->regs.acq = (sc->regs.acq & (0x00000000FFFFFFFF)) |
3126 (value << 32);
3127 break;
3128 default:
3129 DPRINTF("%s unknown offset 0x%lx, value 0x%lx size %d",
3130 __func__, offset, value, size);
3131 }
3132 pthread_mutex_unlock(&sc->mtx);
3133 }
3134
3135 static void
pci_nvme_write(struct pci_devinst * pi,int baridx,uint64_t offset,int size,uint64_t value)3136 pci_nvme_write(struct pci_devinst *pi, int baridx, uint64_t offset, int size,
3137 uint64_t value)
3138 {
3139 struct pci_nvme_softc* sc = pi->pi_arg;
3140
3141 if (baridx == pci_msix_table_bar(pi) ||
3142 baridx == pci_msix_pba_bar(pi)) {
3143 DPRINTF("nvme-write baridx %d, msix: off 0x%lx, size %d, "
3144 " value 0x%lx", baridx, offset, size, value);
3145
3146 pci_emul_msix_twrite(pi, offset, size, value);
3147 return;
3148 }
3149
3150 switch (baridx) {
3151 case 0:
3152 pci_nvme_write_bar_0(sc, offset, size, value);
3153 break;
3154
3155 default:
3156 DPRINTF("%s unknown baridx %d, val 0x%lx",
3157 __func__, baridx, value);
3158 }
3159 }
3160
pci_nvme_read_bar_0(struct pci_nvme_softc * sc,uint64_t offset,int size)3161 static uint64_t pci_nvme_read_bar_0(struct pci_nvme_softc* sc,
3162 uint64_t offset, int size)
3163 {
3164 uint64_t value;
3165
3166 pci_nvme_bar0_reg_dumps(__func__, offset, 0);
3167
3168 if (offset < NVME_DOORBELL_OFFSET) {
3169 void *p = &(sc->regs);
3170 pthread_mutex_lock(&sc->mtx);
3171 memcpy(&value, (void *)((uintptr_t)p + offset), size);
3172 pthread_mutex_unlock(&sc->mtx);
3173 } else {
3174 value = 0;
3175 WPRINTF("pci_nvme: read invalid offset %ld", offset);
3176 }
3177
3178 switch (size) {
3179 case 1:
3180 value &= 0xFF;
3181 break;
3182 case 2:
3183 value &= 0xFFFF;
3184 break;
3185 case 4:
3186 value &= 0xFFFFFFFF;
3187 break;
3188 }
3189
3190 DPRINTF(" nvme-read offset 0x%lx, size %d -> value 0x%x",
3191 offset, size, (uint32_t)value);
3192
3193 return (value);
3194 }
3195
3196
3197
3198 static uint64_t
pci_nvme_read(struct pci_devinst * pi,int baridx,uint64_t offset,int size)3199 pci_nvme_read(struct pci_devinst *pi, int baridx, uint64_t offset, int size)
3200 {
3201 struct pci_nvme_softc* sc = pi->pi_arg;
3202
3203 if (baridx == pci_msix_table_bar(pi) ||
3204 baridx == pci_msix_pba_bar(pi)) {
3205 DPRINTF("nvme-read bar: %d, msix: regoff 0x%lx, size %d",
3206 baridx, offset, size);
3207
3208 return pci_emul_msix_tread(pi, offset, size);
3209 }
3210
3211 switch (baridx) {
3212 case 0:
3213 return pci_nvme_read_bar_0(sc, offset, size);
3214
3215 default:
3216 DPRINTF("unknown bar %d, 0x%lx", baridx, offset);
3217 }
3218
3219 return (0);
3220 }
3221
3222 static int
pci_nvme_parse_config(struct pci_nvme_softc * sc,nvlist_t * nvl)3223 pci_nvme_parse_config(struct pci_nvme_softc *sc, nvlist_t *nvl)
3224 {
3225 char bident[sizeof("XXX:XXX")];
3226 const char *value;
3227 uint32_t sectsz;
3228
3229 sc->max_queues = NVME_QUEUES;
3230 sc->max_qentries = NVME_MAX_QENTRIES;
3231 sc->ioslots = NVME_IOSLOTS;
3232 sc->num_squeues = sc->max_queues;
3233 sc->num_cqueues = sc->max_queues;
3234 sc->dataset_management = NVME_DATASET_MANAGEMENT_AUTO;
3235 sectsz = 0;
3236 snprintf(sc->ctrldata.sn, sizeof(sc->ctrldata.sn),
3237 "NVME-%d-%d", sc->nsc_pi->pi_slot, sc->nsc_pi->pi_func);
3238
3239 value = get_config_value_node(nvl, "maxq");
3240 if (value != NULL)
3241 sc->max_queues = atoi(value);
3242 value = get_config_value_node(nvl, "qsz");
3243 if (value != NULL) {
3244 sc->max_qentries = atoi(value);
3245 if (sc->max_qentries <= 0) {
3246 EPRINTLN("nvme: Invalid qsz option %d",
3247 sc->max_qentries);
3248 return (-1);
3249 }
3250 }
3251 value = get_config_value_node(nvl, "ioslots");
3252 if (value != NULL) {
3253 sc->ioslots = atoi(value);
3254 if (sc->ioslots <= 0) {
3255 EPRINTLN("Invalid ioslots option %d", sc->ioslots);
3256 return (-1);
3257 }
3258 }
3259 value = get_config_value_node(nvl, "sectsz");
3260 if (value != NULL)
3261 sectsz = atoi(value);
3262 value = get_config_value_node(nvl, "ser");
3263 if (value != NULL) {
3264 /*
3265 * This field indicates the Product Serial Number in
3266 * 7-bit ASCII, unused bytes should be space characters.
3267 * Ref: NVMe v1.3c.
3268 */
3269 cpywithpad((char *)sc->ctrldata.sn,
3270 sizeof(sc->ctrldata.sn), value, ' ');
3271 }
3272 value = get_config_value_node(nvl, "eui64");
3273 if (value != NULL)
3274 sc->nvstore.eui64 = htobe64(strtoull(value, NULL, 0));
3275 value = get_config_value_node(nvl, "dsm");
3276 if (value != NULL) {
3277 if (strcmp(value, "auto") == 0)
3278 sc->dataset_management = NVME_DATASET_MANAGEMENT_AUTO;
3279 else if (strcmp(value, "enable") == 0)
3280 sc->dataset_management = NVME_DATASET_MANAGEMENT_ENABLE;
3281 else if (strcmp(value, "disable") == 0)
3282 sc->dataset_management = NVME_DATASET_MANAGEMENT_DISABLE;
3283 }
3284
3285 value = get_config_value_node(nvl, "bootindex");
3286 if (value != NULL) {
3287 if (pci_emul_add_boot_device(sc->nsc_pi, atoi(value))) {
3288 EPRINTLN("Invalid bootindex %d", atoi(value));
3289 return (-1);
3290 }
3291 }
3292
3293 value = get_config_value_node(nvl, "ram");
3294 if (value != NULL) {
3295 uint64_t sz = strtoull(value, NULL, 10);
3296
3297 sc->nvstore.type = NVME_STOR_RAM;
3298 sc->nvstore.size = sz * 1024 * 1024;
3299 sc->nvstore.ctx = calloc(1, sc->nvstore.size);
3300 sc->nvstore.sectsz = 4096;
3301 sc->nvstore.sectsz_bits = 12;
3302 if (sc->nvstore.ctx == NULL) {
3303 EPRINTLN("nvme: Unable to allocate RAM");
3304 return (-1);
3305 }
3306 } else {
3307 snprintf(bident, sizeof(bident), "%u:%u",
3308 sc->nsc_pi->pi_slot, sc->nsc_pi->pi_func);
3309 sc->nvstore.ctx = blockif_open(nvl, bident);
3310 if (sc->nvstore.ctx == NULL) {
3311 EPRINTLN("nvme: Could not open backing file: %s",
3312 strerror(errno));
3313 return (-1);
3314 }
3315 sc->nvstore.type = NVME_STOR_BLOCKIF;
3316 sc->nvstore.size = blockif_size(sc->nvstore.ctx);
3317 }
3318
3319 if (sectsz == 512 || sectsz == 4096 || sectsz == 8192)
3320 sc->nvstore.sectsz = sectsz;
3321 else if (sc->nvstore.type != NVME_STOR_RAM)
3322 sc->nvstore.sectsz = blockif_sectsz(sc->nvstore.ctx);
3323 for (sc->nvstore.sectsz_bits = 9;
3324 (1U << sc->nvstore.sectsz_bits) < sc->nvstore.sectsz;
3325 sc->nvstore.sectsz_bits++);
3326
3327 if (sc->max_queues <= 0 || sc->max_queues > NVME_QUEUES)
3328 sc->max_queues = NVME_QUEUES;
3329
3330 return (0);
3331 }
3332
3333 static void
pci_nvme_resized(struct blockif_ctxt * bctxt __unused,void * arg,size_t new_size)3334 pci_nvme_resized(struct blockif_ctxt *bctxt __unused, void *arg,
3335 size_t new_size)
3336 {
3337 struct pci_nvme_softc *sc;
3338 struct pci_nvme_blockstore *nvstore;
3339 struct nvme_namespace_data *nd;
3340
3341 sc = arg;
3342 nvstore = &sc->nvstore;
3343 nd = &sc->nsdata;
3344
3345 nvstore->size = new_size;
3346 pci_nvme_init_nsdata_size(nvstore, nd);
3347
3348 /* Add changed NSID to list */
3349 sc->ns_log.ns[0] = 1;
3350 sc->ns_log.ns[1] = 0;
3351
3352 pci_nvme_aen_post(sc, PCI_NVME_AE_TYPE_NOTICE,
3353 PCI_NVME_AEI_NOTICE_NS_ATTR_CHANGED);
3354 }
3355
3356 static int
pci_nvme_init(struct pci_devinst * pi,nvlist_t * nvl)3357 pci_nvme_init(struct pci_devinst *pi, nvlist_t *nvl)
3358 {
3359 struct pci_nvme_softc *sc;
3360 uint32_t pci_membar_sz;
3361 int error;
3362
3363 error = 0;
3364
3365 sc = calloc(1, sizeof(struct pci_nvme_softc));
3366 pi->pi_arg = sc;
3367 sc->nsc_pi = pi;
3368
3369 error = pci_nvme_parse_config(sc, nvl);
3370 if (error < 0)
3371 goto done;
3372 else
3373 error = 0;
3374
3375 STAILQ_INIT(&sc->ioreqs_free);
3376 sc->ioreqs = calloc(sc->ioslots, sizeof(struct pci_nvme_ioreq));
3377 for (uint32_t i = 0; i < sc->ioslots; i++) {
3378 STAILQ_INSERT_TAIL(&sc->ioreqs_free, &sc->ioreqs[i], link);
3379 }
3380
3381 pci_set_cfgdata16(pi, PCIR_DEVICE, 0x0A0A);
3382 pci_set_cfgdata16(pi, PCIR_VENDOR, 0xFB5D);
3383 pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_STORAGE);
3384 pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_STORAGE_NVM);
3385 pci_set_cfgdata8(pi, PCIR_PROGIF,
3386 PCIP_STORAGE_NVM_ENTERPRISE_NVMHCI_1_0);
3387
3388 /*
3389 * Allocate size of NVMe registers + doorbell space for all queues.
3390 *
3391 * The specification requires a minimum memory I/O window size of 16K.
3392 * The Windows driver will refuse to start a device with a smaller
3393 * window.
3394 */
3395 pci_membar_sz = sizeof(struct nvme_registers) +
3396 2 * sizeof(uint32_t) * (sc->max_queues + 1);
3397 pci_membar_sz = MAX(pci_membar_sz, NVME_MMIO_SPACE_MIN);
3398
3399 DPRINTF("nvme membar size: %u", pci_membar_sz);
3400
3401 error = pci_emul_alloc_bar(pi, 0, PCIBAR_MEM64, pci_membar_sz);
3402 if (error) {
3403 WPRINTF("%s pci alloc mem bar failed", __func__);
3404 goto done;
3405 }
3406
3407 error = pci_emul_add_msixcap(pi, sc->max_queues + 1, NVME_MSIX_BAR);
3408 if (error) {
3409 WPRINTF("%s pci add msixcap failed", __func__);
3410 goto done;
3411 }
3412
3413 error = pci_emul_add_pciecap(pi, PCIEM_TYPE_ROOT_INT_EP);
3414 if (error) {
3415 WPRINTF("%s pci add Express capability failed", __func__);
3416 goto done;
3417 }
3418
3419 pthread_mutex_init(&sc->mtx, NULL);
3420 sem_init(&sc->iosemlock, 0, sc->ioslots);
3421 blockif_register_resize_callback(sc->nvstore.ctx, pci_nvme_resized, sc);
3422
3423 pci_nvme_init_queues(sc, sc->max_queues, sc->max_queues);
3424 /*
3425 * Controller data depends on Namespace data so initialize Namespace
3426 * data first.
3427 */
3428 pci_nvme_init_nsdata(sc, &sc->nsdata, 1, &sc->nvstore);
3429 pci_nvme_init_ctrldata(sc);
3430 pci_nvme_init_logpages(sc);
3431 pci_nvme_init_features(sc);
3432
3433 pci_nvme_aer_init(sc);
3434 pci_nvme_aen_init(sc);
3435
3436 pci_nvme_reset(sc);
3437 done:
3438 return (error);
3439 }
3440
3441 static int
pci_nvme_legacy_config(nvlist_t * nvl,const char * opts)3442 pci_nvme_legacy_config(nvlist_t *nvl, const char *opts)
3443 {
3444 char *cp, *ram;
3445
3446 if (opts == NULL)
3447 return (0);
3448
3449 if (strncmp(opts, "ram=", 4) == 0) {
3450 cp = strchr(opts, ',');
3451 if (cp == NULL) {
3452 set_config_value_node(nvl, "ram", opts + 4);
3453 return (0);
3454 }
3455 ram = strndup(opts + 4, cp - opts - 4);
3456 set_config_value_node(nvl, "ram", ram);
3457 free(ram);
3458 return (pci_parse_legacy_config(nvl, cp + 1));
3459 } else
3460 return (blockif_legacy_config(nvl, opts));
3461 }
3462
3463 static const struct pci_devemu pci_de_nvme = {
3464 .pe_emu = "nvme",
3465 .pe_init = pci_nvme_init,
3466 .pe_legacy_config = pci_nvme_legacy_config,
3467 .pe_barwrite = pci_nvme_write,
3468 .pe_barread = pci_nvme_read
3469 };
3470 PCI_EMUL_SET(pci_de_nvme);
3471