]> xenbits.xensource.com Git - qemu-xen.git/commitdiff
hw/nvme: fix missing endian conversions for doorbell buffers
authorKlaus Jensen <k.jensen@samsung.com>
Mon, 12 Dec 2022 10:30:52 +0000 (11:30 +0100)
committerMichael Tokarev <mjt@tls.msk.ru>
Wed, 29 Mar 2023 07:20:04 +0000 (10:20 +0300)
The eventidx and doorbell value are not handling endianness correctly.
Fix this.

Fixes: 3f7fe8de3d49 ("hw/nvme: Implement shadow doorbell buffer support")
Cc: qemu-stable@nongnu.org
Reported-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
(cherry picked from commit 2fda0726e5149e032acfa5fe442db56cd6433c4c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Conflicts: hw/nvme/ctrl.c

hw/nvme/ctrl.c

index e54276dc1dc7e5baeca48f22b39bad6cfb9929fc..98d8e341099e108d165069ac66c75a4a5f910f17 100644 (file)
@@ -1333,8 +1333,12 @@ static inline void nvme_blk_write(BlockBackend *blk, int64_t offset,
 
 static void nvme_update_cq_head(NvmeCQueue *cq)
 {
-    pci_dma_read(&cq->ctrl->parent_obj, cq->db_addr, &cq->head,
-            sizeof(cq->head));
+    uint32_t v;
+
+    pci_dma_read(&cq->ctrl->parent_obj, cq->db_addr, &v, sizeof(v));
+
+    cq->head = le32_to_cpu(v);
+
     trace_pci_nvme_shadow_doorbell_cq(cq->cqid, cq->head);
 }
 
@@ -6141,15 +6145,21 @@ static uint16_t nvme_admin_cmd(NvmeCtrl *n, NvmeRequest *req)
 
 static void nvme_update_sq_eventidx(const NvmeSQueue *sq)
 {
-    pci_dma_write(&sq->ctrl->parent_obj, sq->ei_addr, &sq->tail,
-                  sizeof(sq->tail));
+    uint32_t v = cpu_to_le32(sq->tail);
+
+    pci_dma_write(&sq->ctrl->parent_obj, sq->ei_addr, &v, sizeof(v));
+
     trace_pci_nvme_eventidx_sq(sq->sqid, sq->tail);
 }
 
 static void nvme_update_sq_tail(NvmeSQueue *sq)
 {
-    pci_dma_read(&sq->ctrl->parent_obj, sq->db_addr, &sq->tail,
-                 sizeof(sq->tail));
+    uint32_t v;
+
+    pci_dma_read(&sq->ctrl->parent_obj, sq->db_addr, &v, sizeof(v));
+
+    sq->tail = le32_to_cpu(v);
+
     trace_pci_nvme_shadow_doorbell_sq(sq->sqid, sq->tail);
 }