git: 8f65e94045f4 - stable/13 - bhyve nvme: Implement Log Page Offset
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 21 Feb 2022 21:57:54 UTC
The branch stable/13 has been updated by chuck: URL: https://cgit.FreeBSD.org/src/commit/?id=8f65e94045f492a665523ac5b224861be9fccbf0 commit 8f65e94045f492a665523ac5b224861be9fccbf0 Author: Chuck Tuffli <chuck@FreeBSD.org> AuthorDate: 2022-01-30 07:06:46 +0000 Commit: Chuck Tuffli <chuck@FreeBSD.org> CommitDate: 2022-02-22 03:25:51 +0000 bhyve nvme: Implement Log Page Offset Modify the Get Log Page command to parse the Log Page Offset fields to support more recent versions of the NVMe specification. Fixes various tests for UNH Test 1.3.* (cherry picked from commit b1b2a4d9e87e0eec413781e4580cd14edf74af7f) --- usr.sbin/bhyve/pci_nvme.c | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/usr.sbin/bhyve/pci_nvme.c b/usr.sbin/bhyve/pci_nvme.c index e1de57c26e84..78af3077f623 100644 --- a/usr.sbin/bhyve/pci_nvme.c +++ b/usr.sbin/bhyve/pci_nvme.c @@ -1329,6 +1329,7 @@ static int nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command, struct nvme_completion* compl) { + uint64_t logoff; uint32_t logsize; uint8_t logpage = command->cdw10 & 0xFF; @@ -1342,15 +1343,28 @@ nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command, */ logsize = ((command->cdw11 << 16) | (command->cdw10 >> 16)) + 1; logsize *= sizeof(uint32_t); + logoff = ((uint64_t)(command->cdw13) << 32) | command->cdw12; switch (logpage) { case NVME_LOG_ERROR: + if (logoff >= sizeof(sc->err_log)) { + pci_nvme_status_genc(&compl->status, + NVME_SC_INVALID_FIELD); + break; + } + nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1, - command->prp2, (uint8_t *)&sc->err_log, - MIN(logsize, sizeof(sc->err_log)), + command->prp2, (uint8_t *)&sc->err_log + logoff, + MIN(logsize - logoff, sizeof(sc->err_log)), NVME_COPY_TO_PRP); break; case NVME_LOG_HEALTH_INFORMATION: + if (logoff >= sizeof(sc->health_log)) { + pci_nvme_status_genc(&compl->status, + NVME_SC_INVALID_FIELD); + break; + } + pthread_mutex_lock(&sc->mtx); memcpy(&sc->health_log.data_units_read, &sc->read_data_units, sizeof(sc->health_log.data_units_read)); @@ -1363,20 +1377,32 @@ nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command, pthread_mutex_unlock(&sc->mtx); nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1, - command->prp2, (uint8_t *)&sc->health_log, - MIN(logsize, sizeof(sc->health_log)), + command->prp2, (uint8_t *)&sc->health_log + logoff, + MIN(logsize - logoff, sizeof(sc->health_log)), NVME_COPY_TO_PRP); break; case NVME_LOG_FIRMWARE_SLOT: + if (logoff >= sizeof(sc->fw_log)) { + pci_nvme_status_genc(&compl->status, + NVME_SC_INVALID_FIELD); + break; + } + nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1, - command->prp2, (uint8_t *)&sc->fw_log, - MIN(logsize, sizeof(sc->fw_log)), + command->prp2, (uint8_t *)&sc->fw_log + logoff, + MIN(logsize - logoff, sizeof(sc->fw_log)), NVME_COPY_TO_PRP); break; case NVME_LOG_CHANGED_NAMESPACE: + if (logoff >= sizeof(sc->ns_log)) { + pci_nvme_status_genc(&compl->status, + NVME_SC_INVALID_FIELD); + break; + } + nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1, - command->prp2, (uint8_t *)&sc->ns_log, - MIN(logsize, sizeof(sc->ns_log)), + command->prp2, (uint8_t *)&sc->ns_log + logoff, + MIN(logsize - logoff, sizeof(sc->ns_log)), NVME_COPY_TO_PRP); memset(&sc->ns_log, 0, sizeof(sc->ns_log)); break;