mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/nvme/tags/pull-nvme-20200902' into staging
qemu-nvme # gpg: Signature made Wed 02 Sep 2020 15:39:10 BST # gpg: using RSA key DBC11D2D373B4A3755F502EC625156610A4F6CC0 # gpg: Good signature from "Keith Busch <kbusch@kernel.org>" [unknown] # gpg: aka "Keith Busch <keith.busch@gmail.com>" [unknown] # gpg: aka "Keith Busch <keith.busch@intel.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: DBC1 1D2D 373B 4A37 55F5 02EC 6251 5661 0A4F 6CC0 * remotes/nvme/tags/pull-nvme-20200902: (39 commits) hw/block/nvme: remove explicit qsg/iov parameters hw/block/nvme: use preallocated qsg/iov in nvme_dma_prp hw/block/nvme: consolidate qsg/iov clearing hw/block/nvme: add ns/cmd references in NvmeRequest hw/block/nvme: be consistent about zeros vs zeroes hw/block/nvme: add check for mdts hw/block/nvme: refactor request bounds checking hw/block/nvme: verify validity of prp lists in the cmb hw/block/nvme: add request mapping helper hw/block/nvme: add tracing to nvme_map_prp hw/block/nvme: refactor dma read/write hw/block/nvme: destroy request iov before reuse hw/block/nvme: remove redundant has_sg member hw/block/nvme: replace dma_acct with blk_acct equivalent hw/block/nvme: add mapping helpers hw/block/nvme: memset preallocated requests structures hw/block/nvme: bump supported version to v1.3 hw/block/nvme: provide the mandatory subnqn field hw/block/nvme: enforce valid queue creation sequence hw/block/nvme: reject invalid nsid values in active namespace id list ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -1856,10 +1856,12 @@ F: include/hw/virtio/virtio-mem.h
|
||||
|
||||
nvme
|
||||
M: Keith Busch <kbusch@kernel.org>
|
||||
M: Klaus Jensen <its@irrelevant.dk>
|
||||
L: qemu-block@nongnu.org
|
||||
S: Supported
|
||||
F: hw/block/nvme*
|
||||
F: tests/qtest/nvme-test.c
|
||||
T: git git://git.infradead.org/qemu-nvme.git nvme-next
|
||||
|
||||
megasas
|
||||
M: Hannes Reinecke <hare@suse.com>
|
||||
|
||||
+11
-11
@@ -518,7 +518,7 @@ static void nvme_identify(BlockDriverState *bs, int namespace, Error **errp)
|
||||
error_setg(errp, "Cannot map buffer for DMA");
|
||||
goto out;
|
||||
}
|
||||
cmd.prp1 = cpu_to_le64(iova);
|
||||
cmd.dptr.prp1 = cpu_to_le64(iova);
|
||||
|
||||
if (nvme_cmd_sync(bs, s->queues[0], &cmd)) {
|
||||
error_setg(errp, "Failed to identify controller");
|
||||
@@ -537,7 +537,7 @@ static void nvme_identify(BlockDriverState *bs, int namespace, Error **errp)
|
||||
s->page_size / sizeof(uint64_t) * s->page_size);
|
||||
|
||||
oncs = le16_to_cpu(idctrl->oncs);
|
||||
s->supports_write_zeroes = !!(oncs & NVME_ONCS_WRITE_ZEROS);
|
||||
s->supports_write_zeroes = !!(oncs & NVME_ONCS_WRITE_ZEROES);
|
||||
s->supports_discard = !!(oncs & NVME_ONCS_DSM);
|
||||
|
||||
memset(resp, 0, 4096);
|
||||
@@ -629,7 +629,7 @@ static bool nvme_add_io_queue(BlockDriverState *bs, Error **errp)
|
||||
}
|
||||
cmd = (NvmeCmd) {
|
||||
.opcode = NVME_ADM_CMD_CREATE_CQ,
|
||||
.prp1 = cpu_to_le64(q->cq.iova),
|
||||
.dptr.prp1 = cpu_to_le64(q->cq.iova),
|
||||
.cdw10 = cpu_to_le32(((queue_size - 1) << 16) | (n & 0xFFFF)),
|
||||
.cdw11 = cpu_to_le32(0x3),
|
||||
};
|
||||
@@ -640,7 +640,7 @@ static bool nvme_add_io_queue(BlockDriverState *bs, Error **errp)
|
||||
}
|
||||
cmd = (NvmeCmd) {
|
||||
.opcode = NVME_ADM_CMD_CREATE_SQ,
|
||||
.prp1 = cpu_to_le64(q->sq.iova),
|
||||
.dptr.prp1 = cpu_to_le64(q->sq.iova),
|
||||
.cdw10 = cpu_to_le32(((queue_size - 1) << 16) | (n & 0xFFFF)),
|
||||
.cdw11 = cpu_to_le32(0x1 | (n << 16)),
|
||||
};
|
||||
@@ -988,16 +988,16 @@ try_map:
|
||||
case 0:
|
||||
abort();
|
||||
case 1:
|
||||
cmd->prp1 = pagelist[0];
|
||||
cmd->prp2 = 0;
|
||||
cmd->dptr.prp1 = pagelist[0];
|
||||
cmd->dptr.prp2 = 0;
|
||||
break;
|
||||
case 2:
|
||||
cmd->prp1 = pagelist[0];
|
||||
cmd->prp2 = pagelist[1];
|
||||
cmd->dptr.prp1 = pagelist[0];
|
||||
cmd->dptr.prp2 = pagelist[1];
|
||||
break;
|
||||
default:
|
||||
cmd->prp1 = pagelist[0];
|
||||
cmd->prp2 = cpu_to_le64(req->prp_list_iova + sizeof(uint64_t));
|
||||
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);
|
||||
@@ -1201,7 +1201,7 @@ static coroutine_fn int nvme_co_pwrite_zeroes(BlockDriverState *bs,
|
||||
}
|
||||
|
||||
NvmeCmd cmd = {
|
||||
.opcode = NVME_CMD_WRITE_ZEROS,
|
||||
.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),
|
||||
|
||||
+977
-177
File diff suppressed because it is too large
Load Diff
+24
-2
@@ -9,19 +9,23 @@ typedef struct NvmeParams {
|
||||
uint32_t max_ioqpairs;
|
||||
uint16_t msix_qsize;
|
||||
uint32_t cmb_size_mb;
|
||||
uint8_t aerl;
|
||||
uint32_t aer_max_queued;
|
||||
uint8_t mdts;
|
||||
} NvmeParams;
|
||||
|
||||
typedef struct NvmeAsyncEvent {
|
||||
QSIMPLEQ_ENTRY(NvmeAsyncEvent) entry;
|
||||
QTAILQ_ENTRY(NvmeAsyncEvent) entry;
|
||||
NvmeAerResult result;
|
||||
} NvmeAsyncEvent;
|
||||
|
||||
typedef struct NvmeRequest {
|
||||
struct NvmeSQueue *sq;
|
||||
struct NvmeNamespace *ns;
|
||||
BlockAIOCB *aiocb;
|
||||
uint16_t status;
|
||||
bool has_sg;
|
||||
NvmeCqe cqe;
|
||||
NvmeCmd cmd;
|
||||
BlockAcctCookie acct;
|
||||
QEMUSGList qsg;
|
||||
QEMUIOVector iov;
|
||||
@@ -77,6 +81,14 @@ static inline uint8_t nvme_ns_lbads(NvmeNamespace *ns)
|
||||
#define NVME(obj) \
|
||||
OBJECT_CHECK(NvmeCtrl, (obj), TYPE_NVME)
|
||||
|
||||
typedef struct NvmeFeatureVal {
|
||||
struct {
|
||||
uint16_t temp_thresh_hi;
|
||||
uint16_t temp_thresh_low;
|
||||
};
|
||||
uint32_t async_config;
|
||||
} NvmeFeatureVal;
|
||||
|
||||
typedef struct NvmeCtrl {
|
||||
PCIDevice parent_obj;
|
||||
MemoryRegion iomem;
|
||||
@@ -85,6 +97,7 @@ typedef struct NvmeCtrl {
|
||||
BlockConf conf;
|
||||
NvmeParams params;
|
||||
|
||||
bool qs_created;
|
||||
uint32_t page_size;
|
||||
uint16_t page_bits;
|
||||
uint16_t max_prp_ents;
|
||||
@@ -94,19 +107,28 @@ typedef struct NvmeCtrl {
|
||||
uint32_t num_namespaces;
|
||||
uint32_t max_q_ents;
|
||||
uint64_t ns_size;
|
||||
uint8_t outstanding_aers;
|
||||
uint8_t *cmbuf;
|
||||
uint32_t irq_status;
|
||||
uint64_t host_timestamp; /* Timestamp sent by the host */
|
||||
uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
|
||||
uint64_t starttime_ms;
|
||||
uint16_t temperature;
|
||||
|
||||
HostMemoryBackend *pmrdev;
|
||||
|
||||
uint8_t aer_mask;
|
||||
NvmeRequest **aer_reqs;
|
||||
QTAILQ_HEAD(, NvmeAsyncEvent) aer_queue;
|
||||
int aer_queued;
|
||||
|
||||
NvmeNamespace *namespaces;
|
||||
NvmeSQueue **sq;
|
||||
NvmeCQueue **cq;
|
||||
NvmeSQueue admin_sq;
|
||||
NvmeCQueue admin_cq;
|
||||
NvmeIdCtrl id_ctrl;
|
||||
NvmeFeatureVal features;
|
||||
} NvmeCtrl;
|
||||
|
||||
/* calculate the number of LBAs that the namespace can accomodate */
|
||||
|
||||
+29
-2
@@ -33,19 +33,44 @@ pci_nvme_irq_msix(uint32_t vector) "raising MSI-X IRQ vector %u"
|
||||
pci_nvme_irq_pin(void) "pulsing IRQ pin"
|
||||
pci_nvme_irq_masked(void) "IRQ is masked"
|
||||
pci_nvme_dma_read(uint64_t prp1, uint64_t prp2) "DMA read, prp1=0x%"PRIx64" prp2=0x%"PRIx64""
|
||||
pci_nvme_map_addr(uint64_t addr, uint64_t len) "addr 0x%"PRIx64" len %"PRIu64""
|
||||
pci_nvme_map_addr_cmb(uint64_t addr, uint64_t len) "addr 0x%"PRIx64" len %"PRIu64""
|
||||
pci_nvme_map_prp(uint64_t trans_len, uint32_t len, uint64_t prp1, uint64_t prp2, int num_prps) "trans_len %"PRIu64" len %"PRIu32" prp1 0x%"PRIx64" prp2 0x%"PRIx64" num_prps %d"
|
||||
pci_nvme_io_cmd(uint16_t cid, uint32_t nsid, uint16_t sqid, uint8_t opcode) "cid %"PRIu16" nsid %"PRIu32" sqid %"PRIu16" opc 0x%"PRIx8""
|
||||
pci_nvme_admin_cmd(uint16_t cid, uint16_t sqid, uint8_t opcode) "cid %"PRIu16" sqid %"PRIu16" opc 0x%"PRIx8""
|
||||
pci_nvme_rw(const char *verb, uint32_t blk_count, uint64_t byte_count, uint64_t lba) "%s %"PRIu32" blocks (%"PRIu64" bytes) from LBA %"PRIu64""
|
||||
pci_nvme_rw_cb(uint16_t cid) "cid %"PRIu16""
|
||||
pci_nvme_write_zeroes(uint16_t cid, uint64_t slba, uint32_t nlb) "cid %"PRIu16" slba %"PRIu64" nlb %"PRIu32""
|
||||
pci_nvme_create_sq(uint64_t addr, uint16_t sqid, uint16_t cqid, uint16_t qsize, uint16_t qflags) "create submission queue, addr=0x%"PRIx64", sqid=%"PRIu16", cqid=%"PRIu16", qsize=%"PRIu16", qflags=%"PRIu16""
|
||||
pci_nvme_create_cq(uint64_t addr, uint16_t cqid, uint16_t vector, uint16_t size, uint16_t qflags, int ien) "create completion queue, addr=0x%"PRIx64", cqid=%"PRIu16", vector=%"PRIu16", qsize=%"PRIu16", qflags=%"PRIu16", ien=%d"
|
||||
pci_nvme_del_sq(uint16_t qid) "deleting submission queue sqid=%"PRIu16""
|
||||
pci_nvme_del_cq(uint16_t cqid) "deleted completion queue, cqid=%"PRIu16""
|
||||
pci_nvme_identify_ctrl(void) "identify controller"
|
||||
pci_nvme_identify_ns(uint16_t ns) "identify namespace, nsid=%"PRIu16""
|
||||
pci_nvme_identify_nslist(uint16_t ns) "identify namespace list, nsid=%"PRIu16""
|
||||
pci_nvme_identify_ns(uint32_t ns) "nsid %"PRIu32""
|
||||
pci_nvme_identify_nslist(uint32_t ns) "nsid %"PRIu32""
|
||||
pci_nvme_identify_ns_descr_list(uint32_t ns) "nsid %"PRIu32""
|
||||
pci_nvme_get_log(uint16_t cid, uint8_t lid, uint8_t lsp, uint8_t rae, uint32_t len, uint64_t off) "cid %"PRIu16" lid 0x%"PRIx8" lsp 0x%"PRIx8" rae 0x%"PRIx8" len %"PRIu32" off %"PRIu64""
|
||||
pci_nvme_getfeat(uint16_t cid, uint8_t fid, uint8_t sel, uint32_t cdw11) "cid %"PRIu16" fid 0x%"PRIx8" sel 0x%"PRIx8" cdw11 0x%"PRIx32""
|
||||
pci_nvme_setfeat(uint16_t cid, uint8_t fid, uint8_t save, uint32_t cdw11) "cid %"PRIu16" fid 0x%"PRIx8" save 0x%"PRIx8" cdw11 0x%"PRIx32""
|
||||
pci_nvme_getfeat_vwcache(const char* result) "get feature volatile write cache, result=%s"
|
||||
pci_nvme_getfeat_numq(int result) "get feature number of queues, result=%d"
|
||||
pci_nvme_setfeat_numq(int reqcq, int reqsq, int gotcq, int gotsq) "requested cq_count=%d sq_count=%d, responding with cq_count=%d sq_count=%d"
|
||||
pci_nvme_setfeat_timestamp(uint64_t ts) "set feature timestamp = 0x%"PRIx64""
|
||||
pci_nvme_getfeat_timestamp(uint64_t ts) "get feature timestamp = 0x%"PRIx64""
|
||||
pci_nvme_process_aers(int queued) "queued %d"
|
||||
pci_nvme_aer(uint16_t cid) "cid %"PRIu16""
|
||||
pci_nvme_aer_aerl_exceeded(void) "aerl exceeded"
|
||||
pci_nvme_aer_masked(uint8_t type, uint8_t mask) "type 0x%"PRIx8" mask 0x%"PRIx8""
|
||||
pci_nvme_aer_post_cqe(uint8_t typ, uint8_t info, uint8_t log_page) "type 0x%"PRIx8" info 0x%"PRIx8" lid 0x%"PRIx8""
|
||||
pci_nvme_enqueue_event(uint8_t typ, uint8_t info, uint8_t log_page) "type 0x%"PRIx8" info 0x%"PRIx8" lid 0x%"PRIx8""
|
||||
pci_nvme_enqueue_event_noqueue(int queued) "queued %d"
|
||||
pci_nvme_enqueue_event_masked(uint8_t typ) "type 0x%"PRIx8""
|
||||
pci_nvme_no_outstanding_aers(void) "ignoring event; no outstanding AERs"
|
||||
pci_nvme_enqueue_req_completion(uint16_t cid, uint16_t cqid, uint16_t status) "cid %"PRIu16" cqid %"PRIu16" status 0x%"PRIx16""
|
||||
pci_nvme_mmio_read(uint64_t addr) "addr 0x%"PRIx64""
|
||||
pci_nvme_mmio_write(uint64_t addr, uint64_t data) "addr 0x%"PRIx64" data 0x%"PRIx64""
|
||||
pci_nvme_mmio_doorbell_cq(uint16_t cqid, uint16_t new_head) "cqid %"PRIu16" new_head %"PRIu16""
|
||||
pci_nvme_mmio_doorbell_sq(uint16_t sqid, uint16_t new_tail) "cqid %"PRIu16" new_tail %"PRIu16""
|
||||
pci_nvme_mmio_intm_set(uint64_t data, uint64_t new_mask) "wrote MMIO, interrupt mask set, data=0x%"PRIx64", new_mask=0x%"PRIx64""
|
||||
pci_nvme_mmio_intm_clr(uint64_t data, uint64_t new_mask) "wrote MMIO, interrupt mask clr, data=0x%"PRIx64", new_mask=0x%"PRIx64""
|
||||
pci_nvme_mmio_cfg(uint64_t data) "wrote MMIO, config controller config=0x%"PRIx64""
|
||||
@@ -60,6 +85,7 @@ pci_nvme_mmio_shutdown_set(void) "shutdown bit set"
|
||||
pci_nvme_mmio_shutdown_cleared(void) "shutdown bit cleared"
|
||||
|
||||
# nvme traces for error conditions
|
||||
pci_nvme_err_mdts(uint16_t cid, size_t len) "cid %"PRIu16" len %zu"
|
||||
pci_nvme_err_invalid_dma(void) "PRP/SGL is too small for transfer size"
|
||||
pci_nvme_err_invalid_prplist_ent(uint64_t prplist) "PRP list entry is null or not page aligned: 0x%"PRIx64""
|
||||
pci_nvme_err_invalid_prp2_align(uint64_t prp2) "PRP2 is not page aligned: 0x%"PRIx64""
|
||||
@@ -85,6 +111,7 @@ pci_nvme_err_invalid_create_cq_qflags(uint16_t qflags) "failed creating completi
|
||||
pci_nvme_err_invalid_identify_cns(uint16_t cns) "identify, invalid cns=0x%"PRIx16""
|
||||
pci_nvme_err_invalid_getfeat(int dw10) "invalid get features, dw10=0x%"PRIx32""
|
||||
pci_nvme_err_invalid_setfeat(uint32_t dw10) "invalid set features, dw10=0x%"PRIx32""
|
||||
pci_nvme_err_invalid_log_page(uint16_t cid, uint16_t lid) "cid %"PRIu16" lid 0x%"PRIx16""
|
||||
pci_nvme_err_startfail_cq(void) "nvme_start_ctrl failed because there are non-admin completion queues"
|
||||
pci_nvme_err_startfail_sq(void) "nvme_start_ctrl failed because there are non-admin submission queues"
|
||||
pci_nvme_err_startfail_nbarasq(void) "nvme_start_ctrl failed because the admin submission queue address is null"
|
||||
|
||||
+214
-57
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user