]> xenbits.xensource.com Git - people/andrewcoop/seabios.git/commitdiff
nvme: fix I/O queue length calculation overflow
authorMatt DeVillier <matt.devillier@puri.sm>
Tue, 21 Aug 2018 15:00:53 +0000 (10:00 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Thu, 23 Aug 2018 14:23:21 +0000 (10:23 -0400)
Commit cd47172 changed the I/O queue length calculation to use the
Maximum Queue Entries Supported (MQES) value from the capabilities
register, plus one, with a maximum value of NVME_PAGE_SIZE.

An unintended effect from this is that due to length being an unsigned
16-bit int, a MQES value of 0xFFFF yields a length of zero, resulting
in the queue allocation failing. Fix this by changing length to a u32.

TEST: build/boot on a Purism Librem13v2 with a MyDigitalSSD BPX NVMe
drive, which reports a MQES of 0xFFFF. Verify NVMe drive present in
boot menu and OS boots successfully.

Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
src/hw/nvme.c

index e6d739d935b51a8c8c1d5381d6f6134eea785771..2e3aa38682c4f54022700ceec2196faf692cd34b 100644 (file)
@@ -318,7 +318,7 @@ nvme_create_io_cq(struct nvme_ctrl *ctrl, struct nvme_cq *cq, u16 q_idx)
 {
     int rc;
     struct nvme_sqe *cmd_create_cq;
-    u16 length = 1 + (ctrl->reg->cap & 0xffff);
+    u32 length = 1 + (ctrl->reg->cap & 0xffff);
     if (length > NVME_PAGE_SIZE / sizeof(struct nvme_cqe))
         length = NVME_PAGE_SIZE / sizeof(struct nvme_cqe);
 
@@ -362,7 +362,7 @@ nvme_create_io_sq(struct nvme_ctrl *ctrl, struct nvme_sq *sq, u16 q_idx, struct
 {
     int rc;
     struct nvme_sqe *cmd_create_sq;
-    u16 length = 1 + (ctrl->reg->cap & 0xffff);
+    u32 length = 1 + (ctrl->reg->cap & 0xffff);
     if (length > NVME_PAGE_SIZE / sizeof(struct nvme_cqe))
         length = NVME_PAGE_SIZE / sizeof(struct nvme_cqe);