@@ -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) {
@@ -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 */
@@ -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""
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(-)