IB/mthca: fix page shift calculation in mthca_reg_phys_mr()
authorMichael S. Tsirkin <mst@mellanox.co.il>
Mon, 9 Jan 2006 21:50:57 +0000 (13:50 -0800)
committerRoland Dreier <rolandd@cisco.com>
Mon, 9 Jan 2006 21:50:57 +0000 (13:50 -0800)
For all pages except possibly the last one, the byte beyond the buffer
end must be page aligned.  Therefore, when computing the page shift to
use, OR the end addresses of the buffers as well as the start
addresses into the mask we check.

Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/hw/mthca/mthca_provider.c

index 4cc7e2846df16c08e4f114a7832ca86b066b8cdb..30b67c20026710ae167d65d140b060284c1a1edf 100644 (file)
@@ -783,24 +783,20 @@ static struct ib_mr *mthca_reg_phys_mr(struct ib_pd       *pd,
        if ((*iova_start & ~PAGE_MASK) != (buffer_list[0].addr & ~PAGE_MASK))
                return ERR_PTR(-EINVAL);
 
-       if (num_phys_buf > 1 &&
-           ((buffer_list[0].addr + buffer_list[0].size) & ~PAGE_MASK))
-               return ERR_PTR(-EINVAL);
-
        mask = 0;
        total_size = 0;
        for (i = 0; i < num_phys_buf; ++i) {
-               if (i != 0 && buffer_list[i].addr & ~PAGE_MASK)
-                       return ERR_PTR(-EINVAL);
-               if (i != 0 && i != num_phys_buf - 1 &&
-                   (buffer_list[i].size & ~PAGE_MASK))
-                       return ERR_PTR(-EINVAL);
+               if (i != 0)
+                       mask |= buffer_list[i].addr;
+               if (i != num_phys_buf - 1)
+                       mask |= buffer_list[i].addr + buffer_list[i].size;
 
                total_size += buffer_list[i].size;
-               if (i > 0)
-                       mask |= buffer_list[i].addr;
        }
 
+       if (mask & ~PAGE_MASK)
+               return ERR_PTR(-EINVAL);
+
        /* Find largest page shift we can use to cover buffers */
        for (shift = PAGE_SHIFT; shift < 31; ++shift)
                if (num_phys_buf > 1) {