diff options
author | Eugenio Pérez <eperezma@redhat.com> | 2022-03-14 18:34:49 +0100 |
---|---|---|
committer | Jason Wang <jasowang@redhat.com> | 2022-03-15 13:57:44 +0800 |
commit | 193d17be0b84cce87db4426622cd4e6b827cae2a (patch) | |
tree | 1b834015c8ef48efd5dcc5a11de3010d70e6011e /util | |
parent | 9376bde894e444ebe2d2ec236569b6e55faa4765 (diff) | |
download | qemu-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')
-rw-r--r-- | util/iova-tree.c | 34 |
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 }; |