nvme: check metadata dword alignment

PSDT 00b also need to check the metadta alignment.

Change-Id: I117f524c61bc4c712b46c91e4d51549825d06f6c
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1353
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Changpeng Liu 2020-03-19 01:17:13 -04:00 committed by Tomasz Zawadzki
parent 8065ab2c27
commit 760c98651e

View File

@ -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,12 +2184,16 @@ 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);
exit: