Commit 760c9865 authored by Changpeng Liu's avatar Changpeng Liu Committed by Tomasz Zawadzki
Browse files

nvme: check metadata dword alignment



PSDT 00b also need to check the metadta alignment.

Change-Id: I117f524c61bc4c712b46c91e4d51549825d06f6c
Signed-off-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1353


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent 8065ab2c
Loading
Loading
Loading
Loading
+34 −18
Original line number Diff line number Diff line
@@ -2116,12 +2116,37 @@ static build_req_fn const g_nvme_pcie_build_req_table[][2] = {
	}
};

static int
nvme_pcie_qpair_build_metadata(struct spdk_nvme_qpair *qpair, struct nvme_tracker *tr,
			       bool dword_aligned)
{
	void *md_payload;
	struct nvme_request *req = tr->req;

	if (req->payload.md) {
		md_payload = req->payload.md + req->md_offset;
		if (dword_aligned && ((uintptr_t)md_payload & 3)) {
			SPDK_ERRLOG("virt_addr %p not dword aligned\n", md_payload);
			goto exit;
		}
		tr->req->cmd.mptr = spdk_vtophys(md_payload, NULL);
		if (tr->req->cmd.mptr == SPDK_VTOPHYS_ERROR) {
			goto exit;
		}
	}

	return 0;

exit:
	nvme_pcie_fail_request_bad_vtophys(qpair, tr);
	return -EINVAL;
}

static int
nvme_pcie_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_request *req)
{
	struct nvme_tracker	*tr;
	int			rc = 0;
	void			*md_payload;
	struct spdk_nvme_ctrlr	*ctrlr = qpair->ctrlr;
	struct nvme_pcie_qpair	*pqpair = nvme_pcie_qpair(qpair);
	enum nvme_payload_type	payload_type;
@@ -2147,20 +2172,7 @@ nvme_pcie_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_reques
	tr->cb_arg = req->cb_arg;
	req->cmd.cid = tr->cid;

	if (req->payload_size && req->payload.md) {
		md_payload = req->payload.md + req->md_offset;
		tr->req->cmd.mptr = spdk_vtophys(md_payload, NULL);
		if (tr->req->cmd.mptr == SPDK_VTOPHYS_ERROR) {
			nvme_pcie_fail_request_bad_vtophys(qpair, tr);
			rc = -EINVAL;
			goto exit;
		}
	}

	if (req->payload_size == 0) {
		/* Null payload - leave PRP fields untouched */
		rc = 0;
	} else {
	if (req->payload_size != 0) {
		payload_type = nvme_payload_type(&req->payload);
		/* According to the specification, PRPs shall be used for all
		 *  Admin commands for NVMe over PCIe implementations.
@@ -2172,11 +2184,15 @@ nvme_pcie_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_reques
			dword_aligned = false;
		}
		rc = g_nvme_pcie_build_req_table[payload_type][sgl_supported](qpair, req, tr, dword_aligned);
		if (rc < 0) {
			goto exit;
		}

		rc = nvme_pcie_qpair_build_metadata(qpair, tr, dword_aligned);
		if (rc < 0) {
			goto exit;
		}
	}

	nvme_pcie_qpair_submit_tracker(qpair, tr);