IB/srp: Fix FMR mapping for 32-bit kernels and addresses above 4G
authorRoland Dreier <rdreier@cisco.com>
Sat, 16 Dec 2006 04:58:14 +0000 (20:58 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 23 Feb 2007 23:49:51 +0000 (15:49 -0800)
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>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/infiniband/ulp/srp/ib_srp.c
drivers/infiniband/ulp/srp/ib_srp.h

index fd8344cdc0dbcab633326255de9ae1ecc6125bd0..d667d01d8971af7897811a7222414208dc2c8fb5 100644 (file)
@@ -1851,7 +1851,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_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);
 
index 5b581fb8eb0d08addeea3f9a5fff4763592f1ed6..c1865edcdf074d64cd6dcc9c0ae9392903d38a2a 100644 (file)
@@ -87,7 +87,7 @@ struct srp_device {
        struct ib_fmr_pool     *fmr_pool;
        int                     fmr_page_shift;
        int                     fmr_page_size;
-       unsigned long           fmr_page_mask;
+       u64                     fmr_page_mask;
 };
 
 struct srp_host {