--- /dev/null
+From stable-bounces@linux.kernel.org Fri Dec 15 21:04:20 2006
+To: stable@kernel.org
+From: Roland Dreier <rdreier@cisco.com>
+Date: Fri, 15 Dec 2006 20:58:14 -0800
+Message-ID: <adaslfgigih.fsf@cisco.com>
+Subject: 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>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+I just asked Linus to pull this. It fixes nasty corruption/crash
+problems on 32-bit systems with > 4G of memory.
+
+ drivers/infiniband/ulp/srp/ib_srp.c | 2 +-
+ drivers/infiniband/ulp/srp/ib_srp.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- linux-2.6.18.6.orig/drivers/infiniband/ulp/srp/ib_srp.c
++++ linux-2.6.18.6/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -1851,7 +1851,7 @@ static void srp_add_one(struct ib_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);
+
+--- linux-2.6.18.6.orig/drivers/infiniband/ulp/srp/ib_srp.h
++++ linux-2.6.18.6/drivers/infiniband/ulp/srp/ib_srp.h
+@@ -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 {