diff --git a/debian/ibverbs-providers.symbols b/debian/ibverbs-providers.symbols
index acd1715..9bab750 100644
--- a/debian/ibverbs-providers.symbols
+++ b/debian/ibverbs-providers.symbols
@@ -33,3 +33,5 @@ libmlx5.so.1 ibverbs-providers #MINVER#
  mlx5dv_devx_obj_destroy@MLX5_1.7 21
  mlx5dv_devx_obj_query@MLX5_1.7 21
  mlx5dv_devx_obj_modify@MLX5_1.7 21
+ mlx5dv_devx_umem_dereg@MLX5_1.7 21
+ mlx5dv_devx_umem_reg@MLX5_1.7 21
diff --git a/providers/mlx5/libmlx5.map b/providers/mlx5/libmlx5.map
index 91a7a32..d0499cd 100644
--- a/providers/mlx5/libmlx5.map
+++ b/providers/mlx5/libmlx5.map
@@ -51,4 +51,6 @@ MLX5_1.7 {
 		mlx5dv_devx_obj_destroy;
 		mlx5dv_devx_obj_query;
 		mlx5dv_devx_obj_modify;
+		mlx5dv_devx_umem_dereg;
+		mlx5dv_devx_umem_reg;
 } MLX5_1.6;
diff --git a/providers/mlx5/man/CMakeLists.txt b/providers/mlx5/man/CMakeLists.txt
index 8d5d8e2..72a50e0 100644
--- a/providers/mlx5/man/CMakeLists.txt
+++ b/providers/mlx5/man/CMakeLists.txt
@@ -5,6 +5,7 @@ rdma_man_pages(
   mlx5dv_create_flow_matcher.3.md
   mlx5dv_create_qp.3.md
   mlx5dv_devx_obj_create.3.md
+  mlx5dv_devx_umem_reg.3.md
   mlx5dv_flow_action_esp.3.md
   mlx5dv_get_clock_info.3
   mlx5dv_init_obj.3
@@ -18,4 +19,5 @@ rdma_alias_man_pages(
  mlx5dv_devx_obj_create.3 mlx5dv_devx_obj_destroy.3
  mlx5dv_devx_obj_create.3 mlx5dv_devx_obj_query.3
  mlx5dv_devx_obj_create.3 mlx5dv_devx_obj_modify.3
+ mlx5dv_devx_umem_reg.3 mlx5dv_devx_umem_dereg.3
 )
diff --git a/providers/mlx5/man/mlx5dv_devx_umem_reg.3.md b/providers/mlx5/man/mlx5dv_devx_umem_reg.3.md
new file mode 100644
index 0000000..c829d54
--- /dev/null
+++ b/providers/mlx5/man/mlx5dv_devx_umem_reg.3.md
@@ -0,0 +1,58 @@
+
+---
+layout: page
+title: mlx5dv_devx_umem_reg, mlx5dv_devx_umem_dereg
+section: 3
+tagline: Verbs
+---
+
+# NAME
+
+mlx5dv_devx_umem_reg - Register a user memory to be used by the devx interface
+
+mlx5dv_devx_umem_dereg - Deregister a devx umem object
+
+# SYNOPSIS
+
+```c
+#include <infiniband/mlx5dv.h>
+
+struct mlx5dv_devx_umem *
+mlx5dv_devx_umem_reg(struct ibv_context *context, void *addr, size_t size,
+		     uint32_t access)
+
+int mlx5dv_devx_umem_dereg(struct mlx5dv_devx_umem *dv_devx_umem)
+```
+
+# DESCRIPTION
+
+Register or deregister a user memory to be used by the devx interface.
+
+# ARGUMENTS
+*context*
+:       RDMA device context to create the action on.
+
+*addr*
+:	The memory start address to register.
+
+*size*
+:       The size of *addr* buffer.
+
+*access*
+:	The desired memory protection attributes; it is either 0 or the bitwise OR of one or more of *enum ibv_access_flags*.
+
+
+# RETURN VALUE
+
+Upon success *mlx5dv_devx_umem_reg* will return a new *struct
+mlx5dv_devx_umem* object, on error NULL will be returned and errno will be set.
+
+*mlx5dv_devx_umem_dereg* returns 0 on success, or the value of errno on failure (which indicates the failure reason).
+
+# SEE ALSO
+
+*mlx5dv_open_device(3)*, *ibv_reg_mr(3)*
+
+#AUTHOR
+
+Yishai Hadas <yishaih@mellanox.com>
diff --git a/providers/mlx5/mlx5.h b/providers/mlx5/mlx5.h
index 91fbc50..61240ed 100644
--- a/providers/mlx5/mlx5.h
+++ b/providers/mlx5/mlx5.h
@@ -572,6 +572,12 @@ struct mlx5dv_devx_obj {
 	uint32_t handle;
 };
 
+struct mlx5_devx_umem {
+	struct mlx5dv_devx_umem dv_devx_umem;
+	struct ibv_context *context;
+	uint32_t handle;
+};
+
 static inline int mlx5_ilog2(int n)
 {
 	int t;
diff --git a/providers/mlx5/mlx5dv.h b/providers/mlx5/mlx5dv.h
index 662433b..0385b68 100644
--- a/providers/mlx5/mlx5dv.h
+++ b/providers/mlx5/mlx5dv.h
@@ -1027,6 +1027,15 @@ int mlx5dv_devx_obj_modify(struct mlx5dv_devx_obj *obj, const void *in, size_t i
 int mlx5dv_devx_obj_destroy(struct mlx5dv_devx_obj *obj);
 int mlx5dv_devx_general_cmd(struct ibv_context *context, const void *in, size_t inlen,
 			    void *out, size_t outlen);
+
+struct mlx5dv_devx_umem {
+	uint32_t umem_id;
+};
+
+struct mlx5dv_devx_umem *
+mlx5dv_devx_umem_reg(struct ibv_context *ctx, void *addr, size_t size, uint32_t access);
+int mlx5dv_devx_umem_dereg(struct mlx5dv_devx_umem *umem);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/providers/mlx5/verbs.c b/providers/mlx5/verbs.c
index f476bc5..a8a7fa3 100644
--- a/providers/mlx5/verbs.c
+++ b/providers/mlx5/verbs.c
@@ -3843,6 +3843,63 @@ err:
 	return NULL;
 }
 
+struct mlx5dv_devx_umem *
+mlx5dv_devx_umem_reg(struct ibv_context *context, void *addr, size_t size, uint32_t access)
+{
+	DECLARE_COMMAND_BUFFER(cmd,
+			       MLX5_IB_OBJECT_DEVX_UMEM,
+			       MLX5_IB_METHOD_DEVX_UMEM_REG,
+			       5);
+	struct ib_uverbs_attr *handle;
+	struct mlx5_devx_umem *umem;
+	int ret;
+
+	umem = calloc(1, sizeof(*umem));
+	if (!umem) {
+		errno = ENOMEM;
+		return NULL;
+	}
+
+	fill_attr_in_uint64(cmd, MLX5_IB_ATTR_DEVX_UMEM_REG_ADDR, (intptr_t)addr);
+	fill_attr_in_uint64(cmd, MLX5_IB_ATTR_DEVX_UMEM_REG_LEN, size);
+	fill_attr_in_uint32(cmd, MLX5_IB_ATTR_DEVX_UMEM_REG_ACCESS, access);
+	fill_attr_out(cmd, MLX5_IB_ATTR_DEVX_UMEM_REG_OUT_ID,
+		      &umem->dv_devx_umem.umem_id,
+		      sizeof(umem->dv_devx_umem.umem_id));
+	handle = fill_attr_out_obj(cmd, MLX5_IB_ATTR_DEVX_UMEM_REG_HANDLE);
+
+	ret = execute_ioctl(context, cmd);
+	if (ret)
+		goto err;
+
+	umem->handle = read_attr_obj(MLX5_IB_ATTR_DEVX_UMEM_REG_HANDLE, handle);
+	umem->context = context;
+
+	return &umem->dv_devx_umem;
+err:
+	free(umem);
+	return NULL;
+}
+
+int mlx5dv_devx_umem_dereg(struct mlx5dv_devx_umem *dv_devx_umem)
+{
+	DECLARE_COMMAND_BUFFER(cmd,
+			       MLX5_IB_OBJECT_DEVX_UMEM,
+			       MLX5_IB_METHOD_DEVX_UMEM_DEREG,
+			       1);
+	int ret;
+	struct mlx5_devx_umem *umem = container_of(dv_devx_umem, struct mlx5_devx_umem,
+						    dv_devx_umem);
+
+	fill_attr_in_obj(cmd, MLX5_IB_ATTR_DEVX_UMEM_DEREG_HANDLE, umem->handle);
+	ret = execute_ioctl(umem->context, cmd);
+	if (ret)
+		return ret;
+
+	free(umem);
+	return 0;
+}
+
 struct mlx5dv_devx_obj *
 mlx5dv_devx_obj_create(struct ibv_context *context, const void *in, size_t inlen,
 				void *out, size_t outlen)
