All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Fix nvme copy command with pi metadata
@ 2022-04-20  9:03 Dmitry Tikhov
  2022-04-20  9:03 ` [PATCH 1/2] hw/nvme: refactor check of disabled dif Dmitry Tikhov
  2022-04-20  9:03 ` [PATCH 2/2] hw/nvme: fix copy cmd for pi enabled namespaces Dmitry Tikhov
  0 siblings, 2 replies; 7+ messages in thread
From: Dmitry Tikhov @ 2022-04-20  9:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: kbusch, its, ddtikhov, qemu-block, linux

Current implementation of copy command, for namespace with end-to-end
data protection enabled, always returns data integrity field check
errors.
For example, issuing with nvme-cli:

    nvme copy --sdlba=25 --blocks=2,1,3 --slbs=1,37,50 --prinfow=5
    --prinfor=5 --ref-tag=25 --expected-ref-tags=1,37,50 /dev/nvme0n1

Always returns End-to-end Reference Tag Check Error.
To reproduce you may need to use upstream version of nvme-cli since
there was a bug which prevented passing prinfow to a command, fixed in
2cf9825 commit.

This patch set attempts to fix copy command for data protection enabled
namespaces.

Dmitry Tikhov (2):
  hw/nvme: refactor check of disabled dif
  hw/nvme: fix copy cmd for pi enabled namespaces

 hw/nvme/ctrl.c       |   5 ++
 hw/nvme/dif.c        | 186 +++++++++++++++++++++++++++++++++----------
 hw/nvme/dif.h        |   3 +
 hw/nvme/trace-events |   4 +-
 4 files changed, 155 insertions(+), 43 deletions(-)

-- 
2.35.1



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/2] hw/nvme: refactor check of disabled dif
  2022-04-20  9:03 [PATCH 0/2] Fix nvme copy command with pi metadata Dmitry Tikhov
@ 2022-04-20  9:03 ` Dmitry Tikhov
  2022-04-20  9:03 ` [PATCH 2/2] hw/nvme: fix copy cmd for pi enabled namespaces Dmitry Tikhov
  1 sibling, 0 replies; 7+ messages in thread
From: Dmitry Tikhov @ 2022-04-20  9:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: kbusch, its, ddtikhov, qemu-block, linux

Move to a separate function code determining whether protection checking
in end-to-end data protection enabled namespace should be done.
Currently this code is used only in nvme_dif_prchk_crc16 and
nvme_dif_prchk_crc64 functions.

Signed-off-by: Dmitry Tikhov <d.tihov@yadro.com>
---
 hw/nvme/dif.c        | 121 ++++++++++++++++++++++++++++---------------
 hw/nvme/dif.h        |   1 +
 hw/nvme/trace-events |   4 +-
 3 files changed, 83 insertions(+), 43 deletions(-)

diff --git a/hw/nvme/dif.c b/hw/nvme/dif.c
index 63c44c86ab..0f65687396 100644
--- a/hw/nvme/dif.c
+++ b/hw/nvme/dif.c
@@ -60,6 +60,75 @@ static uint64_t crc64_nvme(uint64_t crc, const unsigned char *buffer,
     return crc ^ (uint64_t)~0;
 }
 
+static bool nvme_dif_is_disabled_crc16(NvmeNamespace *ns, NvmeDifTuple *dif)
+{
+    switch (NVME_ID_NS_DPS_TYPE(ns->id_ns.dps)) {
+    case NVME_ID_NS_DPS_TYPE_3:
+        if (be32_to_cpu(dif->g16.reftag) != 0xffffffff) {
+            break;
+        }
+
+        /* fallthrough */
+    case NVME_ID_NS_DPS_TYPE_1:
+    case NVME_ID_NS_DPS_TYPE_2:
+        if (be16_to_cpu(dif->g16.apptag) != 0xffff) {
+            break;
+        }
+
+        trace_pci_nvme_dif_is_disabled_crc16(be16_to_cpu(dif->g16.apptag),
+                                             be32_to_cpu(dif->g16.reftag));
+
+        return true;
+    }
+
+    return false;
+}
+
+static bool nvme_dif_is_disabled_crc64(NvmeNamespace *ns, NvmeDifTuple *dif)
+{
+    uint64_t r = 0;
+
+    r |= (uint64_t)dif->g64.sr[0] << 40;
+    r |= (uint64_t)dif->g64.sr[1] << 32;
+    r |= (uint64_t)dif->g64.sr[2] << 24;
+    r |= (uint64_t)dif->g64.sr[3] << 16;
+    r |= (uint64_t)dif->g64.sr[4] << 8;
+    r |= (uint64_t)dif->g64.sr[5];
+
+    switch (NVME_ID_NS_DPS_TYPE(ns->id_ns.dps)) {
+    case NVME_ID_NS_DPS_TYPE_3:
+        if (r != 0xffffffffffff) {
+            break;
+        }
+
+        /* fallthrough */
+    case NVME_ID_NS_DPS_TYPE_1:
+    case NVME_ID_NS_DPS_TYPE_2:
+        if (be16_to_cpu(dif->g64.apptag) != 0xffff) {
+            break;
+        }
+
+        trace_pci_nvme_dif_is_disabled_crc64(be16_to_cpu(dif->g16.apptag),
+                                             r);
+
+        return true;
+    }
+
+    return false;
+}
+
+bool nvme_dif_is_disabled(NvmeNamespace *ns, NvmeDifTuple *dif)
+{
+    switch (ns->pif) {
+    case NVME_PI_GUARD_16:
+        return nvme_dif_is_disabled_crc16(ns, dif);
+    case NVME_PI_GUARD_64:
+        return nvme_dif_is_disabled_crc64(ns, dif);
+    default:
+        abort();
+    }
+}
+
 static void nvme_dif_pract_generate_dif_crc16(NvmeNamespace *ns, uint8_t *buf,
                                               size_t len, uint8_t *mbuf,
                                               size_t mlen, uint16_t apptag,
@@ -155,22 +224,7 @@ static uint16_t nvme_dif_prchk_crc16(NvmeNamespace *ns, NvmeDifTuple *dif,
                                      uint8_t prinfo, uint16_t apptag,
                                      uint16_t appmask, uint64_t reftag)
 {
-    switch (NVME_ID_NS_DPS_TYPE(ns->id_ns.dps)) {
-    case NVME_ID_NS_DPS_TYPE_3:
-        if (be32_to_cpu(dif->g16.reftag) != 0xffffffff) {
-            break;
-        }
-
-        /* fallthrough */
-    case NVME_ID_NS_DPS_TYPE_1:
-    case NVME_ID_NS_DPS_TYPE_2:
-        if (be16_to_cpu(dif->g16.apptag) != 0xffff) {
-            break;
-        }
-
-        trace_pci_nvme_dif_prchk_disabled_crc16(be16_to_cpu(dif->g16.apptag),
-                                                be32_to_cpu(dif->g16.reftag));
-
+    if (nvme_dif_is_disabled_crc16(ns, dif)) {
         return NVME_SUCCESS;
     }
 
@@ -214,31 +268,7 @@ static uint16_t nvme_dif_prchk_crc64(NvmeNamespace *ns, NvmeDifTuple *dif,
                                      uint8_t prinfo, uint16_t apptag,
                                      uint16_t appmask, uint64_t reftag)
 {
-    uint64_t r = 0;
-
-    r |= (uint64_t)dif->g64.sr[0] << 40;
-    r |= (uint64_t)dif->g64.sr[1] << 32;
-    r |= (uint64_t)dif->g64.sr[2] << 24;
-    r |= (uint64_t)dif->g64.sr[3] << 16;
-    r |= (uint64_t)dif->g64.sr[4] << 8;
-    r |= (uint64_t)dif->g64.sr[5];
-
-    switch (NVME_ID_NS_DPS_TYPE(ns->id_ns.dps)) {
-    case NVME_ID_NS_DPS_TYPE_3:
-        if (r != 0xffffffffffff) {
-            break;
-        }
-
-        /* fallthrough */
-    case NVME_ID_NS_DPS_TYPE_1:
-    case NVME_ID_NS_DPS_TYPE_2:
-        if (be16_to_cpu(dif->g64.apptag) != 0xffff) {
-            break;
-        }
-
-        trace_pci_nvme_dif_prchk_disabled_crc64(be16_to_cpu(dif->g16.apptag),
-                                                r);
-
+    if (nvme_dif_is_disabled_crc64(ns, dif)) {
         return NVME_SUCCESS;
     }
 
@@ -266,6 +296,15 @@ static uint16_t nvme_dif_prchk_crc64(NvmeNamespace *ns, NvmeDifTuple *dif,
     }
 
     if (prinfo & NVME_PRINFO_PRCHK_REF) {
+        uint64_t r = 0;
+
+        r |= (uint64_t)dif->g64.sr[0] << 40;
+        r |= (uint64_t)dif->g64.sr[1] << 32;
+        r |= (uint64_t)dif->g64.sr[2] << 24;
+        r |= (uint64_t)dif->g64.sr[3] << 16;
+        r |= (uint64_t)dif->g64.sr[4] << 8;
+        r |= (uint64_t)dif->g64.sr[5];
+
         trace_pci_nvme_dif_prchk_reftag_crc64(r, reftag);
 
         if (r != reftag) {
diff --git a/hw/nvme/dif.h b/hw/nvme/dif.h
index f12e312250..fe1e5828d7 100644
--- a/hw/nvme/dif.h
+++ b/hw/nvme/dif.h
@@ -186,6 +186,7 @@ uint16_t nvme_dif_check(NvmeNamespace *ns, uint8_t *buf, size_t len,
                         uint8_t *mbuf, size_t mlen, uint8_t prinfo,
                         uint64_t slba, uint16_t apptag,
                         uint16_t appmask, uint64_t *reftag);
+bool nvme_dif_is_disabled(NvmeNamespace *ns, NvmeDifTuple *dif);
 uint16_t nvme_dif_rw(NvmeCtrl *n, NvmeRequest *req);
 
 #endif /* HW_NVME_DIF_H */
diff --git a/hw/nvme/trace-events b/hw/nvme/trace-events
index ff1b458969..c4e75b1f5d 100644
--- a/hw/nvme/trace-events
+++ b/hw/nvme/trace-events
@@ -23,8 +23,8 @@ pci_nvme_dif_rw_check_cb(uint16_t cid, uint8_t prinfo, uint16_t apptag, uint16_t
 pci_nvme_dif_pract_generate_dif_crc16(size_t len, size_t lba_size, size_t chksum_len, uint16_t apptag, uint32_t reftag) "len %zu lba_size %zu chksum_len %zu apptag 0x%"PRIx16" reftag 0x%"PRIx32""
 pci_nvme_dif_pract_generate_dif_crc64(size_t len, size_t lba_size, size_t chksum_len, uint16_t apptag, uint64_t reftag) "len %zu lba_size %zu chksum_len %zu apptag 0x%"PRIx16" reftag 0x%"PRIx64""
 pci_nvme_dif_check(uint8_t prinfo, uint16_t chksum_len) "prinfo 0x%"PRIx8" chksum_len %"PRIu16""
-pci_nvme_dif_prchk_disabled_crc16(uint16_t apptag, uint32_t reftag) "apptag 0x%"PRIx16" reftag 0x%"PRIx32""
-pci_nvme_dif_prchk_disabled_crc64(uint16_t apptag, uint64_t reftag) "apptag 0x%"PRIx16" reftag 0x%"PRIx64""
+pci_nvme_dif_is_disabled_crc16(uint16_t apptag, uint32_t reftag) "apptag 0x%"PRIx16" reftag 0x%"PRIx32""
+pci_nvme_dif_is_disabled_crc64(uint16_t apptag, uint64_t reftag) "apptag 0x%"PRIx16" reftag 0x%"PRIx64""
 pci_nvme_dif_prchk_guard_crc16(uint16_t guard, uint16_t crc) "guard 0x%"PRIx16" crc 0x%"PRIx16""
 pci_nvme_dif_prchk_guard_crc64(uint64_t guard, uint64_t crc) "guard 0x%"PRIx64" crc 0x%"PRIx64""
 pci_nvme_dif_prchk_apptag(uint16_t apptag, uint16_t elbat, uint16_t elbatm) "apptag 0x%"PRIx16" elbat 0x%"PRIx16" elbatm 0x%"PRIx16""
-- 
2.35.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/2] hw/nvme: fix copy cmd for pi enabled namespaces
  2022-04-20  9:03 [PATCH 0/2] Fix nvme copy command with pi metadata Dmitry Tikhov
  2022-04-20  9:03 ` [PATCH 1/2] hw/nvme: refactor check of disabled dif Dmitry Tikhov
@ 2022-04-20  9:03 ` Dmitry Tikhov
  2022-04-20 10:04   ` Klaus Jensen
  1 sibling, 1 reply; 7+ messages in thread
From: Dmitry Tikhov @ 2022-04-20  9:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: kbusch, its, ddtikhov, qemu-block, linux

Current implementation have two problems:
First in the read part of copy command. Because there is no metadata
mangling before nvme_dif_check invocation, reftag error is thrown for
blocks of namespace that have not been previously written to.
Second in the write part. Reftag in the protection information section
of the source metadata should not be copied as is to the destination.
Source range start lba and destination range start lba could differ so
recalculation of reftag is always needed.

Signed-off-by: Dmitry Tikhov <d.tihov@yadro.com>
---
 hw/nvme/ctrl.c |  5 ++++
 hw/nvme/dif.c  | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/nvme/dif.h  |  2 ++
 3 files changed, 72 insertions(+)

diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 74540a03d5..cb493f4506 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -2787,6 +2787,10 @@ static void nvme_copy_in_completed_cb(void *opaque, int ret)
         size_t mlen = nvme_m2b(ns, nlb);
         uint8_t *mbounce = iocb->bounce + nvme_l2b(ns, nlb);
 
+        status = nvme_dif_mangle_mdata(ns, mbounce, mlen, reftag);
+        if (status) {
+            goto invalid;
+        }
         status = nvme_dif_check(ns, iocb->bounce, len, mbounce, mlen, prinfor,
                                 slba, apptag, appmask, &reftag);
         if (status) {
@@ -2805,6 +2809,7 @@ static void nvme_copy_in_completed_cb(void *opaque, int ret)
             nvme_dif_pract_generate_dif(ns, iocb->bounce, len, mbounce, mlen,
                                         apptag, &iocb->reftag);
         } else {
+            nvme_dif_restore_reftag(ns, mbounce, mlen, iocb->reftag);
             status = nvme_dif_check(ns, iocb->bounce, len, mbounce, mlen,
                                     prinfow, iocb->slba, apptag, appmask,
                                     &iocb->reftag);
diff --git a/hw/nvme/dif.c b/hw/nvme/dif.c
index 0f65687396..f29c5893e2 100644
--- a/hw/nvme/dif.c
+++ b/hw/nvme/dif.c
@@ -385,6 +385,71 @@ uint16_t nvme_dif_check(NvmeNamespace *ns, uint8_t *buf, size_t len,
     return NVME_SUCCESS;
 }
 
+static void nvme_dif_restore_reftag_crc16(NvmeNamespace *ns, uint8_t *mbuf,
+                                          size_t mlen, uint64_t reftag,
+                                          int16_t pil)
+{
+    uint8_t *mbufp, *end = mbuf + mlen;
+
+    for (mbufp = mbuf; mbufp < end; mbufp += ns->lbaf.ms) {
+        NvmeDifTuple *dif = (NvmeDifTuple *)(mbufp + pil);
+
+        if (!nvme_dif_is_disabled_crc16(ns, dif)) {
+            dif->g16.reftag = cpu_to_be32(reftag++);
+        }
+
+    }
+
+    return;
+}
+
+static void nvme_dif_restore_reftag_crc64(NvmeNamespace *ns, uint8_t *mbuf,
+                                          size_t mlen, uint64_t reftag,
+                                          int16_t pil)
+{
+    uint8_t *mbufp, *end = mbuf + mlen;
+
+    for (mbufp = mbuf; mbufp < end; mbufp += ns->lbaf.ms) {
+        NvmeDifTuple *dif = (NvmeDifTuple *)(mbufp + pil);
+
+        if (!nvme_dif_is_disabled_crc64(ns, dif)) {
+            dif->g64.sr[0] = reftag >> 40;
+            dif->g64.sr[1] = reftag >> 32;
+            dif->g64.sr[2] = reftag >> 24;
+            dif->g64.sr[3] = reftag >> 16;
+            dif->g64.sr[4] = reftag >> 8;
+            dif->g64.sr[5] = reftag;
+
+            reftag++;
+        }
+
+    }
+
+    return;
+}
+
+void nvme_dif_restore_reftag(NvmeNamespace *ns, uint8_t *mbuf,
+                             size_t mlen, uint64_t reftag)
+{
+    int16_t pil = 0;
+
+    if (!(ns->id_ns.dps & NVME_ID_NS_DPS_FIRST_EIGHT)) {
+        pil = ns->lbaf.ms - nvme_pi_tuple_size(ns);
+    }
+
+    switch (ns->pif) {
+    case NVME_PI_GUARD_16:
+        nvme_dif_restore_reftag_crc16(ns, mbuf, mlen, reftag, pil);
+        return;
+    case NVME_PI_GUARD_64:
+        nvme_dif_restore_reftag_crc64(ns, mbuf, mlen, reftag, pil);
+        return;
+    default:
+        abort();
+    }
+
+}
+
 uint16_t nvme_dif_mangle_mdata(NvmeNamespace *ns, uint8_t *mbuf, size_t mlen,
                                uint64_t slba)
 {
diff --git a/hw/nvme/dif.h b/hw/nvme/dif.h
index fe1e5828d7..3203837658 100644
--- a/hw/nvme/dif.h
+++ b/hw/nvme/dif.h
@@ -186,6 +186,8 @@ uint16_t nvme_dif_check(NvmeNamespace *ns, uint8_t *buf, size_t len,
                         uint8_t *mbuf, size_t mlen, uint8_t prinfo,
                         uint64_t slba, uint16_t apptag,
                         uint16_t appmask, uint64_t *reftag);
+void nvme_dif_restore_reftag(NvmeNamespace *ns, uint8_t *mbuf,
+                             size_t mlen, uint64_t reftag);
 bool nvme_dif_is_disabled(NvmeNamespace *ns, NvmeDifTuple *dif);
 uint16_t nvme_dif_rw(NvmeCtrl *n, NvmeRequest *req);
 
-- 
2.35.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] hw/nvme: fix copy cmd for pi enabled namespaces
  2022-04-20  9:03 ` [PATCH 2/2] hw/nvme: fix copy cmd for pi enabled namespaces Dmitry Tikhov
@ 2022-04-20 10:04   ` Klaus Jensen
  2022-04-20 19:16     ` Klaus Jensen
  0 siblings, 1 reply; 7+ messages in thread
From: Klaus Jensen @ 2022-04-20 10:04 UTC (permalink / raw)
  To: Dmitry Tikhov; +Cc: kbusch, ddtikhov, qemu-devel, qemu-block, linux

[-- Attachment #1: Type: text/plain, Size: 1068 bytes --]

On Apr 20 12:03, Dmitry Tikhov wrote:
> Current implementation have two problems:
> First in the read part of copy command. Because there is no metadata
> mangling before nvme_dif_check invocation, reftag error is thrown for
> blocks of namespace that have not been previously written to.

Yes, this is definitely a bug and the fix is good, thanks!

> Second in the write part. Reftag in the protection information section
> of the source metadata should not be copied as is to the destination.

Hmm, says who?

> Source range start lba and destination range start lba could differ so
> recalculation of reftag is always needed.
> 

If PRACT is 0, we really should not touch the protection information. My
interpretation of the Copy command is that it is simply just screwed if
used with PRACT 0 and Type 1. PRACT bit is specifically to allow the
controller to generate appropriate PI in this case.

On the other hand, I can totally see your interpretation as valid as
well. Let me ask some spec people about this, and I will get back to
you.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] hw/nvme: fix copy cmd for pi enabled namespaces
  2022-04-20 10:04   ` Klaus Jensen
@ 2022-04-20 19:16     ` Klaus Jensen
  2022-04-21  7:41       ` Dmitry Tikhov
  0 siblings, 1 reply; 7+ messages in thread
From: Klaus Jensen @ 2022-04-20 19:16 UTC (permalink / raw)
  To: Dmitry Tikhov; +Cc: kbusch, ddtikhov, qemu-devel, qemu-block, linux

[-- Attachment #1: Type: text/plain, Size: 1277 bytes --]

On Apr 20 12:04, Klaus Jensen wrote:
> On Apr 20 12:03, Dmitry Tikhov wrote:
> > Current implementation have two problems:
> > First in the read part of copy command. Because there is no metadata
> > mangling before nvme_dif_check invocation, reftag error is thrown for
> > blocks of namespace that have not been previously written to.
> 
> Yes, this is definitely a bug and the fix is good, thanks!
> 
> > Second in the write part. Reftag in the protection information section
> > of the source metadata should not be copied as is to the destination.
> 
> Hmm, says who?
> 
> > Source range start lba and destination range start lba could differ so
> > recalculation of reftag is always needed.
> > 
> 
> If PRACT is 0, we really should not touch the protection information. My
> interpretation of the Copy command is that it is simply just screwed if
> used with PRACT 0 and Type 1. PRACT bit is specifically to allow the
> controller to generate appropriate PI in this case.
> 
> On the other hand, I can totally see your interpretation as valid as
> well. Let me ask some spec people about this, and I will get back to
> you.

Discussed this with the TP authors and, no, reftag should not be
re-computed for PRACT 0, regardless of the PI type.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] hw/nvme: fix copy cmd for pi enabled namespaces
  2022-04-20 19:16     ` Klaus Jensen
@ 2022-04-21  7:41       ` Dmitry Tikhov
  2022-04-21 10:13         ` Klaus Jensen
  0 siblings, 1 reply; 7+ messages in thread
From: Dmitry Tikhov @ 2022-04-21  7:41 UTC (permalink / raw)
  To: Klaus Jensen; +Cc: kbusch, ddtikhov, qemu-devel, qemu-block, linux

On Wed, Apr 20, 2022 at 21:16:15, Klaus Jensen wrote:
> Discussed this with the TP authors and, no, reftag should not be
> re-computed for PRACT 0, regardless of the PI type.
Ok, should i resend patch with only adding nvme_dif_mangle_mdata in
the read part?


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] hw/nvme: fix copy cmd for pi enabled namespaces
  2022-04-21  7:41       ` Dmitry Tikhov
@ 2022-04-21 10:13         ` Klaus Jensen
  0 siblings, 0 replies; 7+ messages in thread
From: Klaus Jensen @ 2022-04-21 10:13 UTC (permalink / raw)
  To: Dmitry Tikhov; +Cc: kbusch, ddtikhov, qemu-devel, qemu-block, linux

[-- Attachment #1: Type: text/plain, Size: 335 bytes --]

On Apr 21 10:41, Dmitry Tikhov wrote:
> On Wed, Apr 20, 2022 at 21:16:15, Klaus Jensen wrote:
> > Discussed this with the TP authors and, no, reftag should not be
> > re-computed for PRACT 0, regardless of the PI type.
> Ok, should i resend patch with only adding nvme_dif_mangle_mdata in
> the read part?

Yes, that is still a bug :)

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-04-21 10:34 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-20  9:03 [PATCH 0/2] Fix nvme copy command with pi metadata Dmitry Tikhov
2022-04-20  9:03 ` [PATCH 1/2] hw/nvme: refactor check of disabled dif Dmitry Tikhov
2022-04-20  9:03 ` [PATCH 2/2] hw/nvme: fix copy cmd for pi enabled namespaces Dmitry Tikhov
2022-04-20 10:04   ` Klaus Jensen
2022-04-20 19:16     ` Klaus Jensen
2022-04-21  7:41       ` Dmitry Tikhov
2022-04-21 10:13         ` Klaus Jensen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.