@@ -655,6 +655,7 @@ enum NvmeStatusCodes {
NVME_MD_SGL_LEN_INVALID = 0x0010,
NVME_SGL_DESCR_TYPE_INVALID = 0x0011,
NVME_INVALID_USE_OF_CMB = 0x0012,
+ NVME_INVALID_PRP_OFFSET = 0x0013,
NVME_LBA_RANGE = 0x0080,
NVME_CAP_EXCEEDED = 0x0081,
NVME_NS_NOT_READY = 0x0082,
@@ -328,7 +328,7 @@ static uint16_t nvme_map_prp(NvmeCtrl *n, uint64_t prp1, uint64_t prp2,
trace_pci_nvme_map_prp(trans_len, len, prp1, prp2, num_prps);
if (unlikely(!prp1)) {
- trace_pci_nvme_err_invalid_prp();
+ trace_pci_nvme_err_invalid_prp1_missing();
return NVME_INVALID_FIELD | NVME_DNR;
}
@@ -370,11 +370,16 @@ static uint16_t nvme_map_prp(NvmeCtrl *n, uint64_t prp1, uint64_t prp2,
uint64_t prp_ent = le64_to_cpu(prp_list[i]);
if (i == n->max_prp_ents - 1 && len > n->page_size) {
- if (unlikely(!prp_ent || prp_ent & (n->page_size - 1))) {
- trace_pci_nvme_err_invalid_prplist_ent(prp_ent);
+ if (unlikely(!prp_ent)) {
+ trace_pci_nvme_err_invalid_prplist_ent_missing();
return NVME_INVALID_FIELD | NVME_DNR;
}
+ if (unlikely(prp_ent & (n->page_size - 1))) {
+ trace_pci_nvme_err_invalid_prplist_ent(prp_ent);
+ return NVME_INVALID_PRP_OFFSET | NVME_DNR;
+ }
+
if (prp_list_in_cmb != nvme_addr_is_cmb(n, prp_ent)) {
return NVME_INVALID_USE_OF_CMB | NVME_DNR;
}
@@ -391,11 +396,16 @@ static uint16_t nvme_map_prp(NvmeCtrl *n, uint64_t prp1, uint64_t prp2,
prp_ent = le64_to_cpu(prp_list[i]);
}
- if (unlikely(!prp_ent || prp_ent & (n->page_size - 1))) {
- trace_pci_nvme_err_invalid_prplist_ent(prp_ent);
+ if (unlikely(!prp_ent)) {
+ trace_pci_nvme_err_invalid_prplist_ent_missing();
return NVME_INVALID_FIELD | NVME_DNR;
}
+ if (unlikely(prp_ent & (n->page_size - 1))) {
+ trace_pci_nvme_err_invalid_prplist_ent(prp_ent);
+ return NVME_INVALID_PRP_OFFSET | NVME_DNR;
+ }
+
trans_len = MIN(len, n->page_size);
status = nvme_map_addr(n, qsg, iov, prp_ent, trans_len);
if (status) {
@@ -408,7 +418,7 @@ static uint16_t nvme_map_prp(NvmeCtrl *n, uint64_t prp1, uint64_t prp2,
} else {
if (unlikely(prp2 & (n->page_size - 1))) {
trace_pci_nvme_err_invalid_prp2_align(prp2);
- return NVME_INVALID_FIELD | NVME_DNR;
+ return NVME_INVALID_PRP_OFFSET | NVME_DNR;
}
status = nvme_map_addr(n, qsg, iov, prp2, len);
if (status) {
@@ -97,10 +97,11 @@ pci_nvme_err_invalid_sgld(uint16_t cid, uint8_t typ) "cid %"PRIu16" type 0x%"PRI
pci_nvme_err_invalid_num_sgld(uint16_t cid, uint8_t typ) "cid %"PRIu16" type 0x%"PRIx8""
pci_nvme_err_invalid_sgl_excess_length(uint16_t cid) "cid %"PRIu16""
pci_nvme_err_invalid_dma(void) "PRP/SGL is too small for transfer size"
-pci_nvme_err_invalid_prplist_ent(uint64_t prplist) "PRP list entry is null or not page aligned: 0x%"PRIx64""
+pci_nvme_err_invalid_prp1_missing(void) "PRP1 is null"
pci_nvme_err_invalid_prp2_align(uint64_t prp2) "PRP2 is not page aligned: 0x%"PRIx64""
pci_nvme_err_invalid_prp2_missing(void) "PRP2 is null and more data to be transferred"
-pci_nvme_err_invalid_prp(void) "invalid PRP"
+pci_nvme_err_invalid_prplist_ent(uint64_t prplist) "PRP list entry not page aligned: 0x%"PRIx64""
+pci_nvme_err_invalid_prplist_ent_missing(void) "PRP list entry is null and more data to be transferred"
pci_nvme_err_invalid_opc(uint8_t opc) "invalid opcode 0x%"PRIx8""
pci_nvme_err_invalid_admin_opc(uint8_t opc) "invalid admin opcode 0x%"PRIx8""
pci_nvme_err_invalid_lba_range(uint64_t start, uint64_t len, uint64_t limit) "Invalid LBA start=%"PRIu64" len=%"PRIu64" limit=%"PRIu64""