/*
 * NVMe block driver based on vfio
 *
 * Copyright 2016 - 2018 Red Hat, Inc.
 *
 * Authors:
 *   Fam Zheng <famz@redhat.com>
 *   Paolo Bonzini <pbonzini@redhat.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include <linux/vfio.h>
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qstring.h"
#include "qemu/defer-call.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "qemu/cutils.h"
#include "qemu/option.h"
#include "qemu/memalign.h"
#include "qemu/vfio-helpers.h"
#include "block/block-io.h"
#include "block/block_int.h"
#include "sysemu/block-backend.h"
#include "sysemu/replay.h"
#include "trace.h"

#include "block/nvme.h"

#define NVME_SQ_ENTRY_BYTES 64
#define NVME_CQ_ENTRY_BYTES 16
#define NVME_QUEUE_SIZE 128
#define NVME_DOORBELL_SIZE 4096

/*
 * We have to leave one slot empty as that is the full queue case where
 * head == tail + 1.
 */
#define NVME_NUM_REQS (NVME_QUEUE_SIZE - 1)

typedef struct BDRVNVMeState BDRVNVMeState;

/* Same index is used for queues and IRQs */
#define INDEX_ADMIN     0
#define INDEX_IO(n)     (1 + n)

/* This driver shares a single MSIX IRQ for the admin and I/O queues */
enum {
    MSIX_SHARED_IRQ_IDX = 0,
    MSIX_IRQ_COUNT = 1
};

typedef struct {
    int32_t  head, tail;
    uint8_t  *queue;
    uint64_t iova;
    /* Hardware MMIO register */
    volatile uint32_t *doorbell;
} NVMeQueue;

typedef struct {
    BlockCompletionFunc *cb;
    void *opaque;
    int cid;
    void *prp_list_page;
    uint64_t prp_list_iova;
    int free_req_next; /* q->reqs[] index of next free req */
} NVMeRequest;

typedef struct {
    QemuMutex   lock;

    /* Read from I/O code path, initialized under BQL */
    BDRVNVMeState   *s;
    int             index;

    /* Fields protected by BQL */
    uint8_t     *prp_list_pages;

    /* Fields protected by @lock */
    CoQueue     free_req_queue;
    NVMeQueue   sq, cq;
    int         cq_phase;
    int         free_req_head;
    NVMeRequest reqs[NVME_NUM_REQS];
    int         need_kick;
    int         inflight;

    /* Thread-safe, no lock necessary */
    QEMUBH      *completion_bh;
} NVMeQueuePair;

struct BDRVNVMeState {
    AioContext *aio_context;
    QEMUVFIOState *vfio;
    void *bar0_wo_map;
    /* Memory mapped registers */
    volatile struct {
        uint32_t sq_tail;
        uint32_t cq_head;
    } *doorbells;
    /* The submission/completion queue pairs.
     * [0]: admin queue.
     * [1..]: io queues.
     */
    NVMeQueuePair **queues;
    unsigned queue_count;
    size_t page_size;
    /* How many uint32_t elements does each doorbell entry take. */
    size_t doorbell_scale;
    bool write_cache_supported;
    EventNotifier irq_notifier[MSIX_IRQ_COUNT];

    uint64_t nsze; /* Namespace size reported by identify command */
    int nsid;      /* The namespace id to read/write data. */
    int blkshift;

    uint64_t max_transfer;

    bool supports_write_zeroes;
    bool supports_discard;

    CoMutex dma_map_lock;
    CoQueue dma_flush_queue;

    /* Total size of mapped qiov, accessed under dma_map_lock */
    int dma_map_count;

    /* PCI address (required for nvme_refresh_filename()) */
    char *device;

    struct {
        uint64_t completion_errors;
        uint64_t aligned_accesses;
        uint64_t unaligned_accesses;
    } stats;
};

#define NVME_BLOCK_OPT_DEVICE "device"
#define NVME_BLOCK_OPT_NAMESPACE "namespace"

static void nvme_process_completion_bh(void *opaque);

static QemuOptsList runtime_opts = {
    .name = "nvme",
    .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
    .desc = {
        {
            .name = NVME_BLOCK_OPT_DEVICE,
            .type = QEMU_OPT_STRING,
            .help = "NVMe PCI device address",
        },
        {
            .name = NVME_BLOCK_OPT_NAMESPACE,
            .type = QEMU_OPT_NUMBER,
            .help = "NVMe namespace",
        },
        { /* end of list */ }
    },
};

/* Returns true on success, false on failure. */
static bool nvme_init_queue(BDRVNVMeState *s, NVMeQueue *q,
                            unsigned nentries, size_t entry_bytes, Error **errp)
{
    ERRP_GUARD();
    size_t bytes;
    int r;

    bytes = ROUND_UP(nentries * entry_bytes, qemu_real_host_page_size());
    q->head = q->tail = 0;
    q->queue = qemu_try_memalign(qemu_real_host_page_size(), bytes);
    if (!q->queue) {
        error_setg(errp, "Cannot allocate queue");
        return false;
    }
    memset(q->queue, 0, bytes);
    r = qemu_vfio_dma_map(s->vfio, q->queue, bytes, false, &q->iova, errp);
    if (r) {
        error_prepend(errp, "Cannot map queue: ");
    }
    return r == 0;
}

static void nvme_free_queue(NVMeQueue *q)
{
    qemu_vfree(q->queue);
}

static void nvme_free_queue_pair(NVMeQueuePair *q)
{
    trace_nvme_free_queue_pair(q->index, q, &q->cq, &q->sq);
    if (q->completion_bh) {
        qemu_bh_delete(q->completion_bh);
    }
    nvme_free_queue(&q->sq);
    nvme_free_queue(&q->cq);
    qemu_vfree(q->prp_list_pages);
    qemu_mutex_destroy(&q->lock);
    g_free(q);
}

static void nvme_free_req_queue_cb(void *opaque)
{
    NVMeQueuePair *q = opaque;

    qemu_mutex_lock(&q->lock);
    while (q->free_req_head != -1 &&
           qemu_co_enter_next(&q->free_req_queue, &q->lock)) {
        /* Retry waiting requests */
    }
    qemu_mutex_unlock(&q->lock);
}

static NVMeQueuePair *nvme_create_queue_pair(BDRVNVMeState *s,
                                             AioContext *aio_context,
                                             unsigned idx, size_t size,
                                             Error **errp)
{
    ERRP_GUARD();
    int i, r;
    NVMeQueuePair *q;
    uint64_t prp_list_iova;
    size_t bytes;

    q = g_try_new0(NVMeQueuePair, 1);
    if (!q) {
        error_setg(errp, "Cannot allocate queue pair");
        return NULL;
    }
    trace_nvme_create_queue_pair(idx, q, size, aio_context,
                                 event_notifier_get_fd(s->irq_notifier));
    bytes = QEMU_ALIGN_UP(s->page_size * NVME_NUM_REQS,
                          qemu_real_host_page_size());
    q->prp_list_pages = qemu_try_memalign(qemu_real_host_page_size(), bytes);
    if (!q->prp_list_pages) {
        error_setg(errp, "Cannot allocate PRP page list");
        goto fail;
    }
    memset(q->prp_list_pages, 0, bytes);
    qemu_mutex_init(&q->lock);
    q->s = s;
    q->index = idx;
    qemu_co_queue_init(&q->free_req_queue);
    q->completion_bh = aio_bh_new(aio_context, nvme_process_completion_bh, q);
    r = qemu_vfio_dma_map(s->vfio, q->prp_list_pages, bytes,
                          false, &prp_list_iova, errp);
    if (r) {
        error_prepend(errp, "Cannot map buffer for DMA: ");
        goto fail;
    }
    q->free_req_head = -1;
    for (i = 0; i < NVME_NUM_REQS; i++) {
        NVMeRequest *req = &q->reqs[i];
        req->cid = i + 1;
        req->free_req_next = q->free_req_head;
        q->free_req_head = i;
        req->prp_list_page = q->prp_list_pages + i * s->page_size;
        req->prp_list_iova = prp_list_iova + i * s->page_size;
    }

    if (!nvme_init_queue(s, &q->sq, size, NVME_SQ_ENTRY_BYTES, errp)) {
        goto fail;
    }
    q->sq.doorbell = &s->doorbells[idx * s->doorbell_scale].sq_tail;

    if (!nvme_init_queue(s, &q->cq, size, NVME_CQ_ENTRY_BYTES, errp)) {
        goto fail;
    }
    q->cq.doorbell = &s->doorbells[idx * s->doorbell_scale].cq_head;

    return q;
fail:
    nvme_free_queue_pair(q);
    return NULL;
}

/* With q->lock */
static void nvme_kick(NVMeQueuePair *q)
{
    BDRVNVMeState *s = q->s;

    if (!q->need_kick) {
        return;
    }
    trace_nvme_kick(s, q->index);
    assert(!(q->sq.tail & 0xFF00));
    /* Fence the write to submission queue entry before notifying the device. */
    smp_wmb();
    *q->sq.doorbell = cpu_to_le32(q->sq.tail);
    q->inflight += q->need_kick;
    q->need_kick = 0;
}

static NVMeRequest *nvme_get_free_req_nofail_locked(NVMeQueuePair *q)
{
    NVMeRequest *req;

    req = &q->reqs[q->free_req_head];
    q->free_req_head = req->free_req_next;
    req->free_req_next = -1;
    return req;
}

/* Return a free request element if any, otherwise return NULL.  */
static NVMeRequest *nvme_get_free_req_nowait(NVMeQueuePair *q)
{
    QEMU_LOCK_GUARD(&q->lock);
    if (q->free_req_head == -1) {
        return NULL;
    }
    return nvme_get_free_req_nofail_locked(q);
}

/*
 * Wait for a free request to become available if necessary, then
 * return it.
 */
static coroutine_fn NVMeRequest *nvme_get_free_req(NVMeQueuePair *q)
{
    QEMU_LOCK_GUARD(&q->lock);

    while (q->free_req_head == -1) {
        trace_nvme_free_req_queue_wait(q->s, q->index);
        qemu_co_queue_wait(&q->free_req_queue, &q->lock);
    }

    return nvme_get_free_req_nofail_locked(q);
}

/* With q->lock */
static void nvme_put_free_req_locked(NVMeQueuePair *q, NVMeRequest *req)
{
    req->free_req_next = q->free_req_head;
    q->free_req_head = req - q->reqs;
}

/* With q->lock */
static void nvme_wake_free_req_locked(NVMeQueuePair *q)
{
    if (!qemu_co_queue_empty(&q->free_req_queue)) {
        replay_bh_schedule_oneshot_event(q->s->aio_context,
                nvme_free_req_queue_cb, q);
    }
}

/* Insert a request in the freelist and wake waiters */
static void nvme_put_free_req_and_wake(NVMeQueuePair *q, NVMeRequest *req)
{
    qemu_mutex_lock(&q->lock);
    nvme_put_free_req_locked(q, req);
    nvme_wake_free_req_locked(q);
    qemu_mutex_unlock(&q->lock);
}

static inline int nvme_translate_error(const NvmeCqe *c)
{
    uint16_t status = (le16_to_cpu(c->status) >> 1) & 0xFF;
    if (status) {
        trace_nvme_error(le32_to_cpu(c->result),
                         le16_to_cpu(c->sq_head),
                         le16_to_cpu(c->sq_id),
                         le16_to_cpu(c->cid),
                         le16_to_cpu(status));
    }
    switch (status) {
    case 0:
        return 0;
    case 1:
        return -ENOSYS;
    case 2:
        return -EINVAL;
    default:
        return -EIO;
    }
}

/* With q->lock */
static bool nvme_process_completion(NVMeQueuePair *q)
{
    BDRVNVMeState *s = q->s;
    bool progress = false;
    NVMeRequest *preq;
    NVMeRequest req;
    NvmeCqe *c;

    trace_nvme_process_completion(s, q->index, q->inflight);

    /*
     * Support re-entrancy when a request cb() function invokes aio_poll().
     * Pending completions must be visible to aio_poll() so that a cb()
     * function can wait for the completion of another request.
     *
     * The aio_poll() loop will execute our BH and we'll resume completion
     * processing there.
     */
    qemu_bh_schedule(q->completion_bh);

    assert(q->inflight >= 0);
    while (q->inflight) {
        int ret;
        int16_t cid;

        c = (NvmeCqe *)&q->cq.queue[q->cq.head * NVME_CQ_ENTRY_BYTES];
        if ((le16_to_cpu(c->status) & 0x1) == q->cq_phase) {
            break;
        }
        ret = nvme_translate_error(c);
        if (ret) {
            s->stats.completion_errors++;
        }
        q->cq.head = (q->cq.head + 1) % NVME_QUEUE_SIZE;
        if (!q->cq.head) {
            q->cq_phase = !q->cq_phase;
        }
        cid = le16_to_cpu(c->cid);
        if (cid == 0 || cid > NVME_NUM_REQS) {
            warn_report("NVMe: Unexpected CID in completion queue: %" PRIu32
                        ", should be within: 1..%u inclusively", cid,
                        NVME_NUM_REQS);
            continue;
        }
        trace_nvme_complete_command(s, q->index, cid);
        preq = &q->reqs[cid - 1];
        req = *preq;
        assert(req.cid == cid);
        assert(req.cb);
        nvme_put_free_req_locked(q, preq);
        preq->cb = preq->opaque = NULL;
        q->inflight--;
        qemu_mutex_unlock(&q->lock);
        req.cb(req.opaque, ret);
        qemu_mutex_lock(&q->lock);
        progress = true;
    }
    if (progress) {
        /* Notify the device so it can post more completions. */
        smp_mb_release();
        *q->cq.doorbell = cpu_to_le32(q->cq.head);
        nvme_wake_free_req_locked(q);
    }

    qemu_bh_cancel(q->completion_bh);

    return progress;
}

static void nvme_process_completion_bh(void *opaque)
{
    NVMeQueuePair *q = opaque;

    /*
     * We're being invoked because a nvme_process_completion() cb() function
     * called aio_poll(). The callback may be waiting for further completions
     * so notify the device that it has space to fill in more completions now.
     */
    smp_mb_release();
    *q->cq.doorbell = cpu_to_le32(q->cq.head);
    nvme_wake_free_req_locked(q);

    nvme_process_completion(q);
}

static void nvme_trace_command(const NvmeCmd *cmd)
{
    int i;

    if (!trace_event_get_state_backends(TRACE_NVME_SUBMIT_COMMAND_RAW)) {
        return;
    }
    for (i = 0; i < 8; ++i) {
        uint8_t *cmdp = (uint8_t *)cmd + i * 8;
        trace_nvme_submit_command_raw(cmdp[0], cmdp[1], cmdp[2], cmdp[3],
                                      cmdp[4], cmdp[5], cmdp[6], cmdp[7]);
    }
}

static void nvme_deferred_fn(void *opaque)
{
    NVMeQueuePair *q = opaque;

    QEMU_LOCK_GUARD(&q->lock);
    nvme_kick(q);
    nvme_process_completion(q);
}

static void nvme_submit_command(NVMeQueuePair *q, NVMeRequest *req,
                                NvmeCmd *cmd, BlockCompletionFunc cb,
                                void *opaque)
{
    assert(!req->cb);
    req->cb = cb;
    req->opaque = opaque;
    cmd->cid = cpu_to_le16(req->cid);

    trace_nvme_submit_command(q->s, q->index, req->cid);
    nvme_trace_command(cmd);
    qemu_mutex_lock(&q->lock);
    memcpy((uint8_t *)q->sq.queue +
           q->sq.tail * NVME_SQ_ENTRY_BYTES, cmd, sizeof(*cmd));
    q->sq.tail = (q->sq.tail + 1) % NVME_QUEUE_SIZE;
    q->need_kick++;
    qemu_mutex_unlock(&q->lock);

    defer_call(nvme_deferred_fn, q);
}

static void nvme_admin_cmd_sync_cb(void *opaque, int ret)
{
    int *pret = opaque;
    *pret = ret;
    aio_wait_kick();
}

static int nvme_admin_cmd_sync(BlockDriverState *bs, NvmeCmd *cmd)
{
    BDRVNVMeState *s = bs->opaque;
    NVMeQueuePair *q = s->queues[INDEX_ADMIN];
    AioContext *aio_context = bdrv_get_aio_context(bs);
    NVMeRequest *req;
    int ret = -EINPROGRESS;
    req = nvme_get_free_req_nowait(q);
    if (!req) {
        return -EBUSY;
    }
    nvme_submit_command(q, req, cmd, nvme_admin_cmd_sync_cb, &ret);

    AIO_WAIT_WHILE(aio_context, ret == -EINPROGRESS);
    return ret;
}

/* Returns true on success, false on failure. */
static bool nvme_identify(BlockDriverState *bs, int namespace, Error **errp)
{
    ERRP_GUARD();
    BDRVNVMeState *s = bs->opaque;
    bool ret = false;
    QEMU_AUTO_VFREE union {
        NvmeIdCtrl ctrl;
        NvmeIdNs ns;
    } *id = NULL;
    NvmeLBAF *lbaf;
    uint16_t oncs;
    int r;
    uint64_t iova;
    NvmeCmd cmd = {
        .opcode = NVME_ADM_CMD_IDENTIFY,
        .cdw10 = cpu_to_le32(0x1),
    };
    size_t id_size = QEMU_ALIGN_UP(sizeof(*id), qemu_real_host_page_size());

    id = qemu_try_memalign(qemu_real_host_page_size(), id_size);
    if (!id) {
        error_setg(errp, "Cannot allocate buffer for identify response");
        goto out;
    }
    r = qemu_vfio_dma_map(s->vfio, id, id_size, true, &iova, errp);
    if (r) {
        error_prepend(errp, "Cannot map buffer for DMA: ");
        goto out;
    }

    memset(id, 0, id_size);
    cmd.dptr.prp1 = cpu_to_le64(iova);
    if (nvme_admin_cmd_sync(bs, &cmd)) {
        error_setg(errp, "Failed to identify controller");
        goto out;
    }

    if (le32_to_cpu(id->ctrl.nn) < namespace) {
        error_setg(errp, "Invalid namespace");
        goto out;
    }
    s->write_cache_supported = le32_to_cpu(id->ctrl.vwc) & 0x1;
    s->max_transfer = (id->ctrl.mdts ? 1 << id->ctrl.mdts : 0) * s->page_size;
    /* For now the page list buffer per command is one page, to hold at most
     * s->page_size / sizeof(uint64_t) entries. */
    s->max_transfer = MIN_NON_ZERO(s->max_transfer,
                          s->page_size / sizeof(uint64_t) * s->page_size);

    oncs = le16_to_cpu(id->ctrl.oncs);
    s->supports_write_zeroes = !!(oncs & NVME_ONCS_WRITE_ZEROES);
    s->supports_discard = !!(oncs & NVME_ONCS_DSM);

    memset(id, 0, id_size);
    cmd.cdw10 = 0;
    cmd.nsid = cpu_to_le32(namespace);
    if (nvme_admin_cmd_sync(bs, &cmd)) {
        error_setg(errp, "Failed to identify namespace");
        goto out;
    }

    s->nsze = le64_to_cpu(id->ns.nsze);
    lbaf = &id->ns.lbaf[NVME_ID_NS_FLBAS_INDEX(id->ns.flbas)];

    if (NVME_ID_NS_DLFEAT_WRITE_ZEROES(id->ns.dlfeat) &&
            NVME_ID_NS_DLFEAT_READ_BEHAVIOR(id->ns.dlfeat) ==
                    NVME_ID_NS_DLFEAT_READ_BEHAVIOR_ZEROES) {
        bs->supported_write_flags |= BDRV_REQ_MAY_UNMAP;
    }

    if (lbaf->ms) {
        error_setg(errp, "Namespaces with metadata are not yet supported");
        goto out;
    }

    if (lbaf->ds < BDRV_SECTOR_BITS || lbaf->ds > 12 ||
        (1 << lbaf->ds) > s->page_size)
    {
        error_setg(errp, "Namespace has unsupported block size (2^%d)",
                   lbaf->ds);
        goto out;
    }

    ret = true;
    s->blkshift = lbaf->ds;
out:
    qemu_vfio_dma_unmap(s->vfio, id);

    return ret;
}

static void nvme_poll_queue(NVMeQueuePair *q)
{
    const size_t cqe_offset = q->cq.head * NVME_CQ_ENTRY_BYTES;
    NvmeCqe *cqe = (NvmeCqe *)&q->cq.queue[cqe_offset];

    trace_nvme_poll_queue(q->s, q->index);
    /*
     * Do an early check for completions. q->lock isn't needed because
     * nvme_process_completion() only runs in the event loop thread and
     * cannot race with itself.
     */
    if ((le16_to_cpu(cqe->status) & 0x1) == q->cq_phase) {
        return;
    }

    qemu_mutex_lock(&q->lock);
    while (nvme_process_completion(q)) {
        /* Keep polling */
    }
    qemu_mutex_unlock(&q->lock);
}

static void nvme_poll_queues(BDRVNVMeState *s)
{
    int i;

    for (i = 0; i < s->queue_count; i++) {
        nvme_poll_queue(s->queues[i]);
    }
}

static void nvme_handle_event(EventNotifier *n)
{
    BDRVNVMeState *s = container_of(n, BDRVNVMeState,
                                    irq_notifier[MSIX_SHARED_IRQ_IDX]);

    trace_nvme_handle_event(s);
    event_notifier_test_and_clear(n);
    nvme_poll_queues(s);
}

static bool nvme_add_io_queue(BlockDriverState *bs, Error **errp)
{
    BDRVNVMeState *s = bs->opaque;
    unsigned n = s->queue_count;
    NVMeQueuePair *q;
    NvmeCmd cmd;
    unsigned queue_size = NVME_QUEUE_SIZE;

    assert(n <= UINT16_MAX);
    q = nvme_create_queue_pair(s, bdrv_get_aio_context(bs),
                               n, queue_size, errp);
    if (!q) {
        return false;
    }
    cmd = (NvmeCmd) {
        .opcode = NVME_ADM_CMD_CREATE_CQ,
        .dptr.prp1 = cpu_to_le64(q->cq.iova),
        .cdw10 = cpu_to_le32(((queue_size - 1) << 16) | n),
        .cdw11 = cpu_to_le32(NVME_CQ_IEN | NVME_CQ_PC),
    };
    if (nvme_admin_cmd_sync(bs, &cmd)) {
        error_setg(errp, "Failed to create CQ io queue [%u]", n);
        goto out_error;
    }
    cmd = (NvmeCmd) {
        .opcode = NVME_ADM_CMD_CREATE_SQ,
        .dptr.prp1 = cpu_to_le64(q->sq.iova),
        .cdw10 = cpu_to_le32(((queue_size - 1) << 16) | n),
        .cdw11 = cpu_to_le32(NVME_SQ_PC | (n << 16)),
    };
    if (nvme_admin_cmd_sync(bs, &cmd)) {
        error_setg(errp, "Failed to create SQ io queue [%u]", n);
        goto out_error;
    }
    s->queues = g_renew(NVMeQueuePair *, s->queues, n + 1);
    s->queues[n] = q;
    s->queue_count++;
    return true;
out_error:
    nvme_free_queue_pair(q);
    return false;
}

static bool nvme_poll_cb(void *opaque)
{
    EventNotifier *e = opaque;
    BDRVNVMeState *s = container_of(e, BDRVNVMeState,
                                    irq_notifier[MSIX_SHARED_IRQ_IDX]);
    int i;

    for (i = 0; i < s->queue_count; i++) {
        NVMeQueuePair *q = s->queues[i];
        const size_t cqe_offset = q->cq.head * NVME_CQ_ENTRY_BYTES;
        NvmeCqe *cqe = (NvmeCqe *)&q->cq.queue[cqe_offset];

        /*
         * q->lock isn't needed because nvme_process_completion() only runs in
         * the event loop thread and cannot race with itself.
         */
        if ((le16_to_cpu(cqe->status) & 0x1) != q->cq_phase) {
            return true;
        }
    }
    return false;
}

static void nvme_poll_ready(EventNotifier *e)
{
    BDRVNVMeState *s = container_of(e, BDRVNVMeState,
                                    irq_notifier[MSIX_SHARED_IRQ_IDX]);

    nvme_poll_queues(s);
}

static int nvme_init(BlockDriverState *bs, const char *device, int namespace,
                     Error **errp)
{
    BDRVNVMeState *s = bs->opaque;
    NVMeQueuePair *q;
    AioContext *aio_context = bdrv_get_aio_context(bs);
    int ret;
    uint64_t cap;
    uint32_t ver;
    uint64_t timeout_ms;
    uint64_t deadline, now;
    volatile NvmeBar *regs = NULL;

    qemu_co_mutex_init(&s->dma_map_lock);
    qemu_co_queue_init(&s->dma_flush_queue);
    s->device = g_strdup(device);
    s->nsid = namespace;
    s->aio_context = bdrv_get_aio_context(bs);
    ret = event_notifier_init(&s->irq_notifier[MSIX_SHARED_IRQ_IDX], 0);
    if (ret) {
        error_setg(errp, "Failed to init event notifier");
        return ret;
    }

    s->vfio = qemu_vfio_open_pci(device, errp);
    if (!s->vfio) {
        ret = -EINVAL;
        goto out;
    }

    regs = qemu_vfio_pci_map_bar(s->vfio, 0, 0, sizeof(NvmeBar),
                                 PROT_READ | PROT_WRITE, errp);
    if (!regs) {
        ret = -EINVAL;
        goto out;
    }
    /* Perform initialize sequence as described in NVMe spec "7.6.1
     * Initialization". */

    cap = le64_to_cpu(regs->cap);
    trace_nvme_controller_capability_raw(cap);
    trace_nvme_controller_capability("Maximum Queue Entries Supported",
                                     1 + NVME_CAP_MQES(cap));
    trace_nvme_controller_capability("Contiguous Queues Required",
                                     NVME_CAP_CQR(cap));
    trace_nvme_controller_capability("Doorbell Stride",
                                     1 << (2 + NVME_CAP_DSTRD(cap)));
    trace_nvme_controller_capability("Subsystem Reset Supported",
                                     NVME_CAP_NSSRS(cap));
    trace_nvme_controller_capability("Memory Page Size Minimum",
                                     1 << (12 + NVME_CAP_MPSMIN(cap)));
    trace_nvme_controller_capability("Memory Page Size Maximum",
                                     1 << (12 + NVME_CAP_MPSMAX(cap)));
    if (!NVME_CAP_CSS(cap)) {
        error_setg(errp, "Device doesn't support NVMe command set");
        ret = -EINVAL;
        goto out;
    }

    s->page_size = 1u << (12 + NVME_CAP_MPSMIN(cap));
    s->doorbell_scale = (4 << NVME_CAP_DSTRD(cap)) / sizeof(uint32_t);
    bs->bl.opt_mem_alignment = s->page_size;
    bs->bl.request_alignment = s->page_size;
    timeout_ms = MIN(500 * NVME_CAP_TO(cap), 30000);

    ver = le32_to_cpu(regs->vs);
    trace_nvme_controller_spec_version(extract32(ver, 16, 16),
                                       extract32(ver, 8, 8),
                                       extract32(ver, 0, 8));

    /* Reset device to get a clean state. */
    regs->cc = cpu_to_le32(le32_to_cpu(regs->cc) & 0xFE);
    /* Wait for CSTS.RDY = 0. */
    deadline = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + timeout_ms * SCALE_MS;
    while (NVME_CSTS_RDY(le32_to_cpu(regs->csts))) {
        if (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) > deadline) {
            error_setg(errp, "Timeout while waiting for device to reset (%"
                             PRId64 " ms)",
                       timeout_ms);
            ret = -ETIMEDOUT;
            goto out;
        }
    }

    s->bar0_wo_map = qemu_vfio_pci_map_bar(s->vfio, 0, 0,
                                           sizeof(NvmeBar) + NVME_DOORBELL_SIZE,
                                           PROT_WRITE, errp);
    s->doorbells = (void *)((uintptr_t)s->bar0_wo_map + sizeof(NvmeBar));
    if (!s->doorbells) {
        ret = -EINVAL;
        goto out;
    }

    /* Set up admin queue. */
    s->queues = g_new(NVMeQueuePair *, 1);
    q = nvme_create_queue_pair(s, aio_context, 0, NVME_QUEUE_SIZE, errp);
    if (!q) {
        ret = -EINVAL;
        goto out;
    }
    s->queues[INDEX_ADMIN] = q;
    s->queue_count = 1;
    QEMU_BUILD_BUG_ON((NVME_QUEUE_SIZE - 1) & 0xF000);
    regs->aqa = cpu_to_le32(((NVME_QUEUE_SIZE - 1) << AQA_ACQS_SHIFT) |
                            ((NVME_QUEUE_SIZE - 1) << AQA_ASQS_SHIFT));
    regs->asq = cpu_to_le64(q->sq.iova);
    regs->acq = cpu_to_le64(q->cq.iova);

    /* After setting up all control registers we can enable device now. */
    regs->cc = cpu_to_le32((ctz32(NVME_CQ_ENTRY_BYTES) << CC_IOCQES_SHIFT) |
                           (ctz32(NVME_SQ_ENTRY_BYTES) << CC_IOSQES_SHIFT) |
                           CC_EN_MASK);
    /* Wait for CSTS.RDY = 1. */
    now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
    deadline = now + timeout_ms * SCALE_MS;
    while (!NVME_CSTS_RDY(le32_to_cpu(regs->csts))) {
        if (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) > deadline) {
            error_setg(errp, "Timeout while waiting for device to start (%"
                             PRId64 " ms)",
                       timeout_ms);
            ret = -ETIMEDOUT;
            goto out;
        }
    }

    ret = qemu_vfio_pci_init_irq(s->vfio, s->irq_notifier,
                                 VFIO_PCI_MSIX_IRQ_INDEX, errp);
    if (ret) {
        goto out;
    }
    aio_set_event_notifier(bdrv_get_aio_context(bs),
                           &s->irq_notifier[MSIX_SHARED_IRQ_IDX],
                           nvme_handle_event, nvme_poll_cb,
                           nvme_poll_ready);

    if (!nvme_identify(bs, namespace, errp)) {
        ret = -EIO;
        goto out;
    }

    /* Set up command queues. */
    if (!nvme_add_io_queue(bs, errp)) {
        ret = -EIO;
    }
out:
    if (regs) {
        qemu_vfio_pci_unmap_bar(s->vfio, 0, (void *)regs, 0, sizeof(NvmeBar));
    }

    /* Cleaning up is done in nvme_file_open() upon error. */
    return ret;
}

/* Parse a filename in the format of nvme://XXXX:XX:XX.X/X. Example:
 *
 *     nvme://0000:44:00.0/1
 *
 * where the "nvme://" is a fixed form of the protocol prefix, the middle part
 * is the PCI address, and the last part is the namespace number starting from
 * 1 according to the NVMe spec. */
static void nvme_parse_filename(const char *filename, QDict *options,
                                Error **errp)
{
    int pref = strlen("nvme://");

    if (strlen(filename) > pref && !strncmp(filename, "nvme://", pref)) {
        const char *tmp = filename + pref;
        char *device;
        const char *namespace;
        unsigned long ns;
        const char *slash = strchr(tmp, '/');
        if (!slash) {
            qdict_put_str(options, NVME_BLOCK_OPT_DEVICE, tmp);
            return;
        }
        device = g_strndup(tmp, slash - tmp);
        qdict_put_str(options, NVME_BLOCK_OPT_DEVICE, device);
        g_free(device);
        namespace = slash + 1;
        if (*namespace && qemu_strtoul(namespace, NULL, 10, &ns)) {
            error_setg(errp, "Invalid namespace '%s', positive number expected",
                       namespace);
            return;
        }
        qdict_put_str(options, NVME_BLOCK_OPT_NAMESPACE,
                      *namespace ? namespace : "1");
    }
}

static int nvme_enable_disable_write_cache(BlockDriverState *bs, bool enable,
                                           Error **errp)
{
    int ret;
    BDRVNVMeState *s = bs->opaque;
    NvmeCmd cmd = {
        .opcode = NVME_ADM_CMD_SET_FEATURES,
        .nsid = cpu_to_le32(s->nsid),
        .cdw10 = cpu_to_le32(0x06),
        .cdw11 = cpu_to_le32(enable ? 0x01 : 0x00),
    };

    ret = nvme_admin_cmd_sync(bs, &cmd);
    if (ret) {
        error_setg(errp, "Failed to configure NVMe write cache");
    }
    return ret;
}

static void nvme_close(BlockDriverState *bs)
{
    BDRVNVMeState *s = bs->opaque;

    for (unsigned i = 0; i < s->queue_count; ++i) {
        nvme_free_queue_pair(s->queues[i]);
    }
    g_free(s->queues);
    aio_set_event_notifier(bdrv_get_aio_context(bs),
                           &s->irq_notifier[MSIX_SHARED_IRQ_IDX],
                           NULL, NULL, NULL);
    event_notifier_cleanup(&s->irq_notifier[MSIX_SHARED_IRQ_IDX]);
    qemu_vfio_pci_unmap_bar(s->vfio, 0, s->bar0_wo_map,
                            0, sizeof(NvmeBar) + NVME_DOORBELL_SIZE);
    qemu_vfio_close(s->vfio);

    g_free(s->device);
}

static int nvme_file_open(BlockDriverState *bs, QDict *options, int flags,
                          Error **errp)
{
    const char *device;
    QemuOpts *opts;
    int namespace;
    int ret;
    BDRVNVMeState *s = bs->opaque;

    bs->supported_write_flags = BDRV_REQ_FUA;

    opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
    qemu_opts_absorb_qdict(opts, options, &error_abort);
    device = qemu_opt_get(opts, NVME_BLOCK_OPT_DEVICE);
    if (!device) {
        error_setg(errp, "'" NVME_BLOCK_OPT_DEVICE "' option is required");
        qemu_opts_del(opts);
        return -EINVAL;
    }

    namespace = qemu_opt_get_number(opts, NVME_BLOCK_OPT_NAMESPACE, 1);
    ret = nvme_init(bs, device, namespace, errp);
    qemu_opts_del(opts);
    if (ret) {
        goto fail;
    }
    if (flags & BDRV_O_NOCACHE) {
        if (!s->write_cache_supported) {
            error_setg(errp,
                       "NVMe controller doesn't support write cache configuration");
            ret = -EINVAL;
        } else {
            ret = nvme_enable_disable_write_cache(bs, !(flags & BDRV_O_NOCACHE),
                                                  errp);
        }
        if (ret) {
            goto fail;
        }
    }
    return 0;
fail:
    nvme_close(bs);
    return ret;
}

static int64_t coroutine_fn nvme_co_getlength(BlockDriverState *bs)
{
    BDRVNVMeState *s = bs->opaque;
    return s->nsze << s->blkshift;
}

static uint32_t nvme_get_blocksize(BlockDriverState *bs)
{
    BDRVNVMeState *s = bs->opaque;
    assert(s->blkshift >= BDRV_SECTOR_BITS && s->blkshift <= 12);
    return UINT32_C(1) << s->blkshift;
}

static int nvme_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz)
{
    uint32_t blocksize = nvme_get_blocksize(bs);
    bsz->phys = blocksize;
    bsz->log = blocksize;
    return 0;
}

/* Called with s->dma_map_lock */
static coroutine_fn int nvme_cmd_unmap_qiov(BlockDriverState *bs,
                                            QEMUIOVector *qiov)
{
    int r = 0;
    BDRVNVMeState *s = bs->opaque;

    s->dma_map_count -= qiov->size;
    if (!s->dma_map_count && !qemu_co_queue_empty(&s->dma_flush_queue)) {
        r = qemu_vfio_dma_reset_temporary(s->vfio);
        if (!r) {
            qemu_co_queue_restart_all(&s->dma_flush_queue);
        }
    }
    return r;
}

/* Called with s->dma_map_lock */
static coroutine_fn int nvme_cmd_map_qiov(BlockDriverState *bs, NvmeCmd *cmd,
                                          NVMeRequest *req, QEMUIOVector *qiov)
{
    BDRVNVMeState *s = bs->opaque;
    uint64_t *pagelist = req->prp_list_page;
    int i, j, r;
    int entries = 0;
    Error *local_err = NULL, **errp = NULL;

    assert(qiov->size);
    assert(QEMU_IS_ALIGNED(qiov->size, s->page_size));
    assert(qiov->size / s->page_size <= s->page_size / sizeof(uint64_t));
    for (i = 0; i < qiov->niov; ++i) {
        bool retry = true;
        uint64_t iova;
        size_t len = QEMU_ALIGN_UP(qiov->iov[i].iov_len,
                                   qemu_real_host_page_size());
try_map:
        r = qemu_vfio_dma_map(s->vfio,
                              qiov->iov[i].iov_base,
                              len, true, &iova, errp);
        if (r == -ENOSPC) {
            /*
             * In addition to the -ENOMEM error, the VFIO_IOMMU_MAP_DMA
             * ioctl returns -ENOSPC to signal the user exhausted the DMA
             * mappings available for a container since Linux kernel commit
             * 492855939bdb ("vfio/type1: Limit DMA mappings per container",
             * April 2019, see CVE-2019-3882).
             *
             * This block driver already handles this error path by checking
             * for the -ENOMEM error, so we directly replace -ENOSPC by
             * -ENOMEM. Beside, -ENOSPC has a specific meaning for blockdev
             * coroutines: it triggers BLOCKDEV_ON_ERROR_ENOSPC and
             * BLOCK_ERROR_ACTION_STOP which stops the VM, asking the operator
             * to add more storage to the blockdev. Not something we can do
             * easily with an IOMMU :)
             */
            r = -ENOMEM;
        }
        if (r == -ENOMEM && retry) {
            /*
             * We exhausted the DMA mappings available for our container:
             * recycle the volatile IOVA mappings.
             */
            retry = false;
            trace_nvme_dma_flush_queue_wait(s);
            if (s->dma_map_count) {
                trace_nvme_dma_map_flush(s);
                qemu_co_queue_wait(&s->dma_flush_queue, &s->dma_map_lock);
            } else {
                r = qemu_vfio_dma_reset_temporary(s->vfio);
                if (r) {
                    goto fail;
                }
            }
            errp = &local_err;

            goto try_map;
        }
        if (r) {
            goto fail;
        }

        for (j = 0; j < qiov->iov[i].iov_len / s->page_size; j++) {
            pagelist[entries++] = cpu_to_le64(iova + j * s->page_size);
        }
        trace_nvme_cmd_map_qiov_iov(s, i, qiov->iov[i].iov_base,
                                    qiov->iov[i].iov_len / s->page_size);
    }

    s->dma_map_count += qiov->size;

    assert(entries <= s->page_size / sizeof(uint64_t));
    switch (entries) {
    case 0:
        abort();
    case 1:
        cmd->dptr.prp1 = pagelist[0];
        cmd->dptr.prp2 = 0;
        break;
    case 2:
        cmd->dptr.prp1 = pagelist[0];
        cmd->dptr.prp2 = pagelist[1];
        break;
    default:
        cmd->dptr.prp1 = pagelist[0];
        cmd->dptr.prp2 = cpu_to_le64(req->prp_list_iova + sizeof(uint64_t));
        break;
    }
    trace_nvme_cmd_map_qiov(s, cmd, req, qiov, entries);
    for (i = 0; i < entries; ++i) {
        trace_nvme_cmd_map_qiov_pages(s, i, pagelist[i]);
    }
    return 0;
fail:
    /* No need to unmap [0 - i) iovs even if we've failed, since we don't
     * increment s->dma_map_count. This is okay for fixed mapping memory areas
     * because they are already mapped before calling this function; for
     * temporary mappings, a later nvme_cmd_(un)map_qiov will reclaim by
     * calling qemu_vfio_dma_reset_temporary when necessary. */
    if (local_err) {
        error_reportf_err(local_err, "Cannot map buffer for DMA: ");
    }
    return r;
}

typedef struct {
    Coroutine *co;
    int ret;
    AioContext *ctx;
} NVMeCoData;

static void nvme_rw_cb_bh(void *opaque)
{
    NVMeCoData *data = opaque;
    qemu_coroutine_enter(data->co);
}

static void nvme_rw_cb(void *opaque, int ret)
{
    NVMeCoData *data = opaque;
    data->ret = ret;
    if (!data->co) {
        /* The rw coroutine hasn't yielded, don't try to enter. */
        return;
    }
    replay_bh_schedule_oneshot_event(data->ctx, nvme_rw_cb_bh, data);
}

static coroutine_fn int nvme_co_prw_aligned(BlockDriverState *bs,
                                            uint64_t offset, uint64_t bytes,
                                            QEMUIOVector *qiov,
                                            bool is_write,
                                            int flags)
{
    int r;
    BDRVNVMeState *s = bs->opaque;
    NVMeQueuePair *ioq = s->queues[INDEX_IO(0)];
    NVMeRequest *req;

    uint32_t cdw12 = (((bytes >> s->blkshift) - 1) & 0xFFFF) |
                       (flags & BDRV_REQ_FUA ? 1 << 30 : 0);
    NvmeCmd cmd = {
        .opcode = is_write ? NVME_CMD_WRITE : NVME_CMD_READ,
        .nsid = cpu_to_le32(s->nsid),
        .cdw10 = cpu_to_le32((offset >> s->blkshift) & 0xFFFFFFFF),
        .cdw11 = cpu_to_le32(((offset >> s->blkshift) >> 32) & 0xFFFFFFFF),
        .cdw12 = cpu_to_le32(cdw12),
    };
    NVMeCoData data = {
        .ctx = bdrv_get_aio_context(bs),
        .ret = -EINPROGRESS,
    };

    trace_nvme_prw_aligned(s, is_write, offset, bytes, flags, qiov->niov);
    assert(s->queue_count > 1);
    req = nvme_get_free_req(ioq);
    assert(req);

    qemu_co_mutex_lock(&s->dma_map_lock);
    r = nvme_cmd_map_qiov(bs, &cmd, req, qiov);
    qemu_co_mutex_unlock(&s->dma_map_lock);
    if (r) {
        nvme_put_free_req_and_wake(ioq, req);
        return r;
    }
    nvme_submit_command(ioq, req, &cmd, nvme_rw_cb, &data);

    data.co = qemu_coroutine_self();
    while (data.ret == -EINPROGRESS) {
        qemu_coroutine_yield();
    }

    qemu_co_mutex_lock(&s->dma_map_lock);
    r = nvme_cmd_unmap_qiov(bs, qiov);
    qemu_co_mutex_unlock(&s->dma_map_lock);
    if (r) {
        return r;
    }

    trace_nvme_rw_done(s, is_write, offset, bytes, data.ret);
    return data.ret;
}

static inline bool nvme_qiov_aligned(BlockDriverState *bs,
                                     const QEMUIOVector *qiov)
{
    int i;
    BDRVNVMeState *s = bs->opaque;

    for (i = 0; i < qiov->niov; ++i) {
        if (!QEMU_PTR_IS_ALIGNED(qiov->iov[i].iov_base,
                                 qemu_real_host_page_size()) ||
            !QEMU_IS_ALIGNED(qiov->iov[i].iov_len, qemu_real_host_page_size())) {
            trace_nvme_qiov_unaligned(qiov, i, qiov->iov[i].iov_base,
                                      qiov->iov[i].iov_len, s->page_size);
            return false;
        }
    }
    return true;
}

static coroutine_fn int nvme_co_prw(BlockDriverState *bs,
                                    uint64_t offset, uint64_t bytes,
                                    QEMUIOVector *qiov, bool is_write,
                                    int flags)
{
    BDRVNVMeState *s = bs->opaque;
    int r;
    QEMU_AUTO_VFREE uint8_t *buf = NULL;
    QEMUIOVector local_qiov;
    size_t len = QEMU_ALIGN_UP(bytes, qemu_real_host_page_size());
    assert(QEMU_IS_ALIGNED(offset, s->page_size));
    assert(QEMU_IS_ALIGNED(bytes, s->page_size));
    assert(bytes <= s->max_transfer);
    if (nvme_qiov_aligned(bs, qiov)) {
        s->stats.aligned_accesses++;
        return nvme_co_prw_aligned(bs, offset, bytes, qiov, is_write, flags);
    }
    s->stats.unaligned_accesses++;
    trace_nvme_prw_buffered(s, offset, bytes, qiov->niov, is_write);
    buf = qemu_try_memalign(qemu_real_host_page_size(), len);

    if (!buf) {
        return -ENOMEM;
    }
    qemu_iovec_init(&local_qiov, 1);
    if (is_write) {
        qemu_iovec_to_buf(qiov, 0, buf, bytes);
    }
    qemu_iovec_add(&local_qiov, buf, bytes);
    r = nvme_co_prw_aligned(bs, offset, bytes, &local_qiov, is_write, flags);
    qemu_iovec_destroy(&local_qiov);
    if (!r && !is_write) {
        qemu_iovec_from_buf(qiov, 0, buf, bytes);
    }
    return r;
}

static coroutine_fn int nvme_co_preadv(BlockDriverState *bs,
                                       int64_t offset, int64_t bytes,
                                       QEMUIOVector *qiov,
                                       BdrvRequestFlags flags)
{
    return nvme_co_prw(bs, offset, bytes, qiov, false, flags);
}

static coroutine_fn int nvme_co_pwritev(BlockDriverState *bs,
                                        int64_t offset, int64_t bytes,
                                        QEMUIOVector *qiov,
                                        BdrvRequestFlags flags)
{
    return nvme_co_prw(bs, offset, bytes, qiov, true, flags);
}

static coroutine_fn int nvme_co_flush(BlockDriverState *bs)
{
    BDRVNVMeState *s = bs->opaque;
    NVMeQueuePair *ioq = s->queues[INDEX_IO(0)];
    NVMeRequest *req;
    NvmeCmd cmd = {
        .opcode = NVME_CMD_FLUSH,
        .nsid = cpu_to_le32(s->nsid),
    };
    NVMeCoData data = {
        .ctx = bdrv_get_aio_context(bs),
        .ret = -EINPROGRESS,
    };

    assert(s->queue_count > 1);
    req = nvme_get_free_req(ioq);
    assert(req);
    nvme_submit_command(ioq, req, &cmd, nvme_rw_cb, &data);

    data.co = qemu_coroutine_self();
    if (data.ret == -EINPROGRESS) {
        qemu_coroutine_yield();
    }

    return data.ret;
}


static coroutine_fn int nvme_co_pwrite_zeroes(BlockDriverState *bs,
                                              int64_t offset,
                                              int64_t bytes,
                                              BdrvRequestFlags flags)
{
    BDRVNVMeState *s = bs->opaque;
    NVMeQueuePair *ioq = s->queues[INDEX_IO(0)];
    NVMeRequest *req;
    uint32_t cdw12;

    if (!s->supports_write_zeroes) {
        return -ENOTSUP;
    }

    if (bytes == 0) {
        return 0;
    }

    cdw12 = ((bytes >> s->blkshift) - 1) & 0xFFFF;
    /*
     * We should not lose information. pwrite_zeroes_alignment and
     * max_pwrite_zeroes guarantees it.
     */
    assert(((cdw12 + 1) << s->blkshift) == bytes);

    NvmeCmd cmd = {
        .opcode = NVME_CMD_WRITE_ZEROES,
        .nsid = cpu_to_le32(s->nsid),
        .cdw10 = cpu_to_le32((offset >> s->blkshift) & 0xFFFFFFFF),
        .cdw11 = cpu_to_le32(((offset >> s->blkshift) >> 32) & 0xFFFFFFFF),
    };

    NVMeCoData data = {
        .ctx = bdrv_get_aio_context(bs),
        .ret = -EINPROGRESS,
    };

    if (flags & BDRV_REQ_MAY_UNMAP) {
        cdw12 |= (1 << 25);
    }

    if (flags & BDRV_REQ_FUA) {
        cdw12 |= (1 << 30);
    }

    cmd.cdw12 = cpu_to_le32(cdw12);

    trace_nvme_write_zeroes(s, offset, bytes, flags);
    assert(s->queue_count > 1);
    req = nvme_get_free_req(ioq);
    assert(req);

    nvme_submit_command(ioq, req, &cmd, nvme_rw_cb, &data);

    data.co = qemu_coroutine_self();
    while (data.ret == -EINPROGRESS) {
        qemu_coroutine_yield();
    }

    trace_nvme_rw_done(s, true, offset, bytes, data.ret);
    return data.ret;
}


static int coroutine_fn nvme_co_pdiscard(BlockDriverState *bs,
                                         int64_t offset,
                                         int64_t bytes)
{
    BDRVNVMeState *s = bs->opaque;
    NVMeQueuePair *ioq = s->queues[INDEX_IO(0)];
    NVMeRequest *req;
    QEMU_AUTO_VFREE NvmeDsmRange *buf = NULL;
    QEMUIOVector local_qiov;
    int ret;

    NvmeCmd cmd = {
        .opcode = NVME_CMD_DSM,
        .nsid = cpu_to_le32(s->nsid),
        .cdw10 = cpu_to_le32(0), /*number of ranges - 0 based*/
        .cdw11 = cpu_to_le32(1 << 2), /*deallocate bit*/
    };

    NVMeCoData data = {
        .ctx = bdrv_get_aio_context(bs),
        .ret = -EINPROGRESS,
    };

    if (!s->supports_discard) {
        return -ENOTSUP;
    }

    assert(s->queue_count > 1);

    /*
     * Filling the @buf requires @offset and @bytes to satisfy restrictions
     * defined in nvme_refresh_limits().
     */
    assert(QEMU_IS_ALIGNED(bytes, 1UL << s->blkshift));
    assert(QEMU_IS_ALIGNED(offset, 1UL << s->blkshift));
    assert((bytes >> s->blkshift) <= UINT32_MAX);

    buf = qemu_try_memalign(s->page_size, s->page_size);
    if (!buf) {
        return -ENOMEM;
    }
    memset(buf, 0, s->page_size);
    buf->nlb = cpu_to_le32(bytes >> s->blkshift);
    buf->slba = cpu_to_le64(offset >> s->blkshift);
    buf->cattr = 0;

    qemu_iovec_init(&local_qiov, 1);
    qemu_iovec_add(&local_qiov, buf, 4096);

    req = nvme_get_free_req(ioq);
    assert(req);

    qemu_co_mutex_lock(&s->dma_map_lock);
    ret = nvme_cmd_map_qiov(bs, &cmd, req, &local_qiov);
    qemu_co_mutex_unlock(&s->dma_map_lock);

    if (ret) {
        nvme_put_free_req_and_wake(ioq, req);
        goto out;
    }

    trace_nvme_dsm(s, offset, bytes);

    nvme_submit_command(ioq, req, &cmd, nvme_rw_cb, &data);

    data.co = qemu_coroutine_self();
    while (data.ret == -EINPROGRESS) {
        qemu_coroutine_yield();
    }

    qemu_co_mutex_lock(&s->dma_map_lock);
    ret = nvme_cmd_unmap_qiov(bs, &local_qiov);
    qemu_co_mutex_unlock(&s->dma_map_lock);

    if (ret) {
        goto out;
    }

    ret = data.ret;
    trace_nvme_dsm_done(s, offset, bytes, ret);
out:
    qemu_iovec_destroy(&local_qiov);
    return ret;

}

static int coroutine_fn nvme_co_truncate(BlockDriverState *bs, int64_t offset,
                                         bool exact, PreallocMode prealloc,
                                         BdrvRequestFlags flags, Error **errp)
{
    int64_t cur_length;

    if (prealloc != PREALLOC_MODE_OFF) {
        error_setg(errp, "Unsupported preallocation mode '%s'",
                   PreallocMode_str(prealloc));
        return -ENOTSUP;
    }

    cur_length = nvme_co_getlength(bs);
    if (offset != cur_length && exact) {
        error_setg(errp, "Cannot resize NVMe devices");
        return -ENOTSUP;
    } else if (offset > cur_length) {
        error_setg(errp, "Cannot grow NVMe devices");
        return -EINVAL;
    }

    return 0;
}

static int nvme_reopen_prepare(BDRVReopenState *reopen_state,
                               BlockReopenQueue *queue, Error **errp)
{
    return 0;
}

static void nvme_refresh_filename(BlockDriverState *bs)
{
    BDRVNVMeState *s = bs->opaque;

    snprintf(bs->exact_filename, sizeof(bs->exact_filename), "nvme://%s/%i",
             s->device, s->nsid);
}

static void nvme_refresh_limits(BlockDriverState *bs, Error **errp)
{
    BDRVNVMeState *s = bs->opaque;

    bs->bl.opt_mem_alignment = s->page_size;
    bs->bl.request_alignment = s->page_size;
    bs->bl.max_transfer = s->max_transfer;

    /*
     * Look at nvme_co_pwrite_zeroes: after shift and decrement we should get
     * at most 0xFFFF
     */
    bs->bl.max_pwrite_zeroes = 1ULL << (s->blkshift + 16);
    bs->bl.pwrite_zeroes_alignment = MAX(bs->bl.request_alignment,
                                         1UL << s->blkshift);

    bs->bl.max_pdiscard = (uint64_t)UINT32_MAX << s->blkshift;
    bs->bl.pdiscard_alignment = MAX(bs->bl.request_alignment,
                                    1UL << s->blkshift);
}

static void nvme_detach_aio_context(BlockDriverState *bs)
{
    BDRVNVMeState *s = bs->opaque;

    for (unsigned i = 0; i < s->queue_count; i++) {
        NVMeQueuePair *q = s->queues[i];

        qemu_bh_delete(q->completion_bh);
        q->completion_bh = NULL;
    }

    aio_set_event_notifier(bdrv_get_aio_context(bs),
                           &s->irq_notifier[MSIX_SHARED_IRQ_IDX],
                           NULL, NULL, NULL);
}

static void nvme_attach_aio_context(BlockDriverState *bs,
                                    AioContext *new_context)
{
    BDRVNVMeState *s = bs->opaque;

    s->aio_context = new_context;
    aio_set_event_notifier(new_context, &s->irq_notifier[MSIX_SHARED_IRQ_IDX],
                           nvme_handle_event, nvme_poll_cb,
                           nvme_poll_ready);

    for (unsigned i = 0; i < s->queue_count; i++) {
        NVMeQueuePair *q = s->queues[i];

        q->completion_bh =
            aio_bh_new(new_context, nvme_process_completion_bh, q);
    }
}

static bool nvme_register_buf(BlockDriverState *bs, void *host, size_t size,
                              Error **errp)
{
    int ret;
    BDRVNVMeState *s = bs->opaque;

    /*
     * FIXME: we may run out of IOVA addresses after repeated
     * bdrv_register_buf/bdrv_unregister_buf, because nvme_vfio_dma_unmap
     * doesn't reclaim addresses for fixed mappings.
     */
    ret = qemu_vfio_dma_map(s->vfio, host, size, false, NULL, errp);
    return ret == 0;
}

static void nvme_unregister_buf(BlockDriverState *bs, void *host, size_t size)
{
    BDRVNVMeState *s = bs->opaque;

    qemu_vfio_dma_unmap(s->vfio, host);
}

static BlockStatsSpecific *nvme_get_specific_stats(BlockDriverState *bs)
{
    BlockStatsSpecific *stats = g_new(BlockStatsSpecific, 1);
    BDRVNVMeState *s = bs->opaque;

    stats->driver = BLOCKDEV_DRIVER_NVME;
    stats->u.nvme = (BlockStatsSpecificNvme) {
        .completion_errors = s->stats.completion_errors,
        .aligned_accesses = s->stats.aligned_accesses,
        .unaligned_accesses = s->stats.unaligned_accesses,
    };

    return stats;
}

static const char *const nvme_strong_runtime_opts[] = {
    NVME_BLOCK_OPT_DEVICE,
    NVME_BLOCK_OPT_NAMESPACE,

    NULL
};

static BlockDriver bdrv_nvme = {
    .format_name              = "nvme",
    .protocol_name            = "nvme",
    .instance_size            = sizeof(BDRVNVMeState),

    .bdrv_co_create_opts      = bdrv_co_create_opts_simple,
    .create_opts              = &bdrv_create_opts_simple,

    .bdrv_parse_filename      = nvme_parse_filename,
    .bdrv_file_open           = nvme_file_open,
    .bdrv_close               = nvme_close,
    .bdrv_co_getlength        = nvme_co_getlength,
    .bdrv_probe_blocksizes    = nvme_probe_blocksizes,
    .bdrv_co_truncate         = nvme_co_truncate,

    .bdrv_co_preadv           = nvme_co_preadv,
    .bdrv_co_pwritev          = nvme_co_pwritev,

    .bdrv_co_pwrite_zeroes    = nvme_co_pwrite_zeroes,
    .bdrv_co_pdiscard         = nvme_co_pdiscard,

    .bdrv_co_flush_to_disk    = nvme_co_flush,
    .bdrv_reopen_prepare      = nvme_reopen_prepare,

    .bdrv_refresh_filename    = nvme_refresh_filename,
    .bdrv_refresh_limits      = nvme_refresh_limits,
    .strong_runtime_opts      = nvme_strong_runtime_opts,
    .bdrv_get_specific_stats  = nvme_get_specific_stats,

    .bdrv_detach_aio_context  = nvme_detach_aio_context,
    .bdrv_attach_aio_context  = nvme_attach_aio_context,

    .bdrv_register_buf        = nvme_register_buf,
    .bdrv_unregister_buf      = nvme_unregister_buf,
};

static void bdrv_nvme_init(void)
{
    bdrv_register(&bdrv_nvme);
}

block_init(bdrv_nvme_init);
