Message ID | 20221212114409.34972-5-its@irrelevant.dk |
---|---|
State | New |
Headers | show |
Series | hw/nvme: fix broken shadow doorbells on some platforms | expand |
On Mon, Dec 12, 2022 at 12:44:09PM +0100, Klaus Jensen wrote: > From: Klaus Jensen <k.jensen@samsung.com> > > Prior to reading the shadow doorbell cq head, we have to update the > eventidx. Otherwise, we risk that the driver will skip an mmio doorbell > write. This happens on riscv64, as reported by Guenter. > > Adding the missing update to the cq eventidx fixes the issue. > > Fixes: 3f7fe8de3d49 ("hw/nvme: Implement shadow doorbell buffer support") > Cc: qemu-stable@nongnu.org > Cc: qemu-riscv@nongnu.org > Reported-by: Guenter Roeck <linux@roeck-us.net> > Signed-off-by: Klaus Jensen <k.jensen@samsung.com> Looks good. Reviewed-by: Keith Busch <kbusch@kernel.org>
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index bb505131f5f9..3df29ea68b2f 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -1334,6 +1334,15 @@ static inline void nvme_blk_write(BlockBackend *blk, int64_t offset, } } +static void nvme_update_cq_eventidx(const NvmeCQueue *cq) +{ + uint32_t v = cpu_to_le32(cq->head); + + trace_pci_nvme_update_cq_eventidx(cq->cqid, cq->head); + + pci_dma_write(PCI_DEVICE(cq->ctrl), cq->ei_addr, &v, sizeof(v)); +} + static void nvme_update_cq_head(NvmeCQueue *cq) { uint32_t v; @@ -1358,6 +1367,7 @@ static void nvme_post_cqes(void *opaque) hwaddr addr; if (n->dbbuf_enabled) { + nvme_update_cq_eventidx(cq); nvme_update_cq_head(cq); }