From bf190e2f52cc0662c1540b70c768f793b4230b02 Mon Sep 17 00:00:00 2001 From: Changpeng Liu Date: Tue, 2 Nov 2021 22:37:39 +0800 Subject: [PATCH] nvmf/vfio-user: return NVMe compliance SC value when creating IO queues CAP.CQR (Contiguous Queues Required) is always 1, so we should return invalid field when PC bit is 1 and return Invalid Interrupt Vector if Interrupt Vector is too big. Also fix the issue that just creat/delete a CQ. Change-Id: I7cc64a5946a1ed3161448fca8b433d08e5fee715 Signed-off-by: Changpeng Liu Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10080 Reviewed-by: Jim Harris Reviewed-by: Ben Walker Tested-by: SPDK CI Jenkins Community-CI: Broadcom CI Community-CI: Mellanox Build Bot --- lib/nvmf/vfio_user.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/nvmf/vfio_user.c b/lib/nvmf/vfio_user.c index b17e42e89..a19ce3c58 100644 --- a/lib/nvmf/vfio_user.c +++ b/lib/nvmf/vfio_user.c @@ -62,7 +62,6 @@ #define NVME_REG_CFG_SIZE 0x1000 #define NVME_REG_BAR0_SIZE 0x4000 -#define NVME_IRQ_INTX_NUM 1 #define NVME_IRQ_MSIX_NUM NVMF_VFIO_USER_DEFAULT_MAX_QPAIRS_PER_CTRLR struct nvmf_vfio_user_req; @@ -1139,6 +1138,18 @@ handle_create_io_q(struct nvmf_vfio_user_ctrlr *ctrlr, is_cq ? 'C' : 'S', qid, qsize); if (is_cq) { + if (cmd->cdw11_bits.create_io_cq.pc != 0x1) { + SPDK_ERRLOG("%s: non-PC CQ not supporred\n", ctrlr_id(ctrlr)); + sc = SPDK_NVME_SC_INVALID_FIELD; + goto out; + } + if (cmd->cdw11_bits.create_io_cq.iv > NVME_IRQ_MSIX_NUM - 1) { + SPDK_ERRLOG("%s: IV is too big\n", ctrlr_id(ctrlr)); + sct = SPDK_NVME_SCT_COMMAND_SPECIFIC; + sc = SPDK_NVME_SC_INVALID_INTERRUPT_VECTOR; + goto out; + } + err = init_qp(ctrlr, ctrlr->qp[0]->qpair.transport, qsize, qid); if (err != 0) { sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; @@ -1146,11 +1157,6 @@ handle_create_io_q(struct nvmf_vfio_user_ctrlr *ctrlr, } io_q = &ctrlr->qp[qid]->cq; - if (cmd->cdw11_bits.create_io_cq.pc != 0x1) { - SPDK_ERRLOG("%s: non-PC CQ not supporred\n", ctrlr_id(ctrlr)); - sc = SPDK_NVME_SC_INVALID_CONTROLLER_MEM_BUF; - goto out; - } io_q->ien = cmd->cdw11_bits.create_io_cq.ien; io_q->iv = cmd->cdw11_bits.create_io_cq.iv; io_q->phase = true; @@ -1173,7 +1179,7 @@ handle_create_io_q(struct nvmf_vfio_user_ctrlr *ctrlr, if (cmd->cdw11_bits.create_io_sq.pc != 0x1) { SPDK_ERRLOG("%s: non-PC SQ not supported\n", ctrlr_id(ctrlr)); - sc = SPDK_NVME_SC_INVALID_CONTROLLER_MEM_BUF; + sc = SPDK_NVME_SC_INVALID_FIELD; goto out; } /* TODO: support shared IO CQ */ @@ -1277,6 +1283,11 @@ handle_del_io_q(struct nvmf_vfio_user_ctrlr *ctrlr, vu_qpair = ctrlr->qp[cmd->cdw10_bits.delete_io_q.qid]; if (is_cq) { + if (vu_qpair->state == VFIO_USER_QPAIR_UNINITIALIZED) { + free_qp(ctrlr, cmd->cdw10_bits.delete_io_q.qid); + goto out; + } + /* SQ must have been deleted first */ if (vu_qpair->state != VFIO_USER_QPAIR_SQ_DELETED) { SPDK_ERRLOG("%s: the associated SQ must be deleted first\n", ctrlr_id(ctrlr));