[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 09/16] hw/block/nvme: verify validity of prp lists in the cmb
From: |
Klaus Jensen |
Subject: |
[PATCH v2 09/16] hw/block/nvme: verify validity of prp lists in the cmb |
Date: |
Thu, 30 Jul 2020 00:06:31 +0200 |
From: Klaus Jensen <k.jensen@samsung.com>
Before this patch the device already supported PRP lists in the CMB, but
it did not check for the validity of it nor announced the support in the
Identify Controller data structure LISTS field.
If some of the PRPs in a PRP list are in the CMB, then ALL entries must
be there. This patch makes sure that requirement is verified as well as
properly announcing support for PRP lists in the CMB.
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Reviewed-by: Minwoo Im <minwoo.im.dev@gmail.com>
---
hw/block/nvme.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 198a26890e0c..45e4060d52d9 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -273,6 +273,7 @@ static uint16_t nvme_map_prp(QEMUSGList *qsg, QEMUIOVector
*iov, uint64_t prp1,
trans_len = MIN(len, trans_len);
int num_prps = (len >> n->page_bits) + 1;
uint16_t status;
+ bool prp_list_in_cmb = false;
trace_pci_nvme_map_prp(trans_len, len, prp1, prp2, num_prps);
@@ -299,11 +300,16 @@ static uint16_t nvme_map_prp(QEMUSGList *qsg,
QEMUIOVector *iov, uint64_t prp1,
status = NVME_INVALID_FIELD | NVME_DNR;
goto unmap;
}
+
if (len > n->page_size) {
uint64_t prp_list[n->max_prp_ents];
uint32_t nents, prp_trans;
int i = 0;
+ if (nvme_addr_is_cmb(n, prp2)) {
+ prp_list_in_cmb = true;
+ }
+
nents = (len + n->page_size - 1) >> n->page_bits;
prp_trans = MIN(n->max_prp_ents, nents) * sizeof(uint64_t);
nvme_addr_read(n, prp2, (void *)prp_list, prp_trans);
@@ -317,6 +323,11 @@ static uint16_t nvme_map_prp(QEMUSGList *qsg, QEMUIOVector
*iov, uint64_t prp1,
goto unmap;
}
+ if (prp_list_in_cmb != nvme_addr_is_cmb(n, prp_ent)) {
+ status = NVME_INVALID_USE_OF_CMB | NVME_DNR;
+ goto unmap;
+ }
+
i = 0;
nents = (len + n->page_size - 1) >> n->page_bits;
prp_trans = MIN(n->max_prp_ents, nents) * sizeof(uint64_t);
@@ -336,6 +347,7 @@ static uint16_t nvme_map_prp(QEMUSGList *qsg, QEMUIOVector
*iov, uint64_t prp1,
if (status) {
goto unmap;
}
+
len -= trans_len;
i++;
}
@@ -2153,7 +2165,7 @@ static void nvme_init_cmb(NvmeCtrl *n, PCIDevice *pci_dev)
NVME_CMBSZ_SET_SQS(n->bar.cmbsz, 1);
NVME_CMBSZ_SET_CQS(n->bar.cmbsz, 0);
- NVME_CMBSZ_SET_LISTS(n->bar.cmbsz, 0);
+ NVME_CMBSZ_SET_LISTS(n->bar.cmbsz, 1);
NVME_CMBSZ_SET_RDS(n->bar.cmbsz, 1);
NVME_CMBSZ_SET_WDS(n->bar.cmbsz, 1);
NVME_CMBSZ_SET_SZU(n->bar.cmbsz, 2); /* MBs */
--
2.27.0
- [PATCH v2 04/16] hw/block/nvme: remove redundant has_sg member, (continued)
- [PATCH v2 04/16] hw/block/nvme: remove redundant has_sg member, Klaus Jensen, 2020/07/29
- [PATCH v2 06/16] hw/block/nvme: refactor dma read/write, Klaus Jensen, 2020/07/29
- [PATCH v2 10/16] hw/block/nvme: refactor request bounds checking, Klaus Jensen, 2020/07/29
- [PATCH v2 08/16] hw/block/nvme: add request mapping helper, Klaus Jensen, 2020/07/29
- [PATCH v2 07/16] hw/block/nvme: add tracing to nvme_map_prp, Klaus Jensen, 2020/07/29
- [PATCH v2 09/16] hw/block/nvme: verify validity of prp lists in the cmb,
Klaus Jensen <=
- [PATCH v2 12/16] hw/block/nvme: be consistent about zeros vs zeroes, Klaus Jensen, 2020/07/29
- [PATCH v2 11/16] hw/block/nvme: add check for mdts, Klaus Jensen, 2020/07/29
- [PATCH v2 13/16] hw/block/nvme: add ns/cmd references in NvmeRequest, Klaus Jensen, 2020/07/29
- [PATCH v2 15/16] hw/block/nvme: use preallocated qsg/iov in nvme_dma_prp, Klaus Jensen, 2020/07/29
- [PATCH v2 16/16] hw/block/nvme: remove explicit qsg/iov parameters, Klaus Jensen, 2020/07/29
- [PATCH v2 14/16] hw/block/nvme: consolidate qsg/iov clearing, Klaus Jensen, 2020/07/29