When the identify buffer crosses a page boundary, PRP2 is used
and dma_addr is advanced to the second page:
dma_addr += (page_size - offset);
The subsequent invalidate_dcache_range() calls then use the
modified dma_addr instead of the original buffer start address.
As a result, the beginning of the identify buffer is not
invalidated and the invalidation range extends past the end of
the buffer.
Fix this by preserving the original DMA buffer address for cache
invalidation.
Signed-off-by: Prashant Kamble <[email protected]>
---
drivers/nvme/nvme.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
index 4f9473367d3..298010de536 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -456,6 +456,7 @@ int nvme_identify(struct nvme_dev *dev, unsigned nsid,
u32 page_size = dev->page_size;
int offset = dma_addr & (page_size - 1);
int length = sizeof(struct nvme_id_ctrl);
+ dma_addr_t orig_dma_addr = dma_addr;
int ret;
memset(&c, 0, sizeof(c));
@@ -473,13 +474,13 @@ int nvme_identify(struct nvme_dev *dev, unsigned nsid,
c.identify.cns = cpu_to_le32(cns);
- invalidate_dcache_range(dma_addr,
- dma_addr + sizeof(struct nvme_id_ctrl));
+ invalidate_dcache_range(orig_dma_addr,
+ orig_dma_addr + sizeof(struct nvme_id_ctrl));
ret = nvme_submit_admin_cmd(dev, &c, NULL);
if (!ret)
- invalidate_dcache_range(dma_addr,
- dma_addr + sizeof(struct nvme_id_ctrl));
+ invalidate_dcache_range(orig_dma_addr,
+ orig_dma_addr + sizeof(struct
nvme_id_ctrl));
return ret;
}
--
2.43.0