Skip to content

Commit 04b3fb3

Browse files
committed
block/nvme: don't access CQE after moving cq.head
Do not access a CQE after incrementing q->cq.head and releasing q->lock. It is unlikely that this causes problems in practice but it's a latent bug. The reason why it should be safe at the moment is that completion processing is not re-entrant and the CQ doorbell isn't written until the end of nvme_process_completion(). Make this change now because QEMU expects completion processing to be re-entrant and later patches will do that. Signed-off-by: Stefan Hajnoczi <[email protected]> Reviewed-by: Sergio Lopez <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Message-id: [email protected] Signed-off-by: Stefan Hajnoczi <[email protected]>
1 parent d38253c commit 04b3fb3

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

block/nvme.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,11 +321,14 @@ static bool nvme_process_completion(BDRVNVMeState *s, NVMeQueuePair *q)
321321
q->busy = true;
322322
assert(q->inflight >= 0);
323323
while (q->inflight) {
324+
int ret;
324325
int16_t cid;
326+
325327
c = (NvmeCqe *)&q->cq.queue[q->cq.head * NVME_CQ_ENTRY_BYTES];
326328
if ((le16_to_cpu(c->status) & 0x1) == q->cq_phase) {
327329
break;
328330
}
331+
ret = nvme_translate_error(c);
329332
q->cq.head = (q->cq.head + 1) % NVME_QUEUE_SIZE;
330333
if (!q->cq.head) {
331334
q->cq_phase = !q->cq_phase;
@@ -344,7 +347,7 @@ static bool nvme_process_completion(BDRVNVMeState *s, NVMeQueuePair *q)
344347
preq->busy = false;
345348
preq->cb = preq->opaque = NULL;
346349
qemu_mutex_unlock(&q->lock);
347-
req.cb(req.opaque, nvme_translate_error(c));
350+
req.cb(req.opaque, ret);
348351
qemu_mutex_lock(&q->lock);
349352
q->inflight--;
350353
progress = true;

0 commit comments

Comments
 (0)