Skip to content

Commit

Permalink
hw/nvme: add support for the lbafee hbs feature
Browse files Browse the repository at this point in the history
Add support for up to 64 LBA formats through the LBAFEE field of the
Host Behavior Support feature.

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>
  • Loading branch information
Naveen Nagar authored and birkelund committed Mar 3, 2022
1 parent a6de6ed commit 763c05d
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 11 deletions.
34 changes: 31 additions & 3 deletions hw/nvme/ctrl.c
Expand Up @@ -5165,6 +5165,7 @@ static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeRequest *req)
uint32_t nsid = le32_to_cpu(cmd->nsid);
uint8_t fid = NVME_GETSETFEAT_FID(dw10);
uint8_t save = NVME_SETFEAT_SAVE(dw10);
uint16_t status;
int i;

trace_pci_nvme_setfeat(nvme_cid(req), nsid, fid, save, dw11);
Expand Down Expand Up @@ -5287,8 +5288,26 @@ static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeRequest *req)
case NVME_TIMESTAMP:
return nvme_set_feature_timestamp(n, req);
case NVME_HOST_BEHAVIOR_SUPPORT:
return nvme_h2c(n, (uint8_t *)&n->features.hbs,
sizeof(n->features.hbs), req);
status = nvme_h2c(n, (uint8_t *)&n->features.hbs,
sizeof(n->features.hbs), req);
if (status) {
return status;
}

for (i = 1; i <= NVME_MAX_NAMESPACES; i++) {
ns = nvme_ns(n, i);

if (!ns) {
continue;
}

ns->id_ns.nlbaf = ns->nlbaf - 1;
if (!n->features.hbs.lbafee) {
ns->id_ns.nlbaf = MIN(ns->id_ns.nlbaf, 15);
}
}

return status;
case NVME_COMMAND_SET_PROFILE:
if (dw11 & 0x1ff) {
trace_pci_nvme_err_invalid_iocsci(dw11 & 0x1ff);
Expand Down Expand Up @@ -5479,10 +5498,13 @@ static const AIOCBInfo nvme_format_aiocb_info = {
static void nvme_format_set(NvmeNamespace *ns, uint8_t lbaf, uint8_t mset,
uint8_t pi, uint8_t pil)
{
uint8_t lbafl = lbaf & 0xf;
uint8_t lbafu = lbaf >> 4;

trace_pci_nvme_format_set(ns->params.nsid, lbaf, mset, pi, pil);

ns->id_ns.dps = (pil << 3) | pi;
ns->id_ns.flbas = lbaf | (mset << 4);
ns->id_ns.flbas = (lbafu << 5) | (mset << 4) | lbafl;

nvme_ns_init_format(ns);
}
Expand Down Expand Up @@ -5596,6 +5618,7 @@ static uint16_t nvme_format(NvmeCtrl *n, NvmeRequest *req)
uint8_t mset = (dw10 >> 4) & 0x1;
uint8_t pi = (dw10 >> 5) & 0x7;
uint8_t pil = (dw10 >> 8) & 0x1;
uint8_t lbafu = (dw10 >> 12) & 0x3;
uint16_t status;

iocb = qemu_aio_get(&nvme_format_aiocb_info, NULL, nvme_misc_cb, req);
Expand All @@ -5612,6 +5635,10 @@ static uint16_t nvme_format(NvmeCtrl *n, NvmeRequest *req)
iocb->broadcast = (nsid == NVME_NSID_BROADCAST);
iocb->offset = 0;

if (n->features.hbs.lbafee) {
iocb->lbaf |= lbafu << 4;
}

if (!iocb->broadcast) {
if (!nvme_nsid_valid(n, nsid)) {
status = NVME_INVALID_NSID | NVME_DNR;
Expand Down Expand Up @@ -6587,6 +6614,7 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pci_dev)
id->cntlid = cpu_to_le16(n->cntlid);

id->oaes = cpu_to_le32(NVME_OAES_NS_ATTR);
id->ctratt |= cpu_to_le32(NVME_CTRATT_ELBAS);

id->rab = 6;

Expand Down
15 changes: 9 additions & 6 deletions hw/nvme/ns.c
Expand Up @@ -112,10 +112,11 @@ static int nvme_ns_init(NvmeNamespace *ns, Error **errp)
[7] = { .ds = 12, .ms = 64 },
};

ns->nlbaf = 8;

memcpy(&id_ns->lbaf, &lbaf, sizeof(lbaf));
id_ns->nlbaf = 7;

for (i = 0; i <= id_ns->nlbaf; i++) {
for (i = 0; i < ns->nlbaf; i++) {
NvmeLBAF *lbaf = &id_ns->lbaf[i];
if (lbaf->ds == ds) {
if (lbaf->ms == ms) {
Expand All @@ -126,12 +127,14 @@ static int nvme_ns_init(NvmeNamespace *ns, Error **errp)
}

/* add non-standard lba format */
id_ns->nlbaf++;
id_ns->lbaf[id_ns->nlbaf].ds = ds;
id_ns->lbaf[id_ns->nlbaf].ms = ms;
id_ns->flbas |= id_ns->nlbaf;
id_ns->lbaf[ns->nlbaf].ds = ds;
id_ns->lbaf[ns->nlbaf].ms = ms;
ns->nlbaf++;

id_ns->flbas |= i;

lbaf_found:
id_ns->nlbaf = ns->nlbaf - 1;
nvme_ns_init_format(ns);

return 0;
Expand Down
1 change: 1 addition & 0 deletions hw/nvme/nvme.h
Expand Up @@ -128,6 +128,7 @@ typedef struct NvmeNamespace {
int64_t moff;
NvmeIdNs id_ns;
NvmeLBAF lbaf;
unsigned int nlbaf;
size_t lbasz;
const uint32_t *iocs;
uint8_t csi;
Expand Down
7 changes: 5 additions & 2 deletions include/block/nvme.h
Expand Up @@ -1111,6 +1111,10 @@ enum NvmeIdCtrlOaes {
NVME_OAES_NS_ATTR = 1 << 8,
};

enum NvmeIdCtrlCtratt {
NVME_CTRATT_ELBAS = 1 << 15,
};

enum NvmeIdCtrlOacs {
NVME_OACS_SECURITY = 1 << 0,
NVME_OACS_FORMAT = 1 << 1,
Expand Down Expand Up @@ -1312,8 +1316,7 @@ typedef struct QEMU_PACKED NvmeIdNs {
uint8_t rsvd81[23];
uint8_t nguid[16];
uint64_t eui64;
NvmeLBAF lbaf[16];
uint8_t rsvd192[192];
NvmeLBAF lbaf[64];
uint8_t vs[3712];
} NvmeIdNs;

Expand Down

0 comments on commit 763c05d

Please sign in to comment.