mirror of https://github.com/xemu-project/xemu.git
hw/block/nvme: map prp fix if prp2 contains non-zero offset
nvme_map_prp needs to calculate the number of list entries based on the offset value. For the subsequent PRP2 list, need to ensure the number of entries is within the MAX number of PRP entries for a page. Signed-off-by: Padmakar Kalghatgi <p.kalghatgi@samsung.com> Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
This commit is contained in:
parent
a3d9f3a962
commit
d357230b20
|
@ -655,7 +655,12 @@ static uint16_t nvme_map_prp(NvmeCtrl *n, NvmeSg *sg, uint64_t prp1,
|
|||
uint32_t nents, prp_trans;
|
||||
int i = 0;
|
||||
|
||||
nents = (len + n->page_size - 1) >> n->page_bits;
|
||||
/*
|
||||
* The first PRP list entry, pointed to by PRP2 may contain offset.
|
||||
* Hence, we need to calculate the number of entries in based on
|
||||
* that offset.
|
||||
*/
|
||||
nents = (n->page_size - (prp2 & (n->page_size - 1))) >> 3;
|
||||
prp_trans = MIN(n->max_prp_ents, nents) * sizeof(uint64_t);
|
||||
ret = nvme_addr_read(n, prp2, (void *)prp_list, prp_trans);
|
||||
if (ret) {
|
||||
|
@ -666,7 +671,7 @@ static uint16_t nvme_map_prp(NvmeCtrl *n, NvmeSg *sg, uint64_t prp1,
|
|||
while (len != 0) {
|
||||
uint64_t prp_ent = le64_to_cpu(prp_list[i]);
|
||||
|
||||
if (i == n->max_prp_ents - 1 && len > n->page_size) {
|
||||
if (i == nents - 1 && len > n->page_size) {
|
||||
if (unlikely(prp_ent & (n->page_size - 1))) {
|
||||
trace_pci_nvme_err_invalid_prplist_ent(prp_ent);
|
||||
status = NVME_INVALID_PRP_OFFSET | NVME_DNR;
|
||||
|
@ -675,7 +680,8 @@ static uint16_t nvme_map_prp(NvmeCtrl *n, NvmeSg *sg, uint64_t prp1,
|
|||
|
||||
i = 0;
|
||||
nents = (len + n->page_size - 1) >> n->page_bits;
|
||||
prp_trans = MIN(n->max_prp_ents, nents) * sizeof(uint64_t);
|
||||
nents = MIN(nents, n->max_prp_ents);
|
||||
prp_trans = nents * sizeof(uint64_t);
|
||||
ret = nvme_addr_read(n, prp_ent, (void *)prp_list,
|
||||
prp_trans);
|
||||
if (ret) {
|
||||
|
|
Loading…
Reference in New Issue