git: 6e5e38c241e6 - stable/13 - bhyve nvme: Fix Set Features

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

URL: https://cgit.FreeBSD.org/src/commit/?id=6e5e38c241e618007ae7edb0d26b704b68851dd6

commit 6e5e38c241e618007ae7edb0d26b704b68851dd6
Author:     Chuck Tuffli <chuck@FreeBSD.org>
AuthorDate: 2022-01-30 07:07:44 +0000
Commit:     Chuck Tuffli <chuck@FreeBSD.org>
CommitDate: 2022-02-22 03:26:32 +0000

    bhyve nvme: Fix Set Features
    
    Be more conservative and only support the Features mandatory for an I/O
    Controller.
    
    Avoids a "hang" in UNH test 1.2.10 associated with Predictable Latency
    Mode Configuration and Host Behavior Support features.
    
    (cherry picked from commit 1381a118297c5f304178707219983c4f70cfd2c5)
---
 usr.sbin/bhyve/pci_nvme.c | 52 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 36 insertions(+), 16 deletions(-)

diff --git a/usr.sbin/bhyve/pci_nvme.c b/usr.sbin/bhyve/pci_nvme.c
index 682f7561329c..5719a5f6c8c2 100644
--- a/usr.sbin/bhyve/pci_nvme.c
+++ b/usr.sbin/bhyve/pci_nvme.c
@@ -666,21 +666,38 @@ pci_nvme_init_logpages(struct pci_nvme_softc *sc)
 static void
 pci_nvme_init_features(struct pci_nvme_softc *sc)
 {
-
-	sc->feat[0].set = nvme_feature_invalid_cb;
-	sc->feat[0].get = nvme_feature_invalid_cb;
-
-	sc->feat[NVME_FEAT_LBA_RANGE_TYPE].namespace_specific = true;
-	sc->feat[NVME_FEAT_ERROR_RECOVERY].namespace_specific = true;
-	sc->feat[NVME_FEAT_NUMBER_OF_QUEUES].set = nvme_feature_num_queues;
-	sc->feat[NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION].set =
-	    nvme_feature_iv_config;
-	/* Enable all AENs by default */
-	sc->feat[NVME_FEAT_ASYNC_EVENT_CONFIGURATION].cdw11 = 0x31f;
-	sc->feat[NVME_FEAT_PREDICTABLE_LATENCY_MODE_CONFIG].get =
-	    nvme_feature_invalid_cb;
-	sc->feat[NVME_FEAT_PREDICTABLE_LATENCY_MODE_WINDOW].get =
-	    nvme_feature_invalid_cb;
+	enum nvme_feature	fid;
+
+	for (fid = 0; fid < NVME_FID_MAX; fid++) {
+		switch (fid) {
+		case NVME_FEAT_ARBITRATION:
+		case NVME_FEAT_POWER_MANAGEMENT:
+		case NVME_FEAT_TEMPERATURE_THRESHOLD:
+		case NVME_FEAT_INTERRUPT_COALESCING: //XXX
+		case NVME_FEAT_WRITE_ATOMICITY:
+			/* Mandatory but no special handling required */
+		//XXX hang - case NVME_FEAT_PREDICTABLE_LATENCY_MODE_CONFIG:
+		//XXX hang - case NVME_FEAT_HOST_BEHAVIOR_SUPPORT:
+		//		  this returns a data buffer
+			break;
+		case NVME_FEAT_ERROR_RECOVERY:
+			sc->feat[fid].namespace_specific = true;
+			break;
+		case NVME_FEAT_NUMBER_OF_QUEUES:
+			sc->feat[fid].set = nvme_feature_num_queues;
+			break;
+		case NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION:
+			sc->feat[fid].set = nvme_feature_iv_config;
+			break;
+		case NVME_FEAT_ASYNC_EVENT_CONFIGURATION:
+			/* Enable all AENs by default */
+			sc->feat[fid].cdw11 = 0x31f;
+			break;
+		default:
+			sc->feat[fid].set = nvme_feature_invalid_cb;
+			sc->feat[fid].get = nvme_feature_invalid_cb;
+		}
+	}
 }
 
 static void
@@ -1937,11 +1954,14 @@ pci_nvme_handle_admin_cmd(struct pci_nvme_softc* sc, uint64_t value)
 		case NVME_OPC_SECURITY_RECEIVE:
 		case NVME_OPC_SANITIZE:
 		case NVME_OPC_GET_LBA_STATUS:
+			DPRINTF("%s command OPC=%#x (unsupported)", __func__,
+			    cmd->opc);
 			/* Valid but unsupported opcodes */
 			pci_nvme_status_genc(&compl.status, NVME_SC_INVALID_FIELD);
 			break;
 		default:
-			DPRINTF("0x%x command is not implemented",
+			DPRINTF("%s command OPC=%#X (not implemented)",
+			    __func__,
 			    cmd->opc);
 			pci_nvme_status_genc(&compl.status, NVME_SC_INVALID_OPCODE);
 		}