Commit bf628dc2 authored by Roland Dreier's avatar Roland Dreier

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: default avatarRoland Dreier <rolandd@cisco.com>
parent c59a3da1
...@@ -1898,7 +1898,7 @@ static void srp_add_one(struct ib_device *device) ...@@ -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);
......
...@@ -87,7 +87,7 @@ struct srp_device { ...@@ -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 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment