mirror of https://github.com/xemu-project/xemu.git
hw/nvme fixes
- two fixes for hw/nvme -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEUigzqnXi3OaiR2bATeGvMW1PDekFAmTQ2y4ACgkQTeGvMW1P DenpWQf/WFgEljzgTcgxlfZhCyzWGwVNgKqRxlTuF6ELqm8BajCuCeA5ias6AXOr x/gZ0VqrL91L5tRIH5Q0sdC+HBFC1yMs66jopdzc1oL1eYu1HTrLIqMDtkXp/K/P PyGah2t4qEMtacSkad+hmB68ViUkkmhkxrWYIeufUQTfLNF5pBqNvB1kQON3jmXE a1jI/PabYxi8Km0rfFJD6SUGmL9+m7MY/SyZAy+4EZZ1OEnp5jb3o9lbdwbhIU5e dRX4NW4BEDiOJeIcNVDiQkXv2/Lna1B51RVMvM4owpk0eRvRXMSqs2DQ5/jp/nGb 8uChUJ0QW68I4e9ptTfxmBsr4pSktg== =0nwp -----END PGP SIGNATURE----- Merge tag 'nvme-next-pull-request' of https://gitlab.com/birkelund/qemu into staging hw/nvme fixes - two fixes for hw/nvme # -----BEGIN PGP SIGNATURE----- # # iQEzBAABCgAdFiEEUigzqnXi3OaiR2bATeGvMW1PDekFAmTQ2y4ACgkQTeGvMW1P # DenpWQf/WFgEljzgTcgxlfZhCyzWGwVNgKqRxlTuF6ELqm8BajCuCeA5ias6AXOr # x/gZ0VqrL91L5tRIH5Q0sdC+HBFC1yMs66jopdzc1oL1eYu1HTrLIqMDtkXp/K/P # PyGah2t4qEMtacSkad+hmB68ViUkkmhkxrWYIeufUQTfLNF5pBqNvB1kQON3jmXE # a1jI/PabYxi8Km0rfFJD6SUGmL9+m7MY/SyZAy+4EZZ1OEnp5jb3o9lbdwbhIU5e # dRX4NW4BEDiOJeIcNVDiQkXv2/Lna1B51RVMvM4owpk0eRvRXMSqs2DQ5/jp/nGb # 8uChUJ0QW68I4e9ptTfxmBsr4pSktg== # =0nwp # -----END PGP SIGNATURE----- # gpg: Signature made Mon 07 Aug 2023 04:53:18 AM PDT # gpg: using RSA key 522833AA75E2DCE6A24766C04DE1AF316D4F0DE9 # gpg: Good signature from "Klaus Jensen <its@irrelevant.dk>" [unknown] # gpg: aka "Klaus Jensen <k.jensen@samsung.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: DDCA 4D9C 9EF9 31CC 3468 4272 63D5 6FC5 E55D A838 # Subkey fingerprint: 5228 33AA 75E2 DCE6 A247 66C0 4DE1 AF31 6D4F 0DE9 * tag 'nvme-next-pull-request' of https://gitlab.com/birkelund/qemu: hw/nvme: fix compliance issue wrt. iosqes/iocqes hw/nvme: fix oob memory read in fdp events log Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
e0e5dca517
|
@ -1507,7 +1507,7 @@ static void nvme_post_cqes(void *opaque)
|
|||
req->cqe.status = cpu_to_le16((req->status << 1) | cq->phase);
|
||||
req->cqe.sq_id = cpu_to_le16(sq->sqid);
|
||||
req->cqe.sq_head = cpu_to_le16(sq->head);
|
||||
addr = cq->dma_addr + cq->tail * n->cqe_size;
|
||||
addr = cq->dma_addr + (cq->tail << NVME_CQES);
|
||||
ret = pci_dma_write(PCI_DEVICE(n), addr, (void *)&req->cqe,
|
||||
sizeof(req->cqe));
|
||||
if (ret) {
|
||||
|
@ -5120,6 +5120,11 @@ static uint16_t nvme_fdp_events(NvmeCtrl *n, uint32_t endgrpid,
|
|||
}
|
||||
|
||||
log_size = sizeof(NvmeFdpEventsLog) + ebuf->nelems * sizeof(NvmeFdpEvent);
|
||||
|
||||
if (off >= log_size) {
|
||||
return NVME_INVALID_FIELD | NVME_DNR;
|
||||
}
|
||||
|
||||
trans_len = MIN(log_size - off, buf_len);
|
||||
elog = g_malloc0(log_size);
|
||||
elog->num_events = cpu_to_le32(ebuf->nelems);
|
||||
|
@ -5295,10 +5300,18 @@ static uint16_t nvme_create_cq(NvmeCtrl *n, NvmeRequest *req)
|
|||
uint16_t qsize = le16_to_cpu(c->qsize);
|
||||
uint16_t qflags = le16_to_cpu(c->cq_flags);
|
||||
uint64_t prp1 = le64_to_cpu(c->prp1);
|
||||
uint32_t cc = ldq_le_p(&n->bar.cc);
|
||||
uint8_t iocqes = NVME_CC_IOCQES(cc);
|
||||
uint8_t iosqes = NVME_CC_IOSQES(cc);
|
||||
|
||||
trace_pci_nvme_create_cq(prp1, cqid, vector, qsize, qflags,
|
||||
NVME_CQ_FLAGS_IEN(qflags) != 0);
|
||||
|
||||
if (iosqes != NVME_SQES || iocqes != NVME_CQES) {
|
||||
trace_pci_nvme_err_invalid_create_cq_entry_size(iosqes, iocqes);
|
||||
return NVME_MAX_QSIZE_EXCEEDED | NVME_DNR;
|
||||
}
|
||||
|
||||
if (unlikely(!cqid || cqid > n->conf_ioqpairs || n->cq[cqid] != NULL)) {
|
||||
trace_pci_nvme_err_invalid_create_cq_cqid(cqid);
|
||||
return NVME_INVALID_QID | NVME_DNR;
|
||||
|
@ -6995,7 +7008,7 @@ static void nvme_process_sq(void *opaque)
|
|||
}
|
||||
|
||||
while (!(nvme_sq_empty(sq) || QTAILQ_EMPTY(&sq->req_list))) {
|
||||
addr = sq->dma_addr + sq->head * n->sqe_size;
|
||||
addr = sq->dma_addr + (sq->head << NVME_SQES);
|
||||
if (nvme_addr_read(n, addr, (void *)&cmd, sizeof(cmd))) {
|
||||
trace_pci_nvme_err_addr_read(addr);
|
||||
trace_pci_nvme_err_cfs();
|
||||
|
@ -7220,34 +7233,6 @@ static int nvme_start_ctrl(NvmeCtrl *n)
|
|||
NVME_CAP_MPSMAX(cap));
|
||||
return -1;
|
||||
}
|
||||
if (unlikely(NVME_CC_IOCQES(cc) <
|
||||
NVME_CTRL_CQES_MIN(n->id_ctrl.cqes))) {
|
||||
trace_pci_nvme_err_startfail_cqent_too_small(
|
||||
NVME_CC_IOCQES(cc),
|
||||
NVME_CTRL_CQES_MIN(cap));
|
||||
return -1;
|
||||
}
|
||||
if (unlikely(NVME_CC_IOCQES(cc) >
|
||||
NVME_CTRL_CQES_MAX(n->id_ctrl.cqes))) {
|
||||
trace_pci_nvme_err_startfail_cqent_too_large(
|
||||
NVME_CC_IOCQES(cc),
|
||||
NVME_CTRL_CQES_MAX(cap));
|
||||
return -1;
|
||||
}
|
||||
if (unlikely(NVME_CC_IOSQES(cc) <
|
||||
NVME_CTRL_SQES_MIN(n->id_ctrl.sqes))) {
|
||||
trace_pci_nvme_err_startfail_sqent_too_small(
|
||||
NVME_CC_IOSQES(cc),
|
||||
NVME_CTRL_SQES_MIN(cap));
|
||||
return -1;
|
||||
}
|
||||
if (unlikely(NVME_CC_IOSQES(cc) >
|
||||
NVME_CTRL_SQES_MAX(n->id_ctrl.sqes))) {
|
||||
trace_pci_nvme_err_startfail_sqent_too_large(
|
||||
NVME_CC_IOSQES(cc),
|
||||
NVME_CTRL_SQES_MAX(cap));
|
||||
return -1;
|
||||
}
|
||||
if (unlikely(!NVME_AQA_ASQS(aqa))) {
|
||||
trace_pci_nvme_err_startfail_asqent_sz_zero();
|
||||
return -1;
|
||||
|
@ -7260,8 +7245,6 @@ static int nvme_start_ctrl(NvmeCtrl *n)
|
|||
n->page_bits = page_bits;
|
||||
n->page_size = page_size;
|
||||
n->max_prp_ents = n->page_size / sizeof(uint64_t);
|
||||
n->cqe_size = 1 << NVME_CC_IOCQES(cc);
|
||||
n->sqe_size = 1 << NVME_CC_IOSQES(cc);
|
||||
nvme_init_cq(&n->admin_cq, n, acq, 0, 0, NVME_AQA_ACQS(aqa) + 1, 1);
|
||||
nvme_init_sq(&n->admin_sq, n, asq, 0, 0, NVME_AQA_ASQS(aqa) + 1);
|
||||
|
||||
|
@ -8230,8 +8213,8 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pci_dev)
|
|||
id->wctemp = cpu_to_le16(NVME_TEMPERATURE_WARNING);
|
||||
id->cctemp = cpu_to_le16(NVME_TEMPERATURE_CRITICAL);
|
||||
|
||||
id->sqes = (0x6 << 4) | 0x6;
|
||||
id->cqes = (0x4 << 4) | 0x4;
|
||||
id->sqes = (NVME_SQES << 4) | NVME_SQES;
|
||||
id->cqes = (NVME_CQES << 4) | NVME_CQES;
|
||||
id->nn = cpu_to_le32(NVME_MAX_NAMESPACES);
|
||||
id->oncs = cpu_to_le16(NVME_ONCS_WRITE_ZEROES | NVME_ONCS_TIMESTAMP |
|
||||
NVME_ONCS_FEATURES | NVME_ONCS_DSM |
|
||||
|
|
|
@ -30,6 +30,13 @@
|
|||
#define NVME_FDP_MAX_EVENTS 63
|
||||
#define NVME_FDP_MAXPIDS 128
|
||||
|
||||
/*
|
||||
* The controller only supports Submission and Completion Queue Entry Sizes of
|
||||
* 64 and 16 bytes respectively.
|
||||
*/
|
||||
#define NVME_SQES 6
|
||||
#define NVME_CQES 4
|
||||
|
||||
QEMU_BUILD_BUG_ON(NVME_MAX_NAMESPACES > NVME_NSID_BROADCAST - 1);
|
||||
|
||||
typedef struct NvmeCtrl NvmeCtrl;
|
||||
|
@ -530,8 +537,6 @@ typedef struct NvmeCtrl {
|
|||
uint32_t page_size;
|
||||
uint16_t page_bits;
|
||||
uint16_t max_prp_ents;
|
||||
uint16_t cqe_size;
|
||||
uint16_t sqe_size;
|
||||
uint32_t max_q_ents;
|
||||
uint8_t outstanding_aers;
|
||||
uint32_t irq_status;
|
||||
|
|
|
@ -168,6 +168,7 @@ pci_nvme_err_invalid_create_cq_size(uint16_t size) "failed creating completion q
|
|||
pci_nvme_err_invalid_create_cq_addr(uint64_t addr) "failed creating completion queue, addr=0x%"PRIx64""
|
||||
pci_nvme_err_invalid_create_cq_vector(uint16_t vector) "failed creating completion queue, vector=%"PRIu16""
|
||||
pci_nvme_err_invalid_create_cq_qflags(uint16_t qflags) "failed creating completion queue, qflags=%"PRIu16""
|
||||
pci_nvme_err_invalid_create_cq_entry_size(uint8_t iosqes, uint8_t iocqes) "iosqes %"PRIu8" iocqes %"PRIu8""
|
||||
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""
|
||||
|
|
Loading…
Reference in New Issue