mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 00:33:55 -06:00
hw/nvme: 64-bit pi support
This adds support for one possible new protection information format introduced in TP4068 (and integrated in NVMe 2.0): the 64-bit CRC guard and 48-bit reference tag. This version does not support storage tags. Like the CRC16 support already present, this uses a software implementation of CRC64 (so it is naturally pretty slow). But its good enough for verification purposes. This may go nicely hand-in-hand with the support that Keith submitted for the Linux kernel[1]. [1]: https://lore.kernel.org/linux-nvme/20220126165214.GA1782352@dhcp-10-100-145-180.wdc.com/T/ Reviewed-by: Keith Busch <kbusch@kernel.org> Signed-off-by: Naveen Nagar <naveen.n1@samsung.com> Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
This commit is contained in:
parent
ac0b34c58d
commit
44219b6029
7 changed files with 608 additions and 98 deletions
35
hw/nvme/ns.c
35
hw/nvme/ns.c
|
@ -58,6 +58,7 @@ static int nvme_ns_init(NvmeNamespace *ns, Error **errp)
|
|||
{
|
||||
static uint64_t ns_count;
|
||||
NvmeIdNs *id_ns = &ns->id_ns;
|
||||
NvmeIdNsNvm *id_ns_nvm = &ns->id_ns_nvm;
|
||||
uint8_t ds;
|
||||
uint16_t ms;
|
||||
int i;
|
||||
|
@ -101,6 +102,8 @@ static int nvme_ns_init(NvmeNamespace *ns, Error **errp)
|
|||
id_ns->dps |= NVME_ID_NS_DPS_FIRST_EIGHT;
|
||||
}
|
||||
|
||||
ns->pif = ns->params.pif;
|
||||
|
||||
static const NvmeLBAF lbaf[16] = {
|
||||
[0] = { .ds = 9 },
|
||||
[1] = { .ds = 9, .ms = 8 },
|
||||
|
@ -133,7 +136,9 @@ static int nvme_ns_init(NvmeNamespace *ns, Error **errp)
|
|||
|
||||
id_ns->flbas |= i;
|
||||
|
||||
|
||||
lbaf_found:
|
||||
id_ns_nvm->elbaf[i] = (ns->pif & 0x3) << 7;
|
||||
id_ns->nlbaf = ns->nlbaf - 1;
|
||||
nvme_ns_init_format(ns);
|
||||
|
||||
|
@ -373,15 +378,36 @@ static void nvme_zoned_ns_shutdown(NvmeNamespace *ns)
|
|||
|
||||
static int nvme_ns_check_constraints(NvmeNamespace *ns, Error **errp)
|
||||
{
|
||||
unsigned int pi_size;
|
||||
|
||||
if (!ns->blkconf.blk) {
|
||||
error_setg(errp, "block backend not configured");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ns->params.pi && ns->params.ms < 8) {
|
||||
error_setg(errp, "at least 8 bytes of metadata required to enable "
|
||||
"protection information");
|
||||
return -1;
|
||||
if (ns->params.pi) {
|
||||
if (ns->params.pi > NVME_ID_NS_DPS_TYPE_3) {
|
||||
error_setg(errp, "invalid 'pi' value");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (ns->params.pif) {
|
||||
case NVME_PI_GUARD_16:
|
||||
pi_size = 8;
|
||||
break;
|
||||
case NVME_PI_GUARD_64:
|
||||
pi_size = 16;
|
||||
break;
|
||||
default:
|
||||
error_setg(errp, "invalid 'pif'");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ns->params.ms < pi_size) {
|
||||
error_setg(errp, "at least %u bytes of metadata required to "
|
||||
"enable protection information", pi_size);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ns->params.nsid > NVME_MAX_NAMESPACES) {
|
||||
|
@ -593,6 +619,7 @@ static Property nvme_ns_props[] = {
|
|||
DEFINE_PROP_UINT8("mset", NvmeNamespace, params.mset, 0),
|
||||
DEFINE_PROP_UINT8("pi", NvmeNamespace, params.pi, 0),
|
||||
DEFINE_PROP_UINT8("pil", NvmeNamespace, params.pil, 0),
|
||||
DEFINE_PROP_UINT8("pif", NvmeNamespace, params.pif, 0),
|
||||
DEFINE_PROP_UINT16("mssrl", NvmeNamespace, params.mssrl, 128),
|
||||
DEFINE_PROP_UINT32("mcl", NvmeNamespace, params.mcl, 128),
|
||||
DEFINE_PROP_UINT8("msrc", NvmeNamespace, params.msrc, 127),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue