浏览代码

IB/srp: Fix FMR mapping for 32-bit kernels and addresses above 4G

struct srp_device.fmr_page_mask was unsigned long, which means that
the top part of addresses above 4G was being chopped off on 32-bit
architectures.  Of course nothing good happens when data from SRP
targets is DMAed to the wrong place.

Fix this by changing fmr_page_mask to u64, to match the addresses
actually used by IB devices.

Thanks to Brian Cain <Brian.Cain@ge.com> and David McMillen
<davem@systemfabricworks.com> for help diagnosing the bug and testing
the fix.

Signed-off-by: Roland Dreier <rolandd@cisco.com>
Roland Dreier 18 年之前
父节点
当前提交
bf628dc22a
共有 2 个文件被更改,包括 2 次插入2 次删除
  1. 1 1
      drivers/infiniband/ulp/srp/ib_srp.c
  2. 1 1
      drivers/infiniband/ulp/srp/ib_srp.h

+ 1 - 1
drivers/infiniband/ulp/srp/ib_srp.c

@@ -1898,7 +1898,7 @@ static void srp_add_one(struct ib_device *device)
 	 */
 	 */
 	srp_dev->fmr_page_shift = max(9, ffs(dev_attr->page_size_cap) - 1);
 	srp_dev->fmr_page_shift = max(9, ffs(dev_attr->page_size_cap) - 1);
 	srp_dev->fmr_page_size  = 1 << srp_dev->fmr_page_shift;
 	srp_dev->fmr_page_size  = 1 << srp_dev->fmr_page_shift;
-	srp_dev->fmr_page_mask  = ~((unsigned long) srp_dev->fmr_page_size - 1);
+	srp_dev->fmr_page_mask  = ~((u64) srp_dev->fmr_page_size - 1);
 
 
 	INIT_LIST_HEAD(&srp_dev->dev_list);
 	INIT_LIST_HEAD(&srp_dev->dev_list);
 
 

+ 1 - 1
drivers/infiniband/ulp/srp/ib_srp.h

@@ -87,7 +87,7 @@ struct srp_device {
 	struct ib_fmr_pool     *fmr_pool;
 	struct ib_fmr_pool     *fmr_pool;
 	int			fmr_page_shift;
 	int			fmr_page_shift;
 	int			fmr_page_size;
 	int			fmr_page_size;
-	unsigned long		fmr_page_mask;
+	u64			fmr_page_mask;
 };
 };
 
 
 struct srp_host {
 struct srp_host {