This function is a variant of iova_tree_foreach and support tranversing a range to trigger callback with a private data.
Signed-off-by: Zhenzhong Duan <zhenzhong.d...@intel.com> --- include/qemu/iova-tree.h | 17 +++++++++++++++-- util/iova-tree.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/include/qemu/iova-tree.h b/include/qemu/iova-tree.h index 8528e5c98fbc..8bbf049dc3f7 100644 --- a/include/qemu/iova-tree.h +++ b/include/qemu/iova-tree.h @@ -39,6 +39,7 @@ typedef struct DMAMap { IOMMUAccessFlags perm; } QEMU_PACKED DMAMap; typedef gboolean (*iova_tree_iterator)(DMAMap *map); +typedef gboolean (*iova_tree_iterator_2)(DMAMap *map, gpointer *private); /** * iova_tree_new: @@ -131,11 +132,23 @@ const DMAMap *iova_tree_find_address(const IOVATree *tree, hwaddr iova); * @iterator: the interator for the mappings, return true to stop * * Iterate over the iova tree. - * - * Return: 1 if found any overlap, 0 if not, <0 if error. */ void iova_tree_foreach(IOVATree *tree, iova_tree_iterator iterator); +/** + * iova_tree_foreach_range_data: + * + * @tree: the iova tree to iterate on + * @range: the iova range to iterate in + * @func: the iterator for the mappings, return true to stop + * @private: parameter passed to @func + * + * Iterate over an iova range in iova tree. + */ +void iova_tree_foreach_range_data(IOVATree *tree, DMAMap *range, + iova_tree_iterator_2 func, + gpointer *private); + /** * iova_tree_alloc_map: * diff --git a/util/iova-tree.c b/util/iova-tree.c index 536789797e47..a3cbd5198410 100644 --- a/util/iova-tree.c +++ b/util/iova-tree.c @@ -42,6 +42,12 @@ typedef struct IOVATreeFindIOVAArgs { const DMAMap *result; } IOVATreeFindIOVAArgs; +typedef struct IOVATreeIterator { + DMAMap *range; + iova_tree_iterator_2 func; + gpointer *private; +} IOVATreeIterator; + /** * Iterate args to the next hole * @@ -164,6 +170,31 @@ void iova_tree_foreach(IOVATree *tree, iova_tree_iterator iterator) g_tree_foreach(tree->tree, iova_tree_traverse, iterator); } +static gboolean iova_tree_traverse_range(gpointer key, gpointer value, + gpointer data) +{ + DMAMap *map = key; + IOVATreeIterator *iterator = data; + DMAMap *range = iterator->range; + + g_assert(key == value); + + if (iova_tree_compare(map, range, NULL)) { + return false; + } + + return iterator->func(map, iterator->private); +} + +void iova_tree_foreach_range_data(IOVATree *tree, DMAMap *range, + iova_tree_iterator_2 func, + gpointer *private) +{ + IOVATreeIterator iterator = {range, func, private}; + + g_tree_foreach(tree->tree, iova_tree_traverse_range, &iterator); +} + void iova_tree_remove(IOVATree *tree, DMAMap map) { const DMAMap *overlap; -- 2.34.1