From d9703650f4aba7555fde92636d8d9a689029e8f8 Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Wed, 28 Sep 2016 20:25:47 +0000 Subject: IB/{rxe,core,rdmavt}: Fix kernel crash for reg MR This patch fixes below kernel crash on memory registration for rxe and other transport drivers which has dma_ops extension. IB/core invokes ib_map_sg_attrs() in generic manner with dma attributes which is used by mlx5 and mthca adapters. However in doing so it ignored honoring dma_ops extension of software based transports for sg map/unmap operation. This results in calling dma_map_sg_attrs of hardware virtual device resulting in crash for null reference. We extend the core to support sg_map/unmap_attrs and transport drivers to implement those dma_ops callback functions. Verified usign perftest applications. BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] check_addr+0x35/0x60 ... Call Trace: [] ? nommu_map_sg+0x99/0xd0 [] ib_umem_get+0x3d6/0x470 [ib_core] [] rxe_mem_init_user+0x49/0x270 [rdma_rxe] [] ? rxe_add_index+0xca/0x100 [rdma_rxe] [] rxe_reg_user_mr+0x9f/0x130 [rdma_rxe] [] ib_uverbs_reg_mr+0x14e/0x2c0 [ib_uverbs] [] ib_uverbs_write+0x15b/0x3b0 [ib_uverbs] [] ? mem_cgroup_commit_charge+0x76/0xe0 [] ? page_add_new_anon_rmap+0x89/0xc0 [] ? lru_cache_add_active_or_unevictable+0x39/0xc0 [] __vfs_write+0x28/0x120 [] ? rw_verify_area+0x49/0xb0 [] vfs_write+0xb2/0x1b0 [] SyS_write+0x46/0xa0 [] entry_SYSCALL_64_fastpath+0x1a/0xa4 Signed-off-by: Parav Pandit Signed-off-by: Doug Ledford --- include/rdma/ib_verbs.h | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'include/rdma/ib_verbs.h') diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index e1f96737c2a1..9e935655fccb 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -1739,6 +1739,14 @@ struct ib_dma_mapping_ops { void (*unmap_sg)(struct ib_device *dev, struct scatterlist *sg, int nents, enum dma_data_direction direction); + int (*map_sg_attrs)(struct ib_device *dev, + struct scatterlist *sg, int nents, + enum dma_data_direction direction, + unsigned long attrs); + void (*unmap_sg_attrs)(struct ib_device *dev, + struct scatterlist *sg, int nents, + enum dma_data_direction direction, + unsigned long attrs); void (*sync_single_for_cpu)(struct ib_device *dev, u64 dma_handle, size_t size, @@ -3000,8 +3008,12 @@ static inline int ib_dma_map_sg_attrs(struct ib_device *dev, enum dma_data_direction direction, unsigned long dma_attrs) { - return dma_map_sg_attrs(dev->dma_device, sg, nents, direction, - dma_attrs); + if (dev->dma_ops) + return dev->dma_ops->map_sg_attrs(dev, sg, nents, direction, + dma_attrs); + else + return dma_map_sg_attrs(dev->dma_device, sg, nents, direction, + dma_attrs); } static inline void ib_dma_unmap_sg_attrs(struct ib_device *dev, @@ -3009,7 +3021,12 @@ static inline void ib_dma_unmap_sg_attrs(struct ib_device *dev, enum dma_data_direction direction, unsigned long dma_attrs) { - dma_unmap_sg_attrs(dev->dma_device, sg, nents, direction, dma_attrs); + if (dev->dma_ops) + return dev->dma_ops->unmap_sg_attrs(dev, sg, nents, direction, + dma_attrs); + else + dma_unmap_sg_attrs(dev->dma_device, sg, nents, direction, + dma_attrs); } /** * ib_sg_dma_address - Return the DMA address from a scatter/gather entry -- cgit v1.2.3-55-g7522