Skip to content

Commit 26fb1d1

Browse files
John Garryplbossart
authored andcommitted
nvme-pci: Use u32 for nvme_dev.q_depth and nvme_queue.q_depth
Recently nvme_dev.q_depth was changed from an int to u16 type. This falls over for the queue depth calculation in nvme_pci_enable(), where NVME_CAP_MQES(dev->ctrl.cap) + 1 may overflow as a u16, as NVME_CAP_MQES() is a 16b number also. That happens for me, and this is the result: root@ubuntu:/home/john# [148.272996] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010 Mem abort info: ESR = 0x96000004 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 Data abort info: ISV = 0, ISS = 0x00000004 CM = 0, WnR = 0 user pgtable: 4k pages, 48-bit VAs, pgdp=00000a27bf3c9000 [0000000000000010] pgd=0000000000000000, p4d=0000000000000000 Internal error: Oops: 96000004 [#1] PREEMPT SMP Modules linked in: nvme nvme_core CPU: 56 PID: 256 Comm: kworker/u195:0 Not tainted 5.8.0-next-20200812 #27 Hardware name: Huawei D06 /D06, BIOS Hisilicon D06 UEFI RC0 - V1.16.01 03/15/2019 Workqueue: nvme-reset-wq nvme_reset_work [nvme] pstate: 80c00009 (Nzcv daif +PAN +UAO BTYPE=--) pc : __sg_alloc_table_from_pages+0xec/0x238 lr : __sg_alloc_table_from_pages+0xc8/0x238 sp : ffff800013ccbad0 x29: ffff800013ccbad0 x28: ffff0a27b3d380a8 x27: 0000000000000000 x26: 0000000000002dc2 x25: 0000000000000dc0 x24: 0000000000000000 x23: 0000000000000000 x22: ffff800013ccbbe8 x21: 0000000000000010 x20: 0000000000000000 x19: 00000000fffff000 x18: ffffffffffffffff x17: 00000000000000c0 x16: fffffe289eaf6380 x15: ffff800011b59948 x14: ffff002bc8fe98f8 x13: ff00000000000000 x12: ffff8000114ca000 x11: 0000000000000000 x10: ffffffffffffffff x9 : ffffffffffffffc0 x8 : ffff0a27b5f9b6a0 x7 : 0000000000000000 x6 : 0000000000000001 x5 : ffff0a27b5f9b680 x4 : 0000000000000000 x3 : ffff0a27b5f9b680 x2 : 0000000000000000 x1 : 0000000000000001 x0 : 0000000000000000 Call trace: __sg_alloc_table_from_pages+0xec/0x238 sg_alloc_table_from_pages+0x18/0x28 iommu_dma_alloc+0x474/0x678 dma_alloc_attrs+0xd8/0xf0 nvme_alloc_queue+0x114/0x160 [nvme] nvme_reset_work+0xb34/0x14b4 [nvme] process_one_work+0x1e8/0x360 worker_thread+0x44/0x478 kthread+0x150/0x158 ret_from_fork+0x10/0x34 Code: f94002c3 6b01017f 540007c2 11000486 (f8645aa5) ---[ end trace 89bb2b72d59bf925 ]--- Fix by making onto a u32. Also use u32 for nvme_dev.q_depth, as we assign this value from nvme_dev.q_depth, and nvme_dev.q_depth will possibly hold 65536 - this avoids the same crash as above. Fixes: 61f3b89 ("nvme-pci: use unsigned for io queue depth") Signed-off-by: John Garry <[email protected]> Reviewed-by: Keith Busch <[email protected]> Signed-off-by: Sagi Grimberg <[email protected]> Signed-off-by: Jens Axboe <[email protected]> (cherry picked from commit 7442ddc) Signed-off-by: Pierre-Louis Bossart <[email protected]>
1 parent bf9754a commit 26fb1d1

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

drivers/nvme/host/pci.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ struct nvme_dev {
120120
unsigned max_qid;
121121
unsigned io_queues[HCTX_MAX_TYPES];
122122
unsigned int num_vecs;
123-
u16 q_depth;
123+
u32 q_depth;
124124
int io_sqes;
125125
u32 db_stride;
126126
void __iomem *bar;
@@ -157,13 +157,13 @@ struct nvme_dev {
157157
static int io_queue_depth_set(const char *val, const struct kernel_param *kp)
158158
{
159159
int ret;
160-
u16 n;
160+
u32 n;
161161

162-
ret = kstrtou16(val, 10, &n);
162+
ret = kstrtou32(val, 10, &n);
163163
if (ret != 0 || n < 2)
164164
return -EINVAL;
165165

166-
return param_set_ushort(val, kp);
166+
return param_set_uint(val, kp);
167167
}
168168

169169
static inline unsigned int sq_idx(unsigned int qid, u32 stride)
@@ -195,7 +195,7 @@ struct nvme_queue {
195195
dma_addr_t sq_dma_addr;
196196
dma_addr_t cq_dma_addr;
197197
u32 __iomem *q_db;
198-
u16 q_depth;
198+
u32 q_depth;
199199
u16 cq_vector;
200200
u16 sq_tail;
201201
u16 cq_head;
@@ -2320,7 +2320,7 @@ static int nvme_pci_enable(struct nvme_dev *dev)
23202320

23212321
dev->ctrl.cap = lo_hi_readq(dev->bar + NVME_REG_CAP);
23222322

2323-
dev->q_depth = min_t(u16, NVME_CAP_MQES(dev->ctrl.cap) + 1,
2323+
dev->q_depth = min_t(u32, NVME_CAP_MQES(dev->ctrl.cap) + 1,
23242324
io_queue_depth);
23252325
dev->ctrl.sqsize = dev->q_depth - 1; /* 0's based queue depth */
23262326
dev->db_stride = 1 << NVME_CAP_STRIDE(dev->ctrl.cap);

0 commit comments

Comments
 (0)