aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Cohen <eli@dev.mellanox.co.il>2013-10-31 09:26:32 -0400
committerRoland Dreier <roland@purestorage.com>2013-11-15 13:25:32 -0500
commit1c636f801615bdfc9b1d46904e8258c7a025670b (patch)
tree600ff4b245e9287489c6c4b8a3a132f5adae5eb9
parent180771a3707a4c0577cbf4f830c754dbabfdfccb (diff)
IB/core: Encorce MR access rights rules on kernel consumers
Enforce the rule that when requesting remote write or atomic permissions, local write must be indicated as well. See IB spec 11.2.8.2. Spotted by: Hagay Abramovsky <hagaya@mellanox.com> Signed-off-by: Eli Cohen <eli@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c10
-rw-r--r--drivers/infiniband/core/verbs.c14
-rw-r--r--include/rdma/ib_verbs.h13
3 files changed, 30 insertions, 7 deletions
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 5bb2a82d52e7..7f671b7b8bac 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -939,13 +939,9 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
939 if ((cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK)) 939 if ((cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK))
940 return -EINVAL; 940 return -EINVAL;
941 941
942 /* 942 ret = ib_check_mr_access(cmd.access_flags);
943 * Local write permission is required if remote write or 943 if (ret)
944 * remote atomic permission is also requested. 944 return ret;
945 */
946 if (cmd.access_flags & (IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_REMOTE_WRITE) &&
947 !(cmd.access_flags & IB_ACCESS_LOCAL_WRITE))
948 return -EINVAL;
949 945
950 uobj = kmalloc(sizeof *uobj, GFP_KERNEL); 946 uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
951 if (!uobj) 947 if (!uobj)
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 84f502785f89..d4f6ddf72ffa 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -961,6 +961,11 @@ EXPORT_SYMBOL(ib_resize_cq);
961struct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags) 961struct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags)
962{ 962{
963 struct ib_mr *mr; 963 struct ib_mr *mr;
964 int err;
965
966 err = ib_check_mr_access(mr_access_flags);
967 if (err)
968 return ERR_PTR(err);
964 969
965 mr = pd->device->get_dma_mr(pd, mr_access_flags); 970 mr = pd->device->get_dma_mr(pd, mr_access_flags);
966 971
@@ -983,6 +988,11 @@ struct ib_mr *ib_reg_phys_mr(struct ib_pd *pd,
983 u64 *iova_start) 988 u64 *iova_start)
984{ 989{
985 struct ib_mr *mr; 990 struct ib_mr *mr;
991 int err;
992
993 err = ib_check_mr_access(mr_access_flags);
994 if (err)
995 return ERR_PTR(err);
986 996
987 if (!pd->device->reg_phys_mr) 997 if (!pd->device->reg_phys_mr)
988 return ERR_PTR(-ENOSYS); 998 return ERR_PTR(-ENOSYS);
@@ -1013,6 +1023,10 @@ int ib_rereg_phys_mr(struct ib_mr *mr,
1013 struct ib_pd *old_pd; 1023 struct ib_pd *old_pd;
1014 int ret; 1024 int ret;
1015 1025
1026 ret = ib_check_mr_access(mr_access_flags);
1027 if (ret)
1028 return ret;
1029
1016 if (!mr->device->rereg_phys_mr) 1030 if (!mr->device->rereg_phys_mr)
1017 return -ENOSYS; 1031 return -ENOSYS;
1018 1032
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 60354d53948e..68c053d0d629 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -2386,4 +2386,17 @@ struct ib_flow *ib_create_flow(struct ib_qp *qp,
2386 struct ib_flow_attr *flow_attr, int domain); 2386 struct ib_flow_attr *flow_attr, int domain);
2387int ib_destroy_flow(struct ib_flow *flow_id); 2387int ib_destroy_flow(struct ib_flow *flow_id);
2388 2388
2389static inline int ib_check_mr_access(int flags)
2390{
2391 /*
2392 * Local write permission is required if remote write or
2393 * remote atomic permission is also requested.
2394 */
2395 if (flags & (IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_REMOTE_WRITE) &&
2396 !(flags & IB_ACCESS_LOCAL_WRITE))
2397 return -EINVAL;
2398
2399 return 0;
2400}
2401
2389#endif /* IB_VERBS_H */ 2402#endif /* IB_VERBS_H */