Skip to content

Commit 3c2fb1c

Browse files
Christoph Hellwigkeithbusch
authored andcommitted
nvme-pci: fix freeing of the HMB descriptor table
The HMB descriptor table is sized to the maximum number of descriptors that could be used for a given device, but __nvme_alloc_host_mem could break out of the loop earlier on memory allocation failure and end up using less descriptors than planned for, which leads to an incorrect size passed to dma_free_coherent. In practice this was not showing up because the number of descriptors tends to be low and the dma coherent allocator always allocates and frees at least a page. Fixes: 87ad72a ("nvme-pci: implement host memory buffer support") Signed-off-by: Christoph Hellwig <[email protected]> Signed-off-by: Keith Busch <[email protected]>
1 parent 5e52f71 commit 3c2fb1c

File tree

1 file changed

+9
-7
lines changed

1 file changed

+9
-7
lines changed

drivers/nvme/host/pci.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ struct nvme_dev {
153153
/* host memory buffer support: */
154154
u64 host_mem_size;
155155
u32 nr_host_mem_descs;
156+
u32 host_mem_descs_size;
156157
dma_addr_t host_mem_descs_dma;
157158
struct nvme_host_mem_buf_desc *host_mem_descs;
158159
void **host_mem_desc_bufs;
@@ -1966,18 +1967,18 @@ static void nvme_free_host_mem(struct nvme_dev *dev)
19661967

19671968
kfree(dev->host_mem_desc_bufs);
19681969
dev->host_mem_desc_bufs = NULL;
1969-
dma_free_coherent(dev->dev,
1970-
dev->nr_host_mem_descs * sizeof(*dev->host_mem_descs),
1970+
dma_free_coherent(dev->dev, dev->host_mem_descs_size,
19711971
dev->host_mem_descs, dev->host_mem_descs_dma);
19721972
dev->host_mem_descs = NULL;
1973+
dev->host_mem_descs_size = 0;
19731974
dev->nr_host_mem_descs = 0;
19741975
}
19751976

19761977
static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred,
19771978
u32 chunk_size)
19781979
{
19791980
struct nvme_host_mem_buf_desc *descs;
1980-
u32 max_entries, len;
1981+
u32 max_entries, len, descs_size;
19811982
dma_addr_t descs_dma;
19821983
int i = 0;
19831984
void **bufs;
@@ -1990,8 +1991,9 @@ static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred,
19901991
if (dev->ctrl.hmmaxd && dev->ctrl.hmmaxd < max_entries)
19911992
max_entries = dev->ctrl.hmmaxd;
19921993

1993-
descs = dma_alloc_coherent(dev->dev, max_entries * sizeof(*descs),
1994-
&descs_dma, GFP_KERNEL);
1994+
descs_size = max_entries * sizeof(*descs);
1995+
descs = dma_alloc_coherent(dev->dev, descs_size, &descs_dma,
1996+
GFP_KERNEL);
19951997
if (!descs)
19961998
goto out;
19971999

@@ -2020,6 +2022,7 @@ static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred,
20202022
dev->host_mem_size = size;
20212023
dev->host_mem_descs = descs;
20222024
dev->host_mem_descs_dma = descs_dma;
2025+
dev->host_mem_descs_size = descs_size;
20232026
dev->host_mem_desc_bufs = bufs;
20242027
return 0;
20252028

@@ -2034,8 +2037,7 @@ static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred,
20342037

20352038
kfree(bufs);
20362039
out_free_descs:
2037-
dma_free_coherent(dev->dev, max_entries * sizeof(*descs), descs,
2038-
descs_dma);
2040+
dma_free_coherent(dev->dev, descs_size, descs, descs_dma);
20392041
out:
20402042
dev->host_mem_descs = NULL;
20412043
return -ENOMEM;

0 commit comments

Comments
 (0)