@@ -113,6 +113,13 @@ void rxe_mr_init_dma(struct rxe_pd *pd, int access, struct rxe_mr *mr)
mr->type = IB_MR_TYPE_DMA;
}
+static bool vaddr_in_pmem(char *vaddr)
+{
+ return REGION_INTERSECTS ==
+ region_intersects(virt_to_phys(vaddr), 1, IORESOURCE_MEM,
+ IORES_DESC_PERSISTENT_MEMORY);
+}
+
int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
int access, struct rxe_mr *mr)
{
@@ -123,6 +130,7 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
int num_buf;
void *vaddr;
int err;
+ bool first = true, is_pmem = false;
int i;
umem = ib_umem_get(pd->ibpd.device, start, length, access);
@@ -167,6 +175,11 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
goto err_cleanup_map;
}
+ if (first) {
+ first = false;
+ is_pmem = vaddr_in_pmem(vaddr);
+ }
+
buf->addr = (uintptr_t)vaddr;
buf->size = PAGE_SIZE;
num_buf++;
@@ -175,6 +188,12 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
}
}
+ if (!is_pmem && access & IB_ACCESS_FLUSH_PERSISTENT) {
+ pr_warn("Cannot register IB_ACCESS_FLUSH_PERSISTENT for non-pmem memory\n");
+ err = -EINVAL;
+ goto err_release_umem;
+ }
+
mr->ibmr.pd = &pd->ibpd;
mr->umem = umem;
mr->access = access;
Memory region could at most support 2 access flags: IB_ACCESS_FLUSH_PERSISTENT and IB_ACCESS_FLUSH_GLOBAL_VISIBILITY But we only allow user to register persistent flush flags to the pmem MR that supports the ability of persisting data across power cycles. So register a persistent access flag to a non-pmem MR will be rejected by kernel. Signed-off-by: Li Zhijian <lizhijian@fujitsu.com> --- v2: update commit message, get rid of confusing ib_check_flush_access_flags() # Tom --- drivers/infiniband/sw/rxe/rxe_mr.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)