aboutsummaryrefslogtreecommitdiff
path: root/util/iova-tree.c
diff options
context:
space:
mode:
authorEugenio Pérez <eperezma@redhat.com>2022-03-14 18:34:49 +0100
committerJason Wang <jasowang@redhat.com>2022-03-15 13:57:44 +0800
commit193d17be0b84cce87db4426622cd4e6b827cae2a (patch)
tree1b834015c8ef48efd5dcc5a11de3010d70e6011e /util/iova-tree.c
parent9376bde894e444ebe2d2ec236569b6e55faa4765 (diff)
downloadqemu-193d17be0b84cce87db4426622cd4e6b827cae2a.zip
qemu-193d17be0b84cce87db4426622cd4e6b827cae2a.tar.gz
qemu-193d17be0b84cce87db4426622cd4e6b827cae2a.tar.bz2
util: add iova_tree_find_iova
This function does the reverse operation of iova_tree_find: To look for a mapping that match a translated address so we can do the reverse. This have linear complexity instead of logarithmic, but it supports overlapping HVA. Future developments could reduce it. Signed-off-by: Eugenio Pérez <eperezma@redhat.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Jason Wang <jasowang@redhat.com>
Diffstat (limited to 'util/iova-tree.c')
-rw-r--r--util/iova-tree.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/util/iova-tree.c b/util/iova-tree.c
index 139626b..6dff29c 100644
--- a/util/iova-tree.c
+++ b/util/iova-tree.c
@@ -37,6 +37,11 @@ struct IOVATreeAllocArgs {
bool iova_found;
};
+typedef struct IOVATreeFindIOVAArgs {
+ const DMAMap *needle;
+ const DMAMap *result;
+} IOVATreeFindIOVAArgs;
+
/**
* Iterate args to the next hole
*
@@ -81,6 +86,35 @@ const DMAMap *iova_tree_find(const IOVATree *tree, const DMAMap *map)
return g_tree_lookup(tree->tree, map);
}
+static gboolean iova_tree_find_address_iterator(gpointer key, gpointer value,
+ gpointer data)
+{
+ const DMAMap *map = key;
+ IOVATreeFindIOVAArgs *args = data;
+ const DMAMap *needle;
+
+ g_assert(key == value);
+
+ needle = args->needle;
+ if (map->translated_addr + map->size < needle->translated_addr ||
+ needle->translated_addr + needle->size < map->translated_addr) {
+ return false;
+ }
+
+ args->result = map;
+ return true;
+}
+
+const DMAMap *iova_tree_find_iova(const IOVATree *tree, const DMAMap *map)
+{
+ IOVATreeFindIOVAArgs args = {
+ .needle = map,
+ };
+
+ g_tree_foreach(tree->tree, iova_tree_find_address_iterator, &args);
+ return args.result;
+}
+
const DMAMap *iova_tree_find_address(const IOVATree *tree, hwaddr iova)
{
const DMAMap map = { .iova = iova, .size = 0 };