Index: usr.sbin/bhyve/pci_nvme.c =================================================================== --- usr.sbin/bhyve/pci_nvme.c +++ usr.sbin/bhyve/pci_nvme.c @@ -30,7 +30,7 @@ * bhyve PCIe-NVMe device emulation. * * options: - * -s ,nvme,devpath,maxq=#,qsz=#,ioslots=#,sectsz=#,ser=A-Z + * -s ,nvme,devpath,maxq=#,qsz=#,ioslots=#,sectsz=#,ser=A-Z,eui64=# * * accepted devpath: * /dev/blockdev @@ -42,6 +42,7 @@ * ioslots = max number of concurrent io requests * sectsz = sector size (defaults to blockif sector size) * ser = serial number (20-chars max) + * eui64 = IEEE Extended Unique Identifier (8 byte value) * */ @@ -164,6 +165,7 @@ uint64_t size; uint32_t sectsz; uint32_t sectsz_bits; + uint64_t eui64; }; struct pci_nvme_ioreq { @@ -353,11 +355,11 @@ } static void -pci_nvme_init_nsdata(struct pci_nvme_softc *sc) +pci_nvme_init_nsdata(struct pci_nvme_softc *sc, + struct nvme_namespace_data *nd, uint32_t nsid, + uint64_t eui64) { - struct nvme_namespace_data *nd; - - nd = &sc->nsdata; + uint16_t be_nsid; nd->nsze = sc->nvstore.size / sc->nvstore.sectsz; nd->ncap = nd->nsze; @@ -365,10 +367,28 @@ /* Get LBA and backstore information from backing store */ nd->nlbaf = 0; /* NLBAF is a 0's based value (i.e. 1 LBA Format) */ + + nd->flbas = 0; + + /* Create an EUI-64 if user did not provide one */ + if (eui64 != 0) + memcpy(nd->eui64, &eui64, sizeof(nd->eui64)); + else { + /* OUI followed by the PCI BDF and the Namespace ID */ + memcpy(nd->eui64, sc->ctrldata.ieee, 3); + + nd->eui64[3] = sc->nsc_pi->pi_bus; + nd->eui64[4] = sc->nsc_pi->pi_slot; + nd->eui64[5] = sc->nsc_pi->pi_func; + + assert(nsid <= UINT16_MAX); + + be_nsid = htobe16(nsid); + memcpy(nd->eui64 + 6, &be_nsid, 2); + } + /* LBA data-sz = 2^lbads */ nd->lbaf[0] = sc->nvstore.sectsz_bits << NVME_NS_DATA_LBAF_LBADS_SHIFT; - - nd->flbas = 0; } static void @@ -1816,6 +1836,8 @@ free(uopt); return (-1); } + } else if (!strcmp("eui64", xopts)) { + sc->nvstore.eui64 = htobe64(strtoull(config, NULL, 0)); } else if (optidx == 0) { snprintf(bident, sizeof(bident), "%d:%d", sc->nsc_pi->pi_slot, sc->nsc_pi->pi_func); @@ -1936,7 +1958,7 @@ pci_nvme_reset(sc); pci_nvme_init_ctrldata(sc); - pci_nvme_init_nsdata(sc); + pci_nvme_init_nsdata(sc, &sc->nsdata, 0, sc->nvstore.eui64); pci_nvme_init_logpages(sc); pci_lintr_request(pi);