git: 8ab99dbea167 - main - bhyve: abort and return FEATURE_NOT_SAVEABLE while set feature with a save flag for NVMe controller.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 15 Nov 2022 07:26:06 UTC
The branch main has been updated by corvink:
URL: https://cgit.FreeBSD.org/src/commit/?id=8ab99dbea16728f3e34137310587a6aeb3f3d317
commit 8ab99dbea16728f3e34137310587a6aeb3f3d317
Author: Wanpeng Qian <wanpengqian@gmail.com>
AuthorDate: 2022-11-14 13:02:44 +0000
Commit: Corvin Köhne <corvink@FreeBSD.org>
CommitDate: 2022-11-15 06:48:24 +0000
bhyve: abort and return FEATURE_NOT_SAVEABLE while set feature with a save flag for NVMe controller.
Currently bhyve's NVMe controller cannot save feature values cross
reboot. It should return a FEATURE_NOT_SAVEABLE error when the command
specifies a save flag.
Quote from NVMe specification, page 205:
https://nvmexpress.org/wp-content/uploads/NVM-Express-1_4-2019.06.10-Ratified.pdf
If the Feature Identifier specified in the Set Features command is not
saveable by the controller and the controller receives a Set Features
command with the Save bit set to one, then the command shall be aborted
with a status of Feature Identifier Not Saveable.
Reviewed by: chuck (older version)
Approved by: manu (mentor)
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D32767
---
sys/dev/nvme/nvme.h | 16 ++++++++++++++++
usr.sbin/bhyve/pci_nvme.c | 10 +++++++++-
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/sys/dev/nvme/nvme.h b/sys/dev/nvme/nvme.h
index 94b20069c12e..ccc980a7c6ec 100644
--- a/sys/dev/nvme/nvme.h
+++ b/sys/dev/nvme/nvme.h
@@ -566,9 +566,25 @@ enum nvme_critical_warning_state {
#define NVME_SS_PAGE_SSTAT_GDE_SHIFT (8)
#define NVME_SS_PAGE_SSTAT_GDE_MASK (0x1)
+/* Features */
+/* Get Features */
+#define NVME_FEAT_GET_SEL_SHIFT (8)
+#define NVME_FEAT_GET_SEL_MASK (0x7)
+#define NVME_FEAT_GET_FID_SHIFT (0)
+#define NVME_FEAT_GET_FID_MASK (0xff)
+
+/* Set Features */
+#define NVME_FEAT_SET_SV_SHIFT (31)
+#define NVME_FEAT_SET_SV_MASK (0x1)
+#define NVME_FEAT_SET_FID_SHIFT (0)
+#define NVME_FEAT_SET_FID_MASK (0xff)
+
/* Helper macro to combine *_MASK and *_SHIFT defines */
#define NVMEB(name) (name##_MASK << name##_SHIFT)
+/* Helper macro to extract value from x */
+#define NVMEV(name, x) (((x) >> name##_SHIFT) & name##_MASK)
+
/* CC register SHN field values */
enum shn_value {
NVME_SHN_NORMAL = 0x1,
diff --git a/usr.sbin/bhyve/pci_nvme.c b/usr.sbin/bhyve/pci_nvme.c
index b341b70f4e48..1cc9838c112f 100644
--- a/usr.sbin/bhyve/pci_nvme.c
+++ b/usr.sbin/bhyve/pci_nvme.c
@@ -1849,7 +1849,8 @@ nvme_opc_set_features(struct pci_nvme_softc *sc, struct nvme_command *command,
{
struct nvme_feature_obj *feat;
uint32_t nsid = command->nsid;
- uint8_t fid = command->cdw10 & 0xFF;
+ uint8_t fid = NVMEV(NVME_FEAT_SET_FID, command->cdw10);
+ bool sv = NVMEV(NVME_FEAT_SET_SV, command->cdw10);
DPRINTF("%s: Feature ID 0x%x (%s)", __func__, fid, nvme_fid_to_name(fid));
@@ -1858,6 +1859,13 @@ nvme_opc_set_features(struct pci_nvme_softc *sc, struct nvme_command *command,
pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
return (1);
}
+
+ if (sv) {
+ pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC,
+ NVME_SC_FEATURE_NOT_SAVEABLE);
+ return (1);
+ }
+
feat = &sc->feat[fid];
if (feat->namespace_specific && (nsid == NVME_GLOBAL_NAMESPACE_TAG)) {