| From 7efdd5790597863553ff44e16630140df7b271c6 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 17 Sep 2020 18:43:03 +0200 |
| Subject: dma-direct: Fix potential NULL pointer dereference |
| |
| From: Thomas Tai <thomas.tai@oracle.com> |
| |
| [ Upstream commit f959dcd6ddfd29235030e8026471ac1b022ad2b0 ] |
| |
| When booting the kernel v5.9-rc4 on a VM, the kernel would panic when |
| printing a warning message in swiotlb_map(). The dev->dma_mask must not |
| be a NULL pointer when calling the dma mapping layer. A NULL pointer |
| check can potentially avoid the panic. |
| |
| Signed-off-by: Thomas Tai <thomas.tai@oracle.com> |
| Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> |
| Signed-off-by: Christoph Hellwig <hch@lst.de> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| include/linux/dma-direct.h | 3 --- |
| kernel/dma/mapping.c | 11 +++++++++++ |
| 2 files changed, 11 insertions(+), 3 deletions(-) |
| |
| diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h |
| index 6e87225600ae3..064870844f06c 100644 |
| --- a/include/linux/dma-direct.h |
| +++ b/include/linux/dma-direct.h |
| @@ -62,9 +62,6 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size, |
| { |
| dma_addr_t end = addr + size - 1; |
| |
| - if (!dev->dma_mask) |
| - return false; |
| - |
| if (is_ram && !IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT) && |
| min(addr, end) < phys_to_dma(dev, PFN_PHYS(min_low_pfn))) |
| return false; |
| diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c |
| index 0d129421e75fc..7133d5c6e1a6d 100644 |
| --- a/kernel/dma/mapping.c |
| +++ b/kernel/dma/mapping.c |
| @@ -144,6 +144,10 @@ dma_addr_t dma_map_page_attrs(struct device *dev, struct page *page, |
| dma_addr_t addr; |
| |
| BUG_ON(!valid_dma_direction(dir)); |
| + |
| + if (WARN_ON_ONCE(!dev->dma_mask)) |
| + return DMA_MAPPING_ERROR; |
| + |
| if (dma_map_direct(dev, ops)) |
| addr = dma_direct_map_page(dev, page, offset, size, dir, attrs); |
| else |
| @@ -179,6 +183,10 @@ int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, |
| int ents; |
| |
| BUG_ON(!valid_dma_direction(dir)); |
| + |
| + if (WARN_ON_ONCE(!dev->dma_mask)) |
| + return 0; |
| + |
| if (dma_map_direct(dev, ops)) |
| ents = dma_direct_map_sg(dev, sg, nents, dir, attrs); |
| else |
| @@ -213,6 +221,9 @@ dma_addr_t dma_map_resource(struct device *dev, phys_addr_t phys_addr, |
| |
| BUG_ON(!valid_dma_direction(dir)); |
| |
| + if (WARN_ON_ONCE(!dev->dma_mask)) |
| + return DMA_MAPPING_ERROR; |
| + |
| /* Don't allow RAM to be mapped */ |
| if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr)))) |
| return DMA_MAPPING_ERROR; |
| -- |
| 2.25.1 |
| |