Re: [PATCH] dma-direct: Fix data truncation in dma_direct_get_required_mask()

2020-04-08 Thread Christoph Hellwig
Thanks,

applied.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH] dma-direct: Fix data truncation in dma_direct_get_required_mask()

2020-04-06 Thread Kishon Vijay Abraham I via iommu
The upper 32-bit physical address gets truncated inadvertently
when dma_direct_get_required_mask() invokes phys_to_dma_direct().
This results in dma_addressing_limited() return incorrect value
when used in platforms with LPAE enabled.
Fix it here by explicitly type casting 'max_pfn' to phys_addr_t
in order to prevent overflow of intermediate value while evaluating
'(max_pfn - 1) << PAGE_SHIFT'.

Signed-off-by: Kishon Vijay Abraham I 
---
Fixes the following WARN DUMP (and hang thereafter) observed when
connecting NVMe card to a platform with ARM LPAE enabled
nvme :01:00.0: overflow 0x00027b3be000+270336 of DMA mask
 bus limit 
---[ cut here ]---
WARNING: CPU: 0 PID: 26 at kernel/dma/direct.c:35 report_addr+0xf0/0xf4
Modules linked in:
CPU: 0 PID: 26 Comm: kworker/u4:1 Not tainted 5.5.0-2-g1383adf7b819 #2
Hardware name: Generic DRA74X (Flattened Device Tree)
Workqueue: writeback wb_workfn (flush-259:0)
(unwind_backtrace) from [] (show_stack+0x10/0x14)
(show_stack) from [] (dump_stack+0x94/0xa8)
(dump_stack) from [] (__warn+0xbc/0xd8)
(__warn) from [] (warn_slowpath_fmt+0x60/0xb8)
(warn_slowpath_fmt) from [] (report_addr+0xf0/0xf4)
(report_addr) from [] (dma_direct_map_page+0x18c/0x19c)
(dma_direct_map_page) from [] (dma_direct_map_sg+0x64/0xb4)
(dma_direct_map_sg) from [] (nvme_queue_rq+0x778/0x9ec)
(nvme_queue_rq) from [] (__blk_mq_try_issue_directly+0x130/0x1bc)
(__blk_mq_try_issue_directly) from []
(blk_mq_request_issue_directly+0x48/0x78)
(blk_mq_request_issue_directly) from []
(blk_mq_try_issue_list_directly+0x44/0xb8)
(blk_mq_try_issue_list_directly) from []
(blk_mq_sched_insert_requests+0xe0/0x154)
(blk_mq_sched_insert_requests) from []
(blk_mq_flush_plug_list+0x150/0x184)
(blk_mq_flush_plug_list) from [] (blk_flush_plug_list+0xc8/0xe4)
(blk_flush_plug_list) from [] (blk_mq_make_request+0x24c/0x3f0)
(blk_mq_make_request) from [] (generic_make_request+0xb0/0x2d4)
(generic_make_request) from [] (submit_bio+0x44/0x180)
(submit_bio) from [] (mpage_writepages+0xac/0xe8)
(mpage_writepages) from [] (do_writepages+0x44/0xdc)
(do_writepages) from [] (__writeback_single_inode+0x2c/0x1bc)
(__writeback_single_inode) from []
(writeback_sb_inodes+0x1d8/0x404)
(writeback_sb_inodes) from [] (__writeback_inodes_wb+0x58/0x9c)
(__writeback_inodes_wb) from [] (wb_writeback+0x194/0x1d8)
(wb_writeback) from [] (wb_workfn+0x244/0x33c)
(wb_workfn) from [] (process_one_work+0x204/0x458)
(process_one_work) from [] (worker_thread+0x44/0x598)
(worker_thread) from [] (kthread+0x14c/0x150)
(kthread) from [] (ret_from_fork+0x14/0x3c)
 kernel/dma/direct.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index ac7956c38f69..4b24275e306a 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -39,7 +39,8 @@ static inline struct page *dma_direct_to_page(struct device 
*dev,
 
 u64 dma_direct_get_required_mask(struct device *dev)
 {
-   u64 max_dma = phys_to_dma_direct(dev, (max_pfn - 1) << PAGE_SHIFT);
+   phys_addr_t phys = (phys_addr_t)(max_pfn - 1) << PAGE_SHIFT;
+   u64 max_dma = phys_to_dma_direct(dev, phys);
 
return (1ULL << (fls64(max_dma) - 1)) * 2 - 1;
 }
-- 
2.17.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu