1
2
3
4
5
6
7
8
9
10#include "qemu/osdep.h"
11#include "qemu/iova-tree.h"
12#include "vhost-iova-tree.h"
13
14#define iova_min_addr qemu_real_host_page_size()
15
16
17
18
19
20
21
22struct VhostIOVATree {
23
24 uint64_t iova_first;
25
26
27 uint64_t iova_last;
28
29
30 IOVATree *iova_taddr_map;
31};
32
33
34
35
36
37
38VhostIOVATree *vhost_iova_tree_new(hwaddr iova_first, hwaddr iova_last)
39{
40 VhostIOVATree *tree = g_new(VhostIOVATree, 1);
41
42
43 tree->iova_first = MAX(iova_first, iova_min_addr);
44 tree->iova_last = iova_last;
45
46 tree->iova_taddr_map = iova_tree_new();
47 return tree;
48}
49
50
51
52
53void vhost_iova_tree_delete(VhostIOVATree *iova_tree)
54{
55 iova_tree_destroy(iova_tree->iova_taddr_map);
56 g_free(iova_tree);
57}
58
59
60
61
62
63
64
65
66
67const DMAMap *vhost_iova_tree_find_iova(const VhostIOVATree *tree,
68 const DMAMap *map)
69{
70 return iova_tree_find_iova(tree->iova_taddr_map, map);
71}
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86int vhost_iova_tree_map_alloc(VhostIOVATree *tree, DMAMap *map)
87{
88
89 hwaddr iova_first = tree->iova_first ?: qemu_real_host_page_size();
90
91 if (map->translated_addr + map->size < map->translated_addr ||
92 map->perm == IOMMU_NONE) {
93 return IOVA_ERR_INVALID;
94 }
95
96
97 return iova_tree_alloc_map(tree->iova_taddr_map, map, iova_first,
98 tree->iova_last);
99}
100
101
102
103
104
105
106
107void vhost_iova_tree_remove(VhostIOVATree *iova_tree, const DMAMap *map)
108{
109 iova_tree_remove(iova_tree->iova_taddr_map, map);
110}
111