diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
index 676b54c5cf53..cbe9910dbdff 100644
--- a/include/linux/iommufd.h
+++ b/include/linux/iommufd.h
@@ -235,6 +235,10 @@ struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
 					     size_t size,
 					     enum iommufd_object_type type);
 void iommufd_object_abort(struct iommufd_ctx *ictx, struct iommufd_object *obj);
+int _iommufd_object_depend(struct iommufd_object *obj_dependent,
+			   struct iommufd_object *obj_depended);
+void _iommufd_object_undepend(struct iommufd_object *obj_dependent,
+			      struct iommufd_object *obj_depended);
 struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu,
 				       unsigned long vdev_id);
 int iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
@@ -255,6 +259,18 @@ static inline void iommufd_object_abort(struct iommufd_ctx *ictx,
 {
 }
 
+static inline int _iommufd_object_depend(struct iommufd_object *obj_dependent,
+					 struct iommufd_object *obj_depended)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline void
+_iommufd_object_undepend(struct iommufd_object *obj_dependent,
+			 struct iommufd_object *obj_depended)
+{
+}
+
 static inline struct device *
 iommufd_viommu_find_dev(struct iommufd_viommu *viommu, unsigned long vdev_id)
 {
@@ -339,4 +355,36 @@ static inline int iommufd_viommu_report_event(struct iommufd_viommu *viommu,
 		iommufd_object_abort(drv_struct->member.ictx,                  \
 				     &drv_struct->member.obj);                 \
 	})
+
+/*
+ * Helpers for IOMMU driver to build/destroy a dependency between two sibling
+ * structures created by one of the allocators above
+ */
+#define iommufd_vqueue_depend(vqueue_dependent, vqueue_depended, member)       \
+	({                                                                     \
+		static_assert(__same_type(struct iommufd_vqueue,               \
+					  vqueue_dependent->member));          \
+		static_assert(offsetof(typeof(*vqueue_dependent),              \
+					      member.obj) == 0);               \
+		static_assert(__same_type(struct iommufd_vqueue,               \
+					  vqueue_depended->member));           \
+		static_assert(offsetof(typeof(*vqueue_depended),               \
+					      member.obj) == 0);               \
+		_iommufd_object_depend(&vqueue_dependent->member.obj,          \
+				       &vqueue_depended->member.obj);          \
+	})
+
+#define iommufd_vqueue_undepend(vqueue_dependent, vqueue_depended, member)     \
+	({                                                                     \
+		static_assert(__same_type(struct iommufd_vqueue,               \
+					  vqueue_dependent->member));          \
+		static_assert(offsetof(typeof(*vqueue_dependent),              \
+					      member.obj) == 0);               \
+		static_assert(__same_type(struct iommufd_vqueue,               \
+					  vqueue_depended->member));           \
+		static_assert(offsetof(typeof(*vqueue_depended),               \
+					      member.obj) == 0);               \
+		_iommufd_object_undepend(&vqueue_dependent->member.obj,        \
+					 &vqueue_depended->member.obj);        \
+	})
 #endif
diff --git a/drivers/iommu/iommufd/driver.c b/drivers/iommu/iommufd/driver.c
index 7980a09761c2..0bcf0438d255 100644
--- a/drivers/iommu/iommufd/driver.c
+++ b/drivers/iommu/iommufd/driver.c
@@ -50,6 +50,34 @@ void iommufd_object_abort(struct iommufd_ctx *ictx, struct iommufd_object *obj)
 }
 EXPORT_SYMBOL_NS_GPL(iommufd_object_abort, "IOMMUFD");
 
+/* Driver should use a per-structure helper in include/linux/iommufd.h */
+int _iommufd_object_depend(struct iommufd_object *obj_dependent,
+			   struct iommufd_object *obj_depended)
+{
+	/* Reject self dependency that dead locks */
+	if (obj_dependent == obj_depended)
+		return -EINVAL;
+	/* Only support dependency between two objects of the same type */
+	if (obj_dependent->type != obj_depended->type)
+		return -EINVAL;
+
+	refcount_inc(&obj_depended->users);
+	return 0;
+}
+EXPORT_SYMBOL_NS_GPL(_iommufd_object_depend, "IOMMUFD");
+
+/* Driver should use a per-structure helper in include/linux/iommufd.h */
+void _iommufd_object_undepend(struct iommufd_object *obj_dependent,
+			      struct iommufd_object *obj_depended)
+{
+	if (WARN_ON_ONCE(obj_dependent == obj_depended ||
+			 obj_dependent->type != obj_depended->type))
+		return;
+
+	refcount_dec(&obj_depended->users);
+}
+EXPORT_SYMBOL_NS_GPL(_iommufd_object_undepend, "IOMMUFD");
+
 /* Caller should xa_lock(&viommu->vdevs) to protect the return value */
 struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu,
 				       unsigned long vdev_id)
