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.ti...@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