qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] hw/nvme: Format Index Mismatch Protection


From: Arun Kumar
Subject: [PATCH] hw/nvme: Format Index Mismatch Protection
Date: Wed, 15 Jan 2025 05:23:47 +0530

implement TP4140-(Format Index Mismatch Protection)

Signed-off-by: Arun Kumar <arun.kka@samsung.com>
---
 hw/nvme/ctrl.c | 35 ++++++++++++++++++++++++++++++-----
 1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 127c3d2383..46bf522754 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -4452,6 +4452,16 @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeRequest 
*req)
         return NVME_INVALID_FIELD;
     }
 
+    if (!n->features.hbs.lbafee) {
+        if ((NVME_ID_NS_NVM_ELBAF_PIF(ns->id_ns_nvm.elbaf[
+             NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas)]) != 0)) {
+            return NVME_INVALID_FORMAT | NVME_DNR;
+        }
+        if (NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas) > ns->id_ns.nlbaf) {
+            return NVME_INVALID_FORMAT | NVME_DNR;
+        }
+    }
+
     req->ns = ns;
 
     switch (req->cmd.opcode) {
@@ -6537,8 +6547,26 @@ done:
     nvme_do_format(iocb);
 }
 
-static uint16_t nvme_format_check(NvmeNamespace *ns, uint8_t lbaf, uint8_t pi)
+static uint16_t nvme_format_check(NvmeFormatAIOCB *iocb)
 {
+    NvmeNamespace *ns = iocb->ns;
+    NvmeRequest *req = iocb->req;
+    NvmeCtrl *n = nvme_ctrl(req);
+    uint8_t lbaf = iocb->lbaf;
+    uint32_t dw10 = le32_to_cpu(req->cmd.cdw10);
+    uint8_t pi = (dw10 >> 5) & 0x7;
+
+    if (!n->features.hbs.lbafee) {
+        if ((NVME_ID_NS_NVM_ELBAF_PIF(ns->id_ns_nvm.elbaf[lbaf]) != 0) ||
+            (NVME_ID_NS_NVM_ELBAF_PIF(ns->id_ns_nvm.elbaf[
+             NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas)]) != 0)) {
+            return NVME_INVALID_FORMAT | NVME_DNR;
+        }
+        if (NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas) > ns->id_ns.nlbaf) {
+            return NVME_INVALID_FORMAT | NVME_DNR;
+        }
+    }
+
     if (ns->params.zoned) {
         return NVME_INVALID_FORMAT | NVME_DNR;
     }
@@ -6562,9 +6590,6 @@ static void nvme_do_format(NvmeFormatAIOCB *iocb)
 {
     NvmeRequest *req = iocb->req;
     NvmeCtrl *n = nvme_ctrl(req);
-    uint32_t dw10 = le32_to_cpu(req->cmd.cdw10);
-    uint8_t lbaf = dw10 & 0xf;
-    uint8_t pi = (dw10 >> 5) & 0x7;
     uint16_t status;
     int i;
 
@@ -6586,7 +6611,7 @@ static void nvme_do_format(NvmeFormatAIOCB *iocb)
         goto done;
     }
 
-    status = nvme_format_check(iocb->ns, lbaf, pi);
+    status = nvme_format_check(iocb);
     if (status) {
         req->status = status;
         goto done;
-- 
2.43.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]