git: 3d681a9a8009 - stable/13 - bhyve nvme: Fix NVM Format completion status

From: Chuck Tuffli <>
Date: Mon, 21 Feb 2022 21:57:52 UTC
The branch stable/13 has been updated by chuck:


commit 3d681a9a8009dded2f89fad99d186e0de895b3e9
Author:     Chuck Tuffli <>
AuthorDate: 2022-01-30 07:05:58 +0000
Commit:     Chuck Tuffli <>
CommitDate: 2022-02-22 03:25:18 +0000

    bhyve nvme: Fix NVM Format completion status
    The NVM Format command is unique among the Admin commands in that it
    needs to finish asynchronously. For this reason, the emulation code
    invented a synthetic completion status (NVME_NO_STATUS) to indicate that
    the command was still in progress and the command processing loop should
    not generate a completion message. The implementation used the value
    0xffff for the synthetic value as this set both the Status Code and
    Status Code Type fields to reserved values.
    Format initialized the completion status to this value and expected
    error cases to override it with a status code/type appropriate to the
    situation. The macros used to set the NVMe status are careful not to
    modify bit 0 (i.e. the phase bit), which with the synthetic completion
    status, causes the phase bit to get out of sync. When running tests in a
    guest with illegal NVM Format commands, Admin commands would eventually
    hang because it appeared there were no completions due to the incorrect
    phase bit value.
    Fix is to only set NVME_NO_STATUS if the blockif delete command
    succeeds. While in the neighborhood, add a missing break statement when
    NVM Format is not supported.
    (cherry picked from commit cf76cdd4bf05908eb278b825fc6d33bb6557e0c8)
 usr.sbin/bhyve/pci_nvme.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/usr.sbin/bhyve/pci_nvme.c b/usr.sbin/bhyve/pci_nvme.c
index 8352e00cf12b..0ce26f0adfee 100644
--- a/usr.sbin/bhyve/pci_nvme.c
+++ b/usr.sbin/bhyve/pci_nvme.c
@@ -1773,7 +1773,8 @@ nvme_opc_format_nvm(struct pci_nvme_softc* sc, struct nvme_command* command,
 			pci_nvme_release_ioreq(sc, req);
-		}
+		} else
+			compl->status = NVME_NO_STATUS;
 	return (1);
@@ -1900,8 +1901,8 @@ pci_nvme_handle_admin_cmd(struct pci_nvme_softc* sc, uint64_t value)
 			if ((sc->ctrldata.oacs &
 			    (1 << NVME_CTRLR_DATA_OACS_FORMAT_SHIFT)) == 0) {
 				pci_nvme_status_genc(&compl.status, NVME_SC_INVALID_OPCODE);
+				break;
-			compl.status = NVME_NO_STATUS;
 			nvme_opc_format_nvm(sc, cmd, &compl);