Statistics
| Branch: | Revision:

root / memory.c @ 750ecd44

History | View | Annotate | Download (43.4 kB)

1 093bc2cd Avi Kivity
/*
2 093bc2cd Avi Kivity
 * Physical memory management
3 093bc2cd Avi Kivity
 *
4 093bc2cd Avi Kivity
 * Copyright 2011 Red Hat, Inc. and/or its affiliates
5 093bc2cd Avi Kivity
 *
6 093bc2cd Avi Kivity
 * Authors:
7 093bc2cd Avi Kivity
 *  Avi Kivity <avi@redhat.com>
8 093bc2cd Avi Kivity
 *
9 093bc2cd Avi Kivity
 * This work is licensed under the terms of the GNU GPL, version 2.  See
10 093bc2cd Avi Kivity
 * the COPYING file in the top-level directory.
11 093bc2cd Avi Kivity
 *
12 093bc2cd Avi Kivity
 */
13 093bc2cd Avi Kivity
14 093bc2cd Avi Kivity
#include "memory.h"
15 1c0ffa58 Avi Kivity
#include "exec-memory.h"
16 658b2224 Avi Kivity
#include "ioport.h"
17 74901c3b Avi Kivity
#include "bitops.h"
18 3e9d69e7 Avi Kivity
#include "kvm.h"
19 093bc2cd Avi Kivity
#include <assert.h>
20 093bc2cd Avi Kivity
21 4ef4db86 Avi Kivity
unsigned memory_region_transaction_depth = 0;
22 4ef4db86 Avi Kivity
23 093bc2cd Avi Kivity
typedef struct AddrRange AddrRange;
24 093bc2cd Avi Kivity
25 8417cebf Avi Kivity
/*
26 8417cebf Avi Kivity
 * Note using signed integers limits us to physical addresses at most
27 8417cebf Avi Kivity
 * 63 bits wide.  They are needed for negative offsetting in aliases
28 8417cebf Avi Kivity
 * (large MemoryRegion::alias_offset).
29 8417cebf Avi Kivity
 */
30 093bc2cd Avi Kivity
struct AddrRange {
31 08dafab4 Avi Kivity
    Int128 start;
32 08dafab4 Avi Kivity
    Int128 size;
33 093bc2cd Avi Kivity
};
34 093bc2cd Avi Kivity
35 08dafab4 Avi Kivity
static AddrRange addrrange_make(Int128 start, Int128 size)
36 093bc2cd Avi Kivity
{
37 093bc2cd Avi Kivity
    return (AddrRange) { start, size };
38 093bc2cd Avi Kivity
}
39 093bc2cd Avi Kivity
40 093bc2cd Avi Kivity
static bool addrrange_equal(AddrRange r1, AddrRange r2)
41 093bc2cd Avi Kivity
{
42 08dafab4 Avi Kivity
    return int128_eq(r1.start, r2.start) && int128_eq(r1.size, r2.size);
43 093bc2cd Avi Kivity
}
44 093bc2cd Avi Kivity
45 08dafab4 Avi Kivity
static Int128 addrrange_end(AddrRange r)
46 093bc2cd Avi Kivity
{
47 08dafab4 Avi Kivity
    return int128_add(r.start, r.size);
48 093bc2cd Avi Kivity
}
49 093bc2cd Avi Kivity
50 08dafab4 Avi Kivity
static AddrRange addrrange_shift(AddrRange range, Int128 delta)
51 093bc2cd Avi Kivity
{
52 08dafab4 Avi Kivity
    int128_addto(&range.start, delta);
53 093bc2cd Avi Kivity
    return range;
54 093bc2cd Avi Kivity
}
55 093bc2cd Avi Kivity
56 08dafab4 Avi Kivity
static bool addrrange_contains(AddrRange range, Int128 addr)
57 08dafab4 Avi Kivity
{
58 08dafab4 Avi Kivity
    return int128_ge(addr, range.start)
59 08dafab4 Avi Kivity
        && int128_lt(addr, addrrange_end(range));
60 08dafab4 Avi Kivity
}
61 08dafab4 Avi Kivity
62 093bc2cd Avi Kivity
static bool addrrange_intersects(AddrRange r1, AddrRange r2)
63 093bc2cd Avi Kivity
{
64 08dafab4 Avi Kivity
    return addrrange_contains(r1, r2.start)
65 08dafab4 Avi Kivity
        || addrrange_contains(r2, r1.start);
66 093bc2cd Avi Kivity
}
67 093bc2cd Avi Kivity
68 093bc2cd Avi Kivity
static AddrRange addrrange_intersection(AddrRange r1, AddrRange r2)
69 093bc2cd Avi Kivity
{
70 08dafab4 Avi Kivity
    Int128 start = int128_max(r1.start, r2.start);
71 08dafab4 Avi Kivity
    Int128 end = int128_min(addrrange_end(r1), addrrange_end(r2));
72 08dafab4 Avi Kivity
    return addrrange_make(start, int128_sub(end, start));
73 093bc2cd Avi Kivity
}
74 093bc2cd Avi Kivity
75 093bc2cd Avi Kivity
struct CoalescedMemoryRange {
76 093bc2cd Avi Kivity
    AddrRange addr;
77 093bc2cd Avi Kivity
    QTAILQ_ENTRY(CoalescedMemoryRange) link;
78 093bc2cd Avi Kivity
};
79 093bc2cd Avi Kivity
80 3e9d69e7 Avi Kivity
struct MemoryRegionIoeventfd {
81 3e9d69e7 Avi Kivity
    AddrRange addr;
82 3e9d69e7 Avi Kivity
    bool match_data;
83 3e9d69e7 Avi Kivity
    uint64_t data;
84 3e9d69e7 Avi Kivity
    int fd;
85 3e9d69e7 Avi Kivity
};
86 3e9d69e7 Avi Kivity
87 3e9d69e7 Avi Kivity
static bool memory_region_ioeventfd_before(MemoryRegionIoeventfd a,
88 3e9d69e7 Avi Kivity
                                           MemoryRegionIoeventfd b)
89 3e9d69e7 Avi Kivity
{
90 08dafab4 Avi Kivity
    if (int128_lt(a.addr.start, b.addr.start)) {
91 3e9d69e7 Avi Kivity
        return true;
92 08dafab4 Avi Kivity
    } else if (int128_gt(a.addr.start, b.addr.start)) {
93 3e9d69e7 Avi Kivity
        return false;
94 08dafab4 Avi Kivity
    } else if (int128_lt(a.addr.size, b.addr.size)) {
95 3e9d69e7 Avi Kivity
        return true;
96 08dafab4 Avi Kivity
    } else if (int128_gt(a.addr.size, b.addr.size)) {
97 3e9d69e7 Avi Kivity
        return false;
98 3e9d69e7 Avi Kivity
    } else if (a.match_data < b.match_data) {
99 3e9d69e7 Avi Kivity
        return true;
100 3e9d69e7 Avi Kivity
    } else  if (a.match_data > b.match_data) {
101 3e9d69e7 Avi Kivity
        return false;
102 3e9d69e7 Avi Kivity
    } else if (a.match_data) {
103 3e9d69e7 Avi Kivity
        if (a.data < b.data) {
104 3e9d69e7 Avi Kivity
            return true;
105 3e9d69e7 Avi Kivity
        } else if (a.data > b.data) {
106 3e9d69e7 Avi Kivity
            return false;
107 3e9d69e7 Avi Kivity
        }
108 3e9d69e7 Avi Kivity
    }
109 3e9d69e7 Avi Kivity
    if (a.fd < b.fd) {
110 3e9d69e7 Avi Kivity
        return true;
111 3e9d69e7 Avi Kivity
    } else if (a.fd > b.fd) {
112 3e9d69e7 Avi Kivity
        return false;
113 3e9d69e7 Avi Kivity
    }
114 3e9d69e7 Avi Kivity
    return false;
115 3e9d69e7 Avi Kivity
}
116 3e9d69e7 Avi Kivity
117 3e9d69e7 Avi Kivity
static bool memory_region_ioeventfd_equal(MemoryRegionIoeventfd a,
118 3e9d69e7 Avi Kivity
                                          MemoryRegionIoeventfd b)
119 3e9d69e7 Avi Kivity
{
120 3e9d69e7 Avi Kivity
    return !memory_region_ioeventfd_before(a, b)
121 3e9d69e7 Avi Kivity
        && !memory_region_ioeventfd_before(b, a);
122 3e9d69e7 Avi Kivity
}
123 3e9d69e7 Avi Kivity
124 093bc2cd Avi Kivity
typedef struct FlatRange FlatRange;
125 093bc2cd Avi Kivity
typedef struct FlatView FlatView;
126 093bc2cd Avi Kivity
127 093bc2cd Avi Kivity
/* Range of memory in the global map.  Addresses are absolute. */
128 093bc2cd Avi Kivity
struct FlatRange {
129 093bc2cd Avi Kivity
    MemoryRegion *mr;
130 093bc2cd Avi Kivity
    target_phys_addr_t offset_in_region;
131 093bc2cd Avi Kivity
    AddrRange addr;
132 5a583347 Avi Kivity
    uint8_t dirty_log_mask;
133 d0a9b5bc Avi Kivity
    bool readable;
134 fb1cd6f9 Avi Kivity
    bool readonly;
135 093bc2cd Avi Kivity
};
136 093bc2cd Avi Kivity
137 093bc2cd Avi Kivity
/* Flattened global view of current active memory hierarchy.  Kept in sorted
138 093bc2cd Avi Kivity
 * order.
139 093bc2cd Avi Kivity
 */
140 093bc2cd Avi Kivity
struct FlatView {
141 093bc2cd Avi Kivity
    FlatRange *ranges;
142 093bc2cd Avi Kivity
    unsigned nr;
143 093bc2cd Avi Kivity
    unsigned nr_allocated;
144 093bc2cd Avi Kivity
};
145 093bc2cd Avi Kivity
146 cc31e6e7 Avi Kivity
typedef struct AddressSpace AddressSpace;
147 cc31e6e7 Avi Kivity
typedef struct AddressSpaceOps AddressSpaceOps;
148 cc31e6e7 Avi Kivity
149 cc31e6e7 Avi Kivity
/* A system address space - I/O, memory, etc. */
150 cc31e6e7 Avi Kivity
struct AddressSpace {
151 cc31e6e7 Avi Kivity
    const AddressSpaceOps *ops;
152 cc31e6e7 Avi Kivity
    MemoryRegion *root;
153 cc31e6e7 Avi Kivity
    FlatView current_map;
154 3e9d69e7 Avi Kivity
    int ioeventfd_nb;
155 3e9d69e7 Avi Kivity
    MemoryRegionIoeventfd *ioeventfds;
156 cc31e6e7 Avi Kivity
};
157 cc31e6e7 Avi Kivity
158 cc31e6e7 Avi Kivity
struct AddressSpaceOps {
159 cc31e6e7 Avi Kivity
    void (*range_add)(AddressSpace *as, FlatRange *fr);
160 cc31e6e7 Avi Kivity
    void (*range_del)(AddressSpace *as, FlatRange *fr);
161 cc31e6e7 Avi Kivity
    void (*log_start)(AddressSpace *as, FlatRange *fr);
162 cc31e6e7 Avi Kivity
    void (*log_stop)(AddressSpace *as, FlatRange *fr);
163 3e9d69e7 Avi Kivity
    void (*ioeventfd_add)(AddressSpace *as, MemoryRegionIoeventfd *fd);
164 3e9d69e7 Avi Kivity
    void (*ioeventfd_del)(AddressSpace *as, MemoryRegionIoeventfd *fd);
165 cc31e6e7 Avi Kivity
};
166 cc31e6e7 Avi Kivity
167 093bc2cd Avi Kivity
#define FOR_EACH_FLAT_RANGE(var, view)          \
168 093bc2cd Avi Kivity
    for (var = (view)->ranges; var < (view)->ranges + (view)->nr; ++var)
169 093bc2cd Avi Kivity
170 093bc2cd Avi Kivity
static bool flatrange_equal(FlatRange *a, FlatRange *b)
171 093bc2cd Avi Kivity
{
172 093bc2cd Avi Kivity
    return a->mr == b->mr
173 093bc2cd Avi Kivity
        && addrrange_equal(a->addr, b->addr)
174 d0a9b5bc Avi Kivity
        && a->offset_in_region == b->offset_in_region
175 fb1cd6f9 Avi Kivity
        && a->readable == b->readable
176 fb1cd6f9 Avi Kivity
        && a->readonly == b->readonly;
177 093bc2cd Avi Kivity
}
178 093bc2cd Avi Kivity
179 093bc2cd Avi Kivity
static void flatview_init(FlatView *view)
180 093bc2cd Avi Kivity
{
181 093bc2cd Avi Kivity
    view->ranges = NULL;
182 093bc2cd Avi Kivity
    view->nr = 0;
183 093bc2cd Avi Kivity
    view->nr_allocated = 0;
184 093bc2cd Avi Kivity
}
185 093bc2cd Avi Kivity
186 093bc2cd Avi Kivity
/* Insert a range into a given position.  Caller is responsible for maintaining
187 093bc2cd Avi Kivity
 * sorting order.
188 093bc2cd Avi Kivity
 */
189 093bc2cd Avi Kivity
static void flatview_insert(FlatView *view, unsigned pos, FlatRange *range)
190 093bc2cd Avi Kivity
{
191 093bc2cd Avi Kivity
    if (view->nr == view->nr_allocated) {
192 093bc2cd Avi Kivity
        view->nr_allocated = MAX(2 * view->nr, 10);
193 7267c094 Anthony Liguori
        view->ranges = g_realloc(view->ranges,
194 093bc2cd Avi Kivity
                                    view->nr_allocated * sizeof(*view->ranges));
195 093bc2cd Avi Kivity
    }
196 093bc2cd Avi Kivity
    memmove(view->ranges + pos + 1, view->ranges + pos,
197 093bc2cd Avi Kivity
            (view->nr - pos) * sizeof(FlatRange));
198 093bc2cd Avi Kivity
    view->ranges[pos] = *range;
199 093bc2cd Avi Kivity
    ++view->nr;
200 093bc2cd Avi Kivity
}
201 093bc2cd Avi Kivity
202 093bc2cd Avi Kivity
static void flatview_destroy(FlatView *view)
203 093bc2cd Avi Kivity
{
204 7267c094 Anthony Liguori
    g_free(view->ranges);
205 093bc2cd Avi Kivity
}
206 093bc2cd Avi Kivity
207 3d8e6bf9 Avi Kivity
static bool can_merge(FlatRange *r1, FlatRange *r2)
208 3d8e6bf9 Avi Kivity
{
209 08dafab4 Avi Kivity
    return int128_eq(addrrange_end(r1->addr), r2->addr.start)
210 3d8e6bf9 Avi Kivity
        && r1->mr == r2->mr
211 08dafab4 Avi Kivity
        && int128_eq(int128_add(int128_make64(r1->offset_in_region),
212 08dafab4 Avi Kivity
                                r1->addr.size),
213 08dafab4 Avi Kivity
                     int128_make64(r2->offset_in_region))
214 d0a9b5bc Avi Kivity
        && r1->dirty_log_mask == r2->dirty_log_mask
215 fb1cd6f9 Avi Kivity
        && r1->readable == r2->readable
216 fb1cd6f9 Avi Kivity
        && r1->readonly == r2->readonly;
217 3d8e6bf9 Avi Kivity
}
218 3d8e6bf9 Avi Kivity
219 3d8e6bf9 Avi Kivity
/* Attempt to simplify a view by merging ajacent ranges */
220 3d8e6bf9 Avi Kivity
static void flatview_simplify(FlatView *view)
221 3d8e6bf9 Avi Kivity
{
222 3d8e6bf9 Avi Kivity
    unsigned i, j;
223 3d8e6bf9 Avi Kivity
224 3d8e6bf9 Avi Kivity
    i = 0;
225 3d8e6bf9 Avi Kivity
    while (i < view->nr) {
226 3d8e6bf9 Avi Kivity
        j = i + 1;
227 3d8e6bf9 Avi Kivity
        while (j < view->nr
228 3d8e6bf9 Avi Kivity
               && can_merge(&view->ranges[j-1], &view->ranges[j])) {
229 08dafab4 Avi Kivity
            int128_addto(&view->ranges[i].addr.size, view->ranges[j].addr.size);
230 3d8e6bf9 Avi Kivity
            ++j;
231 3d8e6bf9 Avi Kivity
        }
232 3d8e6bf9 Avi Kivity
        ++i;
233 3d8e6bf9 Avi Kivity
        memmove(&view->ranges[i], &view->ranges[j],
234 3d8e6bf9 Avi Kivity
                (view->nr - j) * sizeof(view->ranges[j]));
235 3d8e6bf9 Avi Kivity
        view->nr -= j - i;
236 3d8e6bf9 Avi Kivity
    }
237 3d8e6bf9 Avi Kivity
}
238 3d8e6bf9 Avi Kivity
239 164a4dcd Avi Kivity
static void memory_region_read_accessor(void *opaque,
240 164a4dcd Avi Kivity
                                        target_phys_addr_t addr,
241 164a4dcd Avi Kivity
                                        uint64_t *value,
242 164a4dcd Avi Kivity
                                        unsigned size,
243 164a4dcd Avi Kivity
                                        unsigned shift,
244 164a4dcd Avi Kivity
                                        uint64_t mask)
245 164a4dcd Avi Kivity
{
246 164a4dcd Avi Kivity
    MemoryRegion *mr = opaque;
247 164a4dcd Avi Kivity
    uint64_t tmp;
248 164a4dcd Avi Kivity
249 164a4dcd Avi Kivity
    tmp = mr->ops->read(mr->opaque, addr, size);
250 164a4dcd Avi Kivity
    *value |= (tmp & mask) << shift;
251 164a4dcd Avi Kivity
}
252 164a4dcd Avi Kivity
253 164a4dcd Avi Kivity
static void memory_region_write_accessor(void *opaque,
254 164a4dcd Avi Kivity
                                         target_phys_addr_t addr,
255 164a4dcd Avi Kivity
                                         uint64_t *value,
256 164a4dcd Avi Kivity
                                         unsigned size,
257 164a4dcd Avi Kivity
                                         unsigned shift,
258 164a4dcd Avi Kivity
                                         uint64_t mask)
259 164a4dcd Avi Kivity
{
260 164a4dcd Avi Kivity
    MemoryRegion *mr = opaque;
261 164a4dcd Avi Kivity
    uint64_t tmp;
262 164a4dcd Avi Kivity
263 164a4dcd Avi Kivity
    tmp = (*value >> shift) & mask;
264 164a4dcd Avi Kivity
    mr->ops->write(mr->opaque, addr, tmp, size);
265 164a4dcd Avi Kivity
}
266 164a4dcd Avi Kivity
267 164a4dcd Avi Kivity
static void access_with_adjusted_size(target_phys_addr_t addr,
268 164a4dcd Avi Kivity
                                      uint64_t *value,
269 164a4dcd Avi Kivity
                                      unsigned size,
270 164a4dcd Avi Kivity
                                      unsigned access_size_min,
271 164a4dcd Avi Kivity
                                      unsigned access_size_max,
272 164a4dcd Avi Kivity
                                      void (*access)(void *opaque,
273 164a4dcd Avi Kivity
                                                     target_phys_addr_t addr,
274 164a4dcd Avi Kivity
                                                     uint64_t *value,
275 164a4dcd Avi Kivity
                                                     unsigned size,
276 164a4dcd Avi Kivity
                                                     unsigned shift,
277 164a4dcd Avi Kivity
                                                     uint64_t mask),
278 164a4dcd Avi Kivity
                                      void *opaque)
279 164a4dcd Avi Kivity
{
280 164a4dcd Avi Kivity
    uint64_t access_mask;
281 164a4dcd Avi Kivity
    unsigned access_size;
282 164a4dcd Avi Kivity
    unsigned i;
283 164a4dcd Avi Kivity
284 164a4dcd Avi Kivity
    if (!access_size_min) {
285 164a4dcd Avi Kivity
        access_size_min = 1;
286 164a4dcd Avi Kivity
    }
287 164a4dcd Avi Kivity
    if (!access_size_max) {
288 164a4dcd Avi Kivity
        access_size_max = 4;
289 164a4dcd Avi Kivity
    }
290 164a4dcd Avi Kivity
    access_size = MAX(MIN(size, access_size_max), access_size_min);
291 164a4dcd Avi Kivity
    access_mask = -1ULL >> (64 - access_size * 8);
292 164a4dcd Avi Kivity
    for (i = 0; i < size; i += access_size) {
293 164a4dcd Avi Kivity
        /* FIXME: big-endian support */
294 164a4dcd Avi Kivity
        access(opaque, addr + i, value, access_size, i * 8, access_mask);
295 164a4dcd Avi Kivity
    }
296 164a4dcd Avi Kivity
}
297 164a4dcd Avi Kivity
298 16ef61c9 Avi Kivity
static void memory_region_prepare_ram_addr(MemoryRegion *mr);
299 16ef61c9 Avi Kivity
300 cc31e6e7 Avi Kivity
static void as_memory_range_add(AddressSpace *as, FlatRange *fr)
301 cc31e6e7 Avi Kivity
{
302 cc31e6e7 Avi Kivity
    ram_addr_t phys_offset, region_offset;
303 cc31e6e7 Avi Kivity
304 16ef61c9 Avi Kivity
    memory_region_prepare_ram_addr(fr->mr);
305 16ef61c9 Avi Kivity
306 cc31e6e7 Avi Kivity
    phys_offset = fr->mr->ram_addr;
307 cc31e6e7 Avi Kivity
    region_offset = fr->offset_in_region;
308 cc31e6e7 Avi Kivity
    /* cpu_register_physical_memory_log() wants region_offset for
309 cc31e6e7 Avi Kivity
     * mmio, but prefers offseting phys_offset for RAM.  Humour it.
310 cc31e6e7 Avi Kivity
     */
311 cc31e6e7 Avi Kivity
    if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) {
312 cc31e6e7 Avi Kivity
        phys_offset += region_offset;
313 cc31e6e7 Avi Kivity
        region_offset = 0;
314 cc31e6e7 Avi Kivity
    }
315 cc31e6e7 Avi Kivity
316 d0a9b5bc Avi Kivity
    if (!fr->readable) {
317 b5fe14cc Avi Kivity
        phys_offset &= ~TARGET_PAGE_MASK & ~IO_MEM_ROMD;
318 d0a9b5bc Avi Kivity
    }
319 d0a9b5bc Avi Kivity
320 fb1cd6f9 Avi Kivity
    if (fr->readonly) {
321 fb1cd6f9 Avi Kivity
        phys_offset |= IO_MEM_ROM;
322 fb1cd6f9 Avi Kivity
    }
323 fb1cd6f9 Avi Kivity
324 08dafab4 Avi Kivity
    cpu_register_physical_memory_log(int128_get64(fr->addr.start),
325 08dafab4 Avi Kivity
                                     int128_get64(fr->addr.size),
326 cc31e6e7 Avi Kivity
                                     phys_offset,
327 cc31e6e7 Avi Kivity
                                     region_offset,
328 cc31e6e7 Avi Kivity
                                     fr->dirty_log_mask);
329 cc31e6e7 Avi Kivity
}
330 cc31e6e7 Avi Kivity
331 cc31e6e7 Avi Kivity
static void as_memory_range_del(AddressSpace *as, FlatRange *fr)
332 cc31e6e7 Avi Kivity
{
333 39b796f2 Avi Kivity
    if (fr->dirty_log_mask) {
334 08dafab4 Avi Kivity
        Int128 end = addrrange_end(fr->addr);
335 08dafab4 Avi Kivity
        cpu_physical_sync_dirty_bitmap(int128_get64(fr->addr.start),
336 08dafab4 Avi Kivity
                                       int128_get64(end));
337 39b796f2 Avi Kivity
    }
338 08dafab4 Avi Kivity
    cpu_register_physical_memory(int128_get64(fr->addr.start),
339 08dafab4 Avi Kivity
                                 int128_get64(fr->addr.size),
340 cc31e6e7 Avi Kivity
                                 IO_MEM_UNASSIGNED);
341 cc31e6e7 Avi Kivity
}
342 cc31e6e7 Avi Kivity
343 cc31e6e7 Avi Kivity
static void as_memory_log_start(AddressSpace *as, FlatRange *fr)
344 cc31e6e7 Avi Kivity
{
345 08dafab4 Avi Kivity
    cpu_physical_log_start(int128_get64(fr->addr.start),
346 08dafab4 Avi Kivity
                           int128_get64(fr->addr.size));
347 cc31e6e7 Avi Kivity
}
348 cc31e6e7 Avi Kivity
349 cc31e6e7 Avi Kivity
static void as_memory_log_stop(AddressSpace *as, FlatRange *fr)
350 cc31e6e7 Avi Kivity
{
351 08dafab4 Avi Kivity
    cpu_physical_log_stop(int128_get64(fr->addr.start),
352 08dafab4 Avi Kivity
                          int128_get64(fr->addr.size));
353 cc31e6e7 Avi Kivity
}
354 cc31e6e7 Avi Kivity
355 3e9d69e7 Avi Kivity
static void as_memory_ioeventfd_add(AddressSpace *as, MemoryRegionIoeventfd *fd)
356 3e9d69e7 Avi Kivity
{
357 3e9d69e7 Avi Kivity
    int r;
358 3e9d69e7 Avi Kivity
359 08dafab4 Avi Kivity
    assert(fd->match_data && int128_get64(fd->addr.size) == 4);
360 3e9d69e7 Avi Kivity
361 08dafab4 Avi Kivity
    r = kvm_set_ioeventfd_mmio_long(fd->fd, int128_get64(fd->addr.start),
362 08dafab4 Avi Kivity
                                    fd->data, true);
363 3e9d69e7 Avi Kivity
    if (r < 0) {
364 3e9d69e7 Avi Kivity
        abort();
365 3e9d69e7 Avi Kivity
    }
366 3e9d69e7 Avi Kivity
}
367 3e9d69e7 Avi Kivity
368 3e9d69e7 Avi Kivity
static void as_memory_ioeventfd_del(AddressSpace *as, MemoryRegionIoeventfd *fd)
369 3e9d69e7 Avi Kivity
{
370 3e9d69e7 Avi Kivity
    int r;
371 3e9d69e7 Avi Kivity
372 08dafab4 Avi Kivity
    r = kvm_set_ioeventfd_mmio_long(fd->fd, int128_get64(fd->addr.start),
373 08dafab4 Avi Kivity
                                    fd->data, false);
374 3e9d69e7 Avi Kivity
    if (r < 0) {
375 3e9d69e7 Avi Kivity
        abort();
376 3e9d69e7 Avi Kivity
    }
377 3e9d69e7 Avi Kivity
}
378 3e9d69e7 Avi Kivity
379 cc31e6e7 Avi Kivity
static const AddressSpaceOps address_space_ops_memory = {
380 cc31e6e7 Avi Kivity
    .range_add = as_memory_range_add,
381 cc31e6e7 Avi Kivity
    .range_del = as_memory_range_del,
382 cc31e6e7 Avi Kivity
    .log_start = as_memory_log_start,
383 cc31e6e7 Avi Kivity
    .log_stop = as_memory_log_stop,
384 3e9d69e7 Avi Kivity
    .ioeventfd_add = as_memory_ioeventfd_add,
385 3e9d69e7 Avi Kivity
    .ioeventfd_del = as_memory_ioeventfd_del,
386 cc31e6e7 Avi Kivity
};
387 cc31e6e7 Avi Kivity
388 cc31e6e7 Avi Kivity
static AddressSpace address_space_memory = {
389 cc31e6e7 Avi Kivity
    .ops = &address_space_ops_memory,
390 cc31e6e7 Avi Kivity
};
391 cc31e6e7 Avi Kivity
392 627a0e90 Avi Kivity
static const MemoryRegionPortio *find_portio(MemoryRegion *mr, uint64_t offset,
393 627a0e90 Avi Kivity
                                             unsigned width, bool write)
394 627a0e90 Avi Kivity
{
395 627a0e90 Avi Kivity
    const MemoryRegionPortio *mrp;
396 627a0e90 Avi Kivity
397 627a0e90 Avi Kivity
    for (mrp = mr->ops->old_portio; mrp->size; ++mrp) {
398 627a0e90 Avi Kivity
        if (offset >= mrp->offset && offset < mrp->offset + mrp->len
399 627a0e90 Avi Kivity
            && width == mrp->size
400 627a0e90 Avi Kivity
            && (write ? (bool)mrp->write : (bool)mrp->read)) {
401 627a0e90 Avi Kivity
            return mrp;
402 627a0e90 Avi Kivity
        }
403 627a0e90 Avi Kivity
    }
404 627a0e90 Avi Kivity
    return NULL;
405 627a0e90 Avi Kivity
}
406 627a0e90 Avi Kivity
407 658b2224 Avi Kivity
static void memory_region_iorange_read(IORange *iorange,
408 658b2224 Avi Kivity
                                       uint64_t offset,
409 658b2224 Avi Kivity
                                       unsigned width,
410 658b2224 Avi Kivity
                                       uint64_t *data)
411 658b2224 Avi Kivity
{
412 658b2224 Avi Kivity
    MemoryRegion *mr = container_of(iorange, MemoryRegion, iorange);
413 658b2224 Avi Kivity
414 627a0e90 Avi Kivity
    if (mr->ops->old_portio) {
415 627a0e90 Avi Kivity
        const MemoryRegionPortio *mrp = find_portio(mr, offset, width, false);
416 627a0e90 Avi Kivity
417 627a0e90 Avi Kivity
        *data = ((uint64_t)1 << (width * 8)) - 1;
418 627a0e90 Avi Kivity
        if (mrp) {
419 6bf9fd43 Avi Kivity
            *data = mrp->read(mr->opaque, offset + mr->offset);
420 03808f58 Jan Kiszka
        } else if (width == 2) {
421 03808f58 Jan Kiszka
            mrp = find_portio(mr, offset, 1, false);
422 03808f58 Jan Kiszka
            assert(mrp);
423 03808f58 Jan Kiszka
            *data = mrp->read(mr->opaque, offset + mr->offset) |
424 03808f58 Jan Kiszka
                    (mrp->read(mr->opaque, offset + mr->offset + 1) << 8);
425 627a0e90 Avi Kivity
        }
426 627a0e90 Avi Kivity
        return;
427 627a0e90 Avi Kivity
    }
428 3a130f4e Avi Kivity
    *data = 0;
429 6bf9fd43 Avi Kivity
    access_with_adjusted_size(offset + mr->offset, data, width,
430 3a130f4e Avi Kivity
                              mr->ops->impl.min_access_size,
431 3a130f4e Avi Kivity
                              mr->ops->impl.max_access_size,
432 3a130f4e Avi Kivity
                              memory_region_read_accessor, mr);
433 658b2224 Avi Kivity
}
434 658b2224 Avi Kivity
435 658b2224 Avi Kivity
static void memory_region_iorange_write(IORange *iorange,
436 658b2224 Avi Kivity
                                        uint64_t offset,
437 658b2224 Avi Kivity
                                        unsigned width,
438 658b2224 Avi Kivity
                                        uint64_t data)
439 658b2224 Avi Kivity
{
440 658b2224 Avi Kivity
    MemoryRegion *mr = container_of(iorange, MemoryRegion, iorange);
441 658b2224 Avi Kivity
442 627a0e90 Avi Kivity
    if (mr->ops->old_portio) {
443 627a0e90 Avi Kivity
        const MemoryRegionPortio *mrp = find_portio(mr, offset, width, true);
444 627a0e90 Avi Kivity
445 627a0e90 Avi Kivity
        if (mrp) {
446 6bf9fd43 Avi Kivity
            mrp->write(mr->opaque, offset + mr->offset, data);
447 03808f58 Jan Kiszka
        } else if (width == 2) {
448 03808f58 Jan Kiszka
            mrp = find_portio(mr, offset, 1, false);
449 03808f58 Jan Kiszka
            assert(mrp);
450 03808f58 Jan Kiszka
            mrp->write(mr->opaque, offset + mr->offset, data & 0xff);
451 03808f58 Jan Kiszka
            mrp->write(mr->opaque, offset + mr->offset + 1, data >> 8);
452 627a0e90 Avi Kivity
        }
453 627a0e90 Avi Kivity
        return;
454 627a0e90 Avi Kivity
    }
455 6bf9fd43 Avi Kivity
    access_with_adjusted_size(offset + mr->offset, &data, width,
456 3a130f4e Avi Kivity
                              mr->ops->impl.min_access_size,
457 3a130f4e Avi Kivity
                              mr->ops->impl.max_access_size,
458 3a130f4e Avi Kivity
                              memory_region_write_accessor, mr);
459 658b2224 Avi Kivity
}
460 658b2224 Avi Kivity
461 658b2224 Avi Kivity
static const IORangeOps memory_region_iorange_ops = {
462 658b2224 Avi Kivity
    .read = memory_region_iorange_read,
463 658b2224 Avi Kivity
    .write = memory_region_iorange_write,
464 658b2224 Avi Kivity
};
465 658b2224 Avi Kivity
466 658b2224 Avi Kivity
static void as_io_range_add(AddressSpace *as, FlatRange *fr)
467 658b2224 Avi Kivity
{
468 658b2224 Avi Kivity
    iorange_init(&fr->mr->iorange, &memory_region_iorange_ops,
469 08dafab4 Avi Kivity
                 int128_get64(fr->addr.start), int128_get64(fr->addr.size));
470 658b2224 Avi Kivity
    ioport_register(&fr->mr->iorange);
471 658b2224 Avi Kivity
}
472 658b2224 Avi Kivity
473 658b2224 Avi Kivity
static void as_io_range_del(AddressSpace *as, FlatRange *fr)
474 658b2224 Avi Kivity
{
475 08dafab4 Avi Kivity
    isa_unassign_ioport(int128_get64(fr->addr.start),
476 08dafab4 Avi Kivity
                        int128_get64(fr->addr.size));
477 658b2224 Avi Kivity
}
478 658b2224 Avi Kivity
479 3e9d69e7 Avi Kivity
static void as_io_ioeventfd_add(AddressSpace *as, MemoryRegionIoeventfd *fd)
480 3e9d69e7 Avi Kivity
{
481 3e9d69e7 Avi Kivity
    int r;
482 3e9d69e7 Avi Kivity
483 08dafab4 Avi Kivity
    assert(fd->match_data && int128_get64(fd->addr.size) == 2);
484 3e9d69e7 Avi Kivity
485 08dafab4 Avi Kivity
    r = kvm_set_ioeventfd_pio_word(fd->fd, int128_get64(fd->addr.start),
486 08dafab4 Avi Kivity
                                   fd->data, true);
487 3e9d69e7 Avi Kivity
    if (r < 0) {
488 3e9d69e7 Avi Kivity
        abort();
489 3e9d69e7 Avi Kivity
    }
490 3e9d69e7 Avi Kivity
}
491 3e9d69e7 Avi Kivity
492 3e9d69e7 Avi Kivity
static void as_io_ioeventfd_del(AddressSpace *as, MemoryRegionIoeventfd *fd)
493 3e9d69e7 Avi Kivity
{
494 3e9d69e7 Avi Kivity
    int r;
495 3e9d69e7 Avi Kivity
496 08dafab4 Avi Kivity
    r = kvm_set_ioeventfd_pio_word(fd->fd, int128_get64(fd->addr.start),
497 08dafab4 Avi Kivity
                                   fd->data, false);
498 3e9d69e7 Avi Kivity
    if (r < 0) {
499 3e9d69e7 Avi Kivity
        abort();
500 3e9d69e7 Avi Kivity
    }
501 3e9d69e7 Avi Kivity
}
502 3e9d69e7 Avi Kivity
503 658b2224 Avi Kivity
static const AddressSpaceOps address_space_ops_io = {
504 658b2224 Avi Kivity
    .range_add = as_io_range_add,
505 658b2224 Avi Kivity
    .range_del = as_io_range_del,
506 3e9d69e7 Avi Kivity
    .ioeventfd_add = as_io_ioeventfd_add,
507 3e9d69e7 Avi Kivity
    .ioeventfd_del = as_io_ioeventfd_del,
508 658b2224 Avi Kivity
};
509 658b2224 Avi Kivity
510 658b2224 Avi Kivity
static AddressSpace address_space_io = {
511 658b2224 Avi Kivity
    .ops = &address_space_ops_io,
512 658b2224 Avi Kivity
};
513 658b2224 Avi Kivity
514 093bc2cd Avi Kivity
/* Render a memory region into the global view.  Ranges in @view obscure
515 093bc2cd Avi Kivity
 * ranges in @mr.
516 093bc2cd Avi Kivity
 */
517 093bc2cd Avi Kivity
static void render_memory_region(FlatView *view,
518 093bc2cd Avi Kivity
                                 MemoryRegion *mr,
519 08dafab4 Avi Kivity
                                 Int128 base,
520 fb1cd6f9 Avi Kivity
                                 AddrRange clip,
521 fb1cd6f9 Avi Kivity
                                 bool readonly)
522 093bc2cd Avi Kivity
{
523 093bc2cd Avi Kivity
    MemoryRegion *subregion;
524 093bc2cd Avi Kivity
    unsigned i;
525 093bc2cd Avi Kivity
    target_phys_addr_t offset_in_region;
526 08dafab4 Avi Kivity
    Int128 remain;
527 08dafab4 Avi Kivity
    Int128 now;
528 093bc2cd Avi Kivity
    FlatRange fr;
529 093bc2cd Avi Kivity
    AddrRange tmp;
530 093bc2cd Avi Kivity
531 08dafab4 Avi Kivity
    int128_addto(&base, int128_make64(mr->addr));
532 fb1cd6f9 Avi Kivity
    readonly |= mr->readonly;
533 093bc2cd Avi Kivity
534 093bc2cd Avi Kivity
    tmp = addrrange_make(base, mr->size);
535 093bc2cd Avi Kivity
536 093bc2cd Avi Kivity
    if (!addrrange_intersects(tmp, clip)) {
537 093bc2cd Avi Kivity
        return;
538 093bc2cd Avi Kivity
    }
539 093bc2cd Avi Kivity
540 093bc2cd Avi Kivity
    clip = addrrange_intersection(tmp, clip);
541 093bc2cd Avi Kivity
542 093bc2cd Avi Kivity
    if (mr->alias) {
543 08dafab4 Avi Kivity
        int128_subfrom(&base, int128_make64(mr->alias->addr));
544 08dafab4 Avi Kivity
        int128_subfrom(&base, int128_make64(mr->alias_offset));
545 fb1cd6f9 Avi Kivity
        render_memory_region(view, mr->alias, base, clip, readonly);
546 093bc2cd Avi Kivity
        return;
547 093bc2cd Avi Kivity
    }
548 093bc2cd Avi Kivity
549 093bc2cd Avi Kivity
    /* Render subregions in priority order. */
550 093bc2cd Avi Kivity
    QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {
551 fb1cd6f9 Avi Kivity
        render_memory_region(view, subregion, base, clip, readonly);
552 093bc2cd Avi Kivity
    }
553 093bc2cd Avi Kivity
554 14a3c10a Avi Kivity
    if (!mr->terminates) {
555 093bc2cd Avi Kivity
        return;
556 093bc2cd Avi Kivity
    }
557 093bc2cd Avi Kivity
558 08dafab4 Avi Kivity
    offset_in_region = int128_get64(int128_sub(clip.start, base));
559 093bc2cd Avi Kivity
    base = clip.start;
560 093bc2cd Avi Kivity
    remain = clip.size;
561 093bc2cd Avi Kivity
562 093bc2cd Avi Kivity
    /* Render the region itself into any gaps left by the current view. */
563 08dafab4 Avi Kivity
    for (i = 0; i < view->nr && int128_nz(remain); ++i) {
564 08dafab4 Avi Kivity
        if (int128_ge(base, addrrange_end(view->ranges[i].addr))) {
565 093bc2cd Avi Kivity
            continue;
566 093bc2cd Avi Kivity
        }
567 08dafab4 Avi Kivity
        if (int128_lt(base, view->ranges[i].addr.start)) {
568 08dafab4 Avi Kivity
            now = int128_min(remain,
569 08dafab4 Avi Kivity
                             int128_sub(view->ranges[i].addr.start, base));
570 093bc2cd Avi Kivity
            fr.mr = mr;
571 093bc2cd Avi Kivity
            fr.offset_in_region = offset_in_region;
572 093bc2cd Avi Kivity
            fr.addr = addrrange_make(base, now);
573 5a583347 Avi Kivity
            fr.dirty_log_mask = mr->dirty_log_mask;
574 d0a9b5bc Avi Kivity
            fr.readable = mr->readable;
575 fb1cd6f9 Avi Kivity
            fr.readonly = readonly;
576 093bc2cd Avi Kivity
            flatview_insert(view, i, &fr);
577 093bc2cd Avi Kivity
            ++i;
578 08dafab4 Avi Kivity
            int128_addto(&base, now);
579 08dafab4 Avi Kivity
            offset_in_region += int128_get64(now);
580 08dafab4 Avi Kivity
            int128_subfrom(&remain, now);
581 093bc2cd Avi Kivity
        }
582 08dafab4 Avi Kivity
        if (int128_eq(base, view->ranges[i].addr.start)) {
583 08dafab4 Avi Kivity
            now = int128_min(remain, view->ranges[i].addr.size);
584 08dafab4 Avi Kivity
            int128_addto(&base, now);
585 08dafab4 Avi Kivity
            offset_in_region += int128_get64(now);
586 08dafab4 Avi Kivity
            int128_subfrom(&remain, now);
587 093bc2cd Avi Kivity
        }
588 093bc2cd Avi Kivity
    }
589 08dafab4 Avi Kivity
    if (int128_nz(remain)) {
590 093bc2cd Avi Kivity
        fr.mr = mr;
591 093bc2cd Avi Kivity
        fr.offset_in_region = offset_in_region;
592 093bc2cd Avi Kivity
        fr.addr = addrrange_make(base, remain);
593 5a583347 Avi Kivity
        fr.dirty_log_mask = mr->dirty_log_mask;
594 d0a9b5bc Avi Kivity
        fr.readable = mr->readable;
595 fb1cd6f9 Avi Kivity
        fr.readonly = readonly;
596 093bc2cd Avi Kivity
        flatview_insert(view, i, &fr);
597 093bc2cd Avi Kivity
    }
598 093bc2cd Avi Kivity
}
599 093bc2cd Avi Kivity
600 093bc2cd Avi Kivity
/* Render a memory topology into a list of disjoint absolute ranges. */
601 093bc2cd Avi Kivity
static FlatView generate_memory_topology(MemoryRegion *mr)
602 093bc2cd Avi Kivity
{
603 093bc2cd Avi Kivity
    FlatView view;
604 093bc2cd Avi Kivity
605 093bc2cd Avi Kivity
    flatview_init(&view);
606 093bc2cd Avi Kivity
607 08dafab4 Avi Kivity
    render_memory_region(&view, mr, int128_zero(),
608 08dafab4 Avi Kivity
                         addrrange_make(int128_zero(), int128_2_64()), false);
609 3d8e6bf9 Avi Kivity
    flatview_simplify(&view);
610 093bc2cd Avi Kivity
611 093bc2cd Avi Kivity
    return view;
612 093bc2cd Avi Kivity
}
613 093bc2cd Avi Kivity
614 3e9d69e7 Avi Kivity
static void address_space_add_del_ioeventfds(AddressSpace *as,
615 3e9d69e7 Avi Kivity
                                             MemoryRegionIoeventfd *fds_new,
616 3e9d69e7 Avi Kivity
                                             unsigned fds_new_nb,
617 3e9d69e7 Avi Kivity
                                             MemoryRegionIoeventfd *fds_old,
618 3e9d69e7 Avi Kivity
                                             unsigned fds_old_nb)
619 3e9d69e7 Avi Kivity
{
620 3e9d69e7 Avi Kivity
    unsigned iold, inew;
621 3e9d69e7 Avi Kivity
622 3e9d69e7 Avi Kivity
    /* Generate a symmetric difference of the old and new fd sets, adding
623 3e9d69e7 Avi Kivity
     * and deleting as necessary.
624 3e9d69e7 Avi Kivity
     */
625 3e9d69e7 Avi Kivity
626 3e9d69e7 Avi Kivity
    iold = inew = 0;
627 3e9d69e7 Avi Kivity
    while (iold < fds_old_nb || inew < fds_new_nb) {
628 3e9d69e7 Avi Kivity
        if (iold < fds_old_nb
629 3e9d69e7 Avi Kivity
            && (inew == fds_new_nb
630 3e9d69e7 Avi Kivity
                || memory_region_ioeventfd_before(fds_old[iold],
631 3e9d69e7 Avi Kivity
                                                  fds_new[inew]))) {
632 3e9d69e7 Avi Kivity
            as->ops->ioeventfd_del(as, &fds_old[iold]);
633 3e9d69e7 Avi Kivity
            ++iold;
634 3e9d69e7 Avi Kivity
        } else if (inew < fds_new_nb
635 3e9d69e7 Avi Kivity
                   && (iold == fds_old_nb
636 3e9d69e7 Avi Kivity
                       || memory_region_ioeventfd_before(fds_new[inew],
637 3e9d69e7 Avi Kivity
                                                         fds_old[iold]))) {
638 3e9d69e7 Avi Kivity
            as->ops->ioeventfd_add(as, &fds_new[inew]);
639 3e9d69e7 Avi Kivity
            ++inew;
640 3e9d69e7 Avi Kivity
        } else {
641 3e9d69e7 Avi Kivity
            ++iold;
642 3e9d69e7 Avi Kivity
            ++inew;
643 3e9d69e7 Avi Kivity
        }
644 3e9d69e7 Avi Kivity
    }
645 3e9d69e7 Avi Kivity
}
646 3e9d69e7 Avi Kivity
647 3e9d69e7 Avi Kivity
static void address_space_update_ioeventfds(AddressSpace *as)
648 3e9d69e7 Avi Kivity
{
649 3e9d69e7 Avi Kivity
    FlatRange *fr;
650 3e9d69e7 Avi Kivity
    unsigned ioeventfd_nb = 0;
651 3e9d69e7 Avi Kivity
    MemoryRegionIoeventfd *ioeventfds = NULL;
652 3e9d69e7 Avi Kivity
    AddrRange tmp;
653 3e9d69e7 Avi Kivity
    unsigned i;
654 3e9d69e7 Avi Kivity
655 3e9d69e7 Avi Kivity
    FOR_EACH_FLAT_RANGE(fr, &as->current_map) {
656 3e9d69e7 Avi Kivity
        for (i = 0; i < fr->mr->ioeventfd_nb; ++i) {
657 3e9d69e7 Avi Kivity
            tmp = addrrange_shift(fr->mr->ioeventfds[i].addr,
658 08dafab4 Avi Kivity
                                  int128_sub(fr->addr.start,
659 08dafab4 Avi Kivity
                                             int128_make64(fr->offset_in_region)));
660 3e9d69e7 Avi Kivity
            if (addrrange_intersects(fr->addr, tmp)) {
661 3e9d69e7 Avi Kivity
                ++ioeventfd_nb;
662 7267c094 Anthony Liguori
                ioeventfds = g_realloc(ioeventfds,
663 3e9d69e7 Avi Kivity
                                          ioeventfd_nb * sizeof(*ioeventfds));
664 3e9d69e7 Avi Kivity
                ioeventfds[ioeventfd_nb-1] = fr->mr->ioeventfds[i];
665 3e9d69e7 Avi Kivity
                ioeventfds[ioeventfd_nb-1].addr = tmp;
666 3e9d69e7 Avi Kivity
            }
667 3e9d69e7 Avi Kivity
        }
668 3e9d69e7 Avi Kivity
    }
669 3e9d69e7 Avi Kivity
670 3e9d69e7 Avi Kivity
    address_space_add_del_ioeventfds(as, ioeventfds, ioeventfd_nb,
671 3e9d69e7 Avi Kivity
                                     as->ioeventfds, as->ioeventfd_nb);
672 3e9d69e7 Avi Kivity
673 7267c094 Anthony Liguori
    g_free(as->ioeventfds);
674 3e9d69e7 Avi Kivity
    as->ioeventfds = ioeventfds;
675 3e9d69e7 Avi Kivity
    as->ioeventfd_nb = ioeventfd_nb;
676 3e9d69e7 Avi Kivity
}
677 3e9d69e7 Avi Kivity
678 b8af1afb Avi Kivity
static void address_space_update_topology_pass(AddressSpace *as,
679 b8af1afb Avi Kivity
                                               FlatView old_view,
680 b8af1afb Avi Kivity
                                               FlatView new_view,
681 b8af1afb Avi Kivity
                                               bool adding)
682 093bc2cd Avi Kivity
{
683 093bc2cd Avi Kivity
    unsigned iold, inew;
684 093bc2cd Avi Kivity
    FlatRange *frold, *frnew;
685 093bc2cd Avi Kivity
686 093bc2cd Avi Kivity
    /* Generate a symmetric difference of the old and new memory maps.
687 093bc2cd Avi Kivity
     * Kill ranges in the old map, and instantiate ranges in the new map.
688 093bc2cd Avi Kivity
     */
689 093bc2cd Avi Kivity
    iold = inew = 0;
690 093bc2cd Avi Kivity
    while (iold < old_view.nr || inew < new_view.nr) {
691 093bc2cd Avi Kivity
        if (iold < old_view.nr) {
692 093bc2cd Avi Kivity
            frold = &old_view.ranges[iold];
693 093bc2cd Avi Kivity
        } else {
694 093bc2cd Avi Kivity
            frold = NULL;
695 093bc2cd Avi Kivity
        }
696 093bc2cd Avi Kivity
        if (inew < new_view.nr) {
697 093bc2cd Avi Kivity
            frnew = &new_view.ranges[inew];
698 093bc2cd Avi Kivity
        } else {
699 093bc2cd Avi Kivity
            frnew = NULL;
700 093bc2cd Avi Kivity
        }
701 093bc2cd Avi Kivity
702 093bc2cd Avi Kivity
        if (frold
703 093bc2cd Avi Kivity
            && (!frnew
704 08dafab4 Avi Kivity
                || int128_lt(frold->addr.start, frnew->addr.start)
705 08dafab4 Avi Kivity
                || (int128_eq(frold->addr.start, frnew->addr.start)
706 093bc2cd Avi Kivity
                    && !flatrange_equal(frold, frnew)))) {
707 093bc2cd Avi Kivity
            /* In old, but (not in new, or in new but attributes changed). */
708 093bc2cd Avi Kivity
709 b8af1afb Avi Kivity
            if (!adding) {
710 b8af1afb Avi Kivity
                as->ops->range_del(as, frold);
711 b8af1afb Avi Kivity
            }
712 b8af1afb Avi Kivity
713 093bc2cd Avi Kivity
            ++iold;
714 093bc2cd Avi Kivity
        } else if (frold && frnew && flatrange_equal(frold, frnew)) {
715 093bc2cd Avi Kivity
            /* In both (logging may have changed) */
716 093bc2cd Avi Kivity
717 b8af1afb Avi Kivity
            if (adding) {
718 b8af1afb Avi Kivity
                if (frold->dirty_log_mask && !frnew->dirty_log_mask) {
719 b8af1afb Avi Kivity
                    as->ops->log_stop(as, frnew);
720 b8af1afb Avi Kivity
                } else if (frnew->dirty_log_mask && !frold->dirty_log_mask) {
721 b8af1afb Avi Kivity
                    as->ops->log_start(as, frnew);
722 b8af1afb Avi Kivity
                }
723 5a583347 Avi Kivity
            }
724 5a583347 Avi Kivity
725 093bc2cd Avi Kivity
            ++iold;
726 093bc2cd Avi Kivity
            ++inew;
727 093bc2cd Avi Kivity
        } else {
728 093bc2cd Avi Kivity
            /* In new */
729 093bc2cd Avi Kivity
730 b8af1afb Avi Kivity
            if (adding) {
731 b8af1afb Avi Kivity
                as->ops->range_add(as, frnew);
732 b8af1afb Avi Kivity
            }
733 b8af1afb Avi Kivity
734 093bc2cd Avi Kivity
            ++inew;
735 093bc2cd Avi Kivity
        }
736 093bc2cd Avi Kivity
    }
737 b8af1afb Avi Kivity
}
738 b8af1afb Avi Kivity
739 b8af1afb Avi Kivity
740 b8af1afb Avi Kivity
static void address_space_update_topology(AddressSpace *as)
741 b8af1afb Avi Kivity
{
742 b8af1afb Avi Kivity
    FlatView old_view = as->current_map;
743 b8af1afb Avi Kivity
    FlatView new_view = generate_memory_topology(as->root);
744 b8af1afb Avi Kivity
745 b8af1afb Avi Kivity
    address_space_update_topology_pass(as, old_view, new_view, false);
746 b8af1afb Avi Kivity
    address_space_update_topology_pass(as, old_view, new_view, true);
747 b8af1afb Avi Kivity
748 cc31e6e7 Avi Kivity
    as->current_map = new_view;
749 093bc2cd Avi Kivity
    flatview_destroy(&old_view);
750 3e9d69e7 Avi Kivity
    address_space_update_ioeventfds(as);
751 093bc2cd Avi Kivity
}
752 093bc2cd Avi Kivity
753 cc31e6e7 Avi Kivity
static void memory_region_update_topology(void)
754 cc31e6e7 Avi Kivity
{
755 4ef4db86 Avi Kivity
    if (memory_region_transaction_depth) {
756 4ef4db86 Avi Kivity
        return;
757 4ef4db86 Avi Kivity
    }
758 4ef4db86 Avi Kivity
759 658b2224 Avi Kivity
    if (address_space_memory.root) {
760 658b2224 Avi Kivity
        address_space_update_topology(&address_space_memory);
761 658b2224 Avi Kivity
    }
762 658b2224 Avi Kivity
    if (address_space_io.root) {
763 658b2224 Avi Kivity
        address_space_update_topology(&address_space_io);
764 658b2224 Avi Kivity
    }
765 cc31e6e7 Avi Kivity
}
766 cc31e6e7 Avi Kivity
767 4ef4db86 Avi Kivity
void memory_region_transaction_begin(void)
768 4ef4db86 Avi Kivity
{
769 4ef4db86 Avi Kivity
    ++memory_region_transaction_depth;
770 4ef4db86 Avi Kivity
}
771 4ef4db86 Avi Kivity
772 4ef4db86 Avi Kivity
void memory_region_transaction_commit(void)
773 4ef4db86 Avi Kivity
{
774 4ef4db86 Avi Kivity
    assert(memory_region_transaction_depth);
775 4ef4db86 Avi Kivity
    --memory_region_transaction_depth;
776 4ef4db86 Avi Kivity
    memory_region_update_topology();
777 4ef4db86 Avi Kivity
}
778 4ef4db86 Avi Kivity
779 545e92e0 Avi Kivity
static void memory_region_destructor_none(MemoryRegion *mr)
780 545e92e0 Avi Kivity
{
781 545e92e0 Avi Kivity
}
782 545e92e0 Avi Kivity
783 545e92e0 Avi Kivity
static void memory_region_destructor_ram(MemoryRegion *mr)
784 545e92e0 Avi Kivity
{
785 545e92e0 Avi Kivity
    qemu_ram_free(mr->ram_addr);
786 545e92e0 Avi Kivity
}
787 545e92e0 Avi Kivity
788 545e92e0 Avi Kivity
static void memory_region_destructor_ram_from_ptr(MemoryRegion *mr)
789 545e92e0 Avi Kivity
{
790 545e92e0 Avi Kivity
    qemu_ram_free_from_ptr(mr->ram_addr);
791 545e92e0 Avi Kivity
}
792 545e92e0 Avi Kivity
793 545e92e0 Avi Kivity
static void memory_region_destructor_iomem(MemoryRegion *mr)
794 545e92e0 Avi Kivity
{
795 545e92e0 Avi Kivity
    cpu_unregister_io_memory(mr->ram_addr);
796 545e92e0 Avi Kivity
}
797 545e92e0 Avi Kivity
798 d0a9b5bc Avi Kivity
static void memory_region_destructor_rom_device(MemoryRegion *mr)
799 d0a9b5bc Avi Kivity
{
800 d0a9b5bc Avi Kivity
    qemu_ram_free(mr->ram_addr & TARGET_PAGE_MASK);
801 d0a9b5bc Avi Kivity
    cpu_unregister_io_memory(mr->ram_addr & ~(TARGET_PAGE_MASK | IO_MEM_ROMD));
802 d0a9b5bc Avi Kivity
}
803 d0a9b5bc Avi Kivity
804 093bc2cd Avi Kivity
void memory_region_init(MemoryRegion *mr,
805 093bc2cd Avi Kivity
                        const char *name,
806 093bc2cd Avi Kivity
                        uint64_t size)
807 093bc2cd Avi Kivity
{
808 093bc2cd Avi Kivity
    mr->ops = NULL;
809 093bc2cd Avi Kivity
    mr->parent = NULL;
810 08dafab4 Avi Kivity
    mr->size = int128_make64(size);
811 08dafab4 Avi Kivity
    if (size == UINT64_MAX) {
812 08dafab4 Avi Kivity
        mr->size = int128_2_64();
813 08dafab4 Avi Kivity
    }
814 093bc2cd Avi Kivity
    mr->addr = 0;
815 093bc2cd Avi Kivity
    mr->offset = 0;
816 14a3c10a Avi Kivity
    mr->terminates = false;
817 d0a9b5bc Avi Kivity
    mr->readable = true;
818 fb1cd6f9 Avi Kivity
    mr->readonly = false;
819 545e92e0 Avi Kivity
    mr->destructor = memory_region_destructor_none;
820 093bc2cd Avi Kivity
    mr->priority = 0;
821 093bc2cd Avi Kivity
    mr->may_overlap = false;
822 093bc2cd Avi Kivity
    mr->alias = NULL;
823 093bc2cd Avi Kivity
    QTAILQ_INIT(&mr->subregions);
824 093bc2cd Avi Kivity
    memset(&mr->subregions_link, 0, sizeof mr->subregions_link);
825 093bc2cd Avi Kivity
    QTAILQ_INIT(&mr->coalesced);
826 7267c094 Anthony Liguori
    mr->name = g_strdup(name);
827 5a583347 Avi Kivity
    mr->dirty_log_mask = 0;
828 3e9d69e7 Avi Kivity
    mr->ioeventfd_nb = 0;
829 3e9d69e7 Avi Kivity
    mr->ioeventfds = NULL;
830 093bc2cd Avi Kivity
}
831 093bc2cd Avi Kivity
832 093bc2cd Avi Kivity
static bool memory_region_access_valid(MemoryRegion *mr,
833 093bc2cd Avi Kivity
                                       target_phys_addr_t addr,
834 897fa7cf Avi Kivity
                                       unsigned size,
835 897fa7cf Avi Kivity
                                       bool is_write)
836 093bc2cd Avi Kivity
{
837 897fa7cf Avi Kivity
    if (mr->ops->valid.accepts
838 897fa7cf Avi Kivity
        && !mr->ops->valid.accepts(mr->opaque, addr, size, is_write)) {
839 897fa7cf Avi Kivity
        return false;
840 897fa7cf Avi Kivity
    }
841 897fa7cf Avi Kivity
842 093bc2cd Avi Kivity
    if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
843 093bc2cd Avi Kivity
        return false;
844 093bc2cd Avi Kivity
    }
845 093bc2cd Avi Kivity
846 093bc2cd Avi Kivity
    /* Treat zero as compatibility all valid */
847 093bc2cd Avi Kivity
    if (!mr->ops->valid.max_access_size) {
848 093bc2cd Avi Kivity
        return true;
849 093bc2cd Avi Kivity
    }
850 093bc2cd Avi Kivity
851 093bc2cd Avi Kivity
    if (size > mr->ops->valid.max_access_size
852 093bc2cd Avi Kivity
        || size < mr->ops->valid.min_access_size) {
853 093bc2cd Avi Kivity
        return false;
854 093bc2cd Avi Kivity
    }
855 093bc2cd Avi Kivity
    return true;
856 093bc2cd Avi Kivity
}
857 093bc2cd Avi Kivity
858 093bc2cd Avi Kivity
static uint32_t memory_region_read_thunk_n(void *_mr,
859 093bc2cd Avi Kivity
                                           target_phys_addr_t addr,
860 093bc2cd Avi Kivity
                                           unsigned size)
861 093bc2cd Avi Kivity
{
862 093bc2cd Avi Kivity
    MemoryRegion *mr = _mr;
863 164a4dcd Avi Kivity
    uint64_t data = 0;
864 093bc2cd Avi Kivity
865 897fa7cf Avi Kivity
    if (!memory_region_access_valid(mr, addr, size, false)) {
866 093bc2cd Avi Kivity
        return -1U; /* FIXME: better signalling */
867 093bc2cd Avi Kivity
    }
868 093bc2cd Avi Kivity
869 74901c3b Avi Kivity
    if (!mr->ops->read) {
870 74901c3b Avi Kivity
        return mr->ops->old_mmio.read[bitops_ffsl(size)](mr->opaque, addr);
871 74901c3b Avi Kivity
    }
872 74901c3b Avi Kivity
873 093bc2cd Avi Kivity
    /* FIXME: support unaligned access */
874 164a4dcd Avi Kivity
    access_with_adjusted_size(addr + mr->offset, &data, size,
875 164a4dcd Avi Kivity
                              mr->ops->impl.min_access_size,
876 164a4dcd Avi Kivity
                              mr->ops->impl.max_access_size,
877 164a4dcd Avi Kivity
                              memory_region_read_accessor, mr);
878 093bc2cd Avi Kivity
879 093bc2cd Avi Kivity
    return data;
880 093bc2cd Avi Kivity
}
881 093bc2cd Avi Kivity
882 093bc2cd Avi Kivity
static void memory_region_write_thunk_n(void *_mr,
883 093bc2cd Avi Kivity
                                        target_phys_addr_t addr,
884 093bc2cd Avi Kivity
                                        unsigned size,
885 093bc2cd Avi Kivity
                                        uint64_t data)
886 093bc2cd Avi Kivity
{
887 093bc2cd Avi Kivity
    MemoryRegion *mr = _mr;
888 093bc2cd Avi Kivity
889 897fa7cf Avi Kivity
    if (!memory_region_access_valid(mr, addr, size, true)) {
890 093bc2cd Avi Kivity
        return; /* FIXME: better signalling */
891 093bc2cd Avi Kivity
    }
892 093bc2cd Avi Kivity
893 74901c3b Avi Kivity
    if (!mr->ops->write) {
894 74901c3b Avi Kivity
        mr->ops->old_mmio.write[bitops_ffsl(size)](mr->opaque, addr, data);
895 74901c3b Avi Kivity
        return;
896 74901c3b Avi Kivity
    }
897 74901c3b Avi Kivity
898 093bc2cd Avi Kivity
    /* FIXME: support unaligned access */
899 164a4dcd Avi Kivity
    access_with_adjusted_size(addr + mr->offset, &data, size,
900 164a4dcd Avi Kivity
                              mr->ops->impl.min_access_size,
901 164a4dcd Avi Kivity
                              mr->ops->impl.max_access_size,
902 164a4dcd Avi Kivity
                              memory_region_write_accessor, mr);
903 093bc2cd Avi Kivity
}
904 093bc2cd Avi Kivity
905 093bc2cd Avi Kivity
static uint32_t memory_region_read_thunk_b(void *mr, target_phys_addr_t addr)
906 093bc2cd Avi Kivity
{
907 093bc2cd Avi Kivity
    return memory_region_read_thunk_n(mr, addr, 1);
908 093bc2cd Avi Kivity
}
909 093bc2cd Avi Kivity
910 093bc2cd Avi Kivity
static uint32_t memory_region_read_thunk_w(void *mr, target_phys_addr_t addr)
911 093bc2cd Avi Kivity
{
912 093bc2cd Avi Kivity
    return memory_region_read_thunk_n(mr, addr, 2);
913 093bc2cd Avi Kivity
}
914 093bc2cd Avi Kivity
915 093bc2cd Avi Kivity
static uint32_t memory_region_read_thunk_l(void *mr, target_phys_addr_t addr)
916 093bc2cd Avi Kivity
{
917 093bc2cd Avi Kivity
    return memory_region_read_thunk_n(mr, addr, 4);
918 093bc2cd Avi Kivity
}
919 093bc2cd Avi Kivity
920 093bc2cd Avi Kivity
static void memory_region_write_thunk_b(void *mr, target_phys_addr_t addr,
921 093bc2cd Avi Kivity
                                        uint32_t data)
922 093bc2cd Avi Kivity
{
923 093bc2cd Avi Kivity
    memory_region_write_thunk_n(mr, addr, 1, data);
924 093bc2cd Avi Kivity
}
925 093bc2cd Avi Kivity
926 093bc2cd Avi Kivity
static void memory_region_write_thunk_w(void *mr, target_phys_addr_t addr,
927 093bc2cd Avi Kivity
                                        uint32_t data)
928 093bc2cd Avi Kivity
{
929 093bc2cd Avi Kivity
    memory_region_write_thunk_n(mr, addr, 2, data);
930 093bc2cd Avi Kivity
}
931 093bc2cd Avi Kivity
932 093bc2cd Avi Kivity
static void memory_region_write_thunk_l(void *mr, target_phys_addr_t addr,
933 093bc2cd Avi Kivity
                                        uint32_t data)
934 093bc2cd Avi Kivity
{
935 093bc2cd Avi Kivity
    memory_region_write_thunk_n(mr, addr, 4, data);
936 093bc2cd Avi Kivity
}
937 093bc2cd Avi Kivity
938 093bc2cd Avi Kivity
static CPUReadMemoryFunc * const memory_region_read_thunk[] = {
939 093bc2cd Avi Kivity
    memory_region_read_thunk_b,
940 093bc2cd Avi Kivity
    memory_region_read_thunk_w,
941 093bc2cd Avi Kivity
    memory_region_read_thunk_l,
942 093bc2cd Avi Kivity
};
943 093bc2cd Avi Kivity
944 093bc2cd Avi Kivity
static CPUWriteMemoryFunc * const memory_region_write_thunk[] = {
945 093bc2cd Avi Kivity
    memory_region_write_thunk_b,
946 093bc2cd Avi Kivity
    memory_region_write_thunk_w,
947 093bc2cd Avi Kivity
    memory_region_write_thunk_l,
948 093bc2cd Avi Kivity
};
949 093bc2cd Avi Kivity
950 16ef61c9 Avi Kivity
static void memory_region_prepare_ram_addr(MemoryRegion *mr)
951 16ef61c9 Avi Kivity
{
952 16ef61c9 Avi Kivity
    if (mr->backend_registered) {
953 16ef61c9 Avi Kivity
        return;
954 16ef61c9 Avi Kivity
    }
955 16ef61c9 Avi Kivity
956 545e92e0 Avi Kivity
    mr->destructor = memory_region_destructor_iomem;
957 16ef61c9 Avi Kivity
    mr->ram_addr = cpu_register_io_memory(memory_region_read_thunk,
958 16ef61c9 Avi Kivity
                                          memory_region_write_thunk,
959 16ef61c9 Avi Kivity
                                          mr,
960 16ef61c9 Avi Kivity
                                          mr->ops->endianness);
961 16ef61c9 Avi Kivity
    mr->backend_registered = true;
962 16ef61c9 Avi Kivity
}
963 16ef61c9 Avi Kivity
964 093bc2cd Avi Kivity
void memory_region_init_io(MemoryRegion *mr,
965 093bc2cd Avi Kivity
                           const MemoryRegionOps *ops,
966 093bc2cd Avi Kivity
                           void *opaque,
967 093bc2cd Avi Kivity
                           const char *name,
968 093bc2cd Avi Kivity
                           uint64_t size)
969 093bc2cd Avi Kivity
{
970 093bc2cd Avi Kivity
    memory_region_init(mr, name, size);
971 093bc2cd Avi Kivity
    mr->ops = ops;
972 093bc2cd Avi Kivity
    mr->opaque = opaque;
973 14a3c10a Avi Kivity
    mr->terminates = true;
974 16ef61c9 Avi Kivity
    mr->backend_registered = false;
975 093bc2cd Avi Kivity
}
976 093bc2cd Avi Kivity
977 093bc2cd Avi Kivity
void memory_region_init_ram(MemoryRegion *mr,
978 093bc2cd Avi Kivity
                            DeviceState *dev,
979 093bc2cd Avi Kivity
                            const char *name,
980 093bc2cd Avi Kivity
                            uint64_t size)
981 093bc2cd Avi Kivity
{
982 093bc2cd Avi Kivity
    memory_region_init(mr, name, size);
983 14a3c10a Avi Kivity
    mr->terminates = true;
984 545e92e0 Avi Kivity
    mr->destructor = memory_region_destructor_ram;
985 093bc2cd Avi Kivity
    mr->ram_addr = qemu_ram_alloc(dev, name, size);
986 16ef61c9 Avi Kivity
    mr->backend_registered = true;
987 093bc2cd Avi Kivity
}
988 093bc2cd Avi Kivity
989 093bc2cd Avi Kivity
void memory_region_init_ram_ptr(MemoryRegion *mr,
990 093bc2cd Avi Kivity
                                DeviceState *dev,
991 093bc2cd Avi Kivity
                                const char *name,
992 093bc2cd Avi Kivity
                                uint64_t size,
993 093bc2cd Avi Kivity
                                void *ptr)
994 093bc2cd Avi Kivity
{
995 093bc2cd Avi Kivity
    memory_region_init(mr, name, size);
996 14a3c10a Avi Kivity
    mr->terminates = true;
997 545e92e0 Avi Kivity
    mr->destructor = memory_region_destructor_ram_from_ptr;
998 093bc2cd Avi Kivity
    mr->ram_addr = qemu_ram_alloc_from_ptr(dev, name, size, ptr);
999 16ef61c9 Avi Kivity
    mr->backend_registered = true;
1000 093bc2cd Avi Kivity
}
1001 093bc2cd Avi Kivity
1002 093bc2cd Avi Kivity
void memory_region_init_alias(MemoryRegion *mr,
1003 093bc2cd Avi Kivity
                              const char *name,
1004 093bc2cd Avi Kivity
                              MemoryRegion *orig,
1005 093bc2cd Avi Kivity
                              target_phys_addr_t offset,
1006 093bc2cd Avi Kivity
                              uint64_t size)
1007 093bc2cd Avi Kivity
{
1008 093bc2cd Avi Kivity
    memory_region_init(mr, name, size);
1009 093bc2cd Avi Kivity
    mr->alias = orig;
1010 093bc2cd Avi Kivity
    mr->alias_offset = offset;
1011 093bc2cd Avi Kivity
}
1012 093bc2cd Avi Kivity
1013 d0a9b5bc Avi Kivity
void memory_region_init_rom_device(MemoryRegion *mr,
1014 d0a9b5bc Avi Kivity
                                   const MemoryRegionOps *ops,
1015 75f5941c Avi Kivity
                                   void *opaque,
1016 d0a9b5bc Avi Kivity
                                   DeviceState *dev,
1017 d0a9b5bc Avi Kivity
                                   const char *name,
1018 d0a9b5bc Avi Kivity
                                   uint64_t size)
1019 d0a9b5bc Avi Kivity
{
1020 d0a9b5bc Avi Kivity
    memory_region_init(mr, name, size);
1021 7bc2b9cd Avi Kivity
    mr->ops = ops;
1022 75f5941c Avi Kivity
    mr->opaque = opaque;
1023 d0a9b5bc Avi Kivity
    mr->terminates = true;
1024 d0a9b5bc Avi Kivity
    mr->destructor = memory_region_destructor_rom_device;
1025 d0a9b5bc Avi Kivity
    mr->ram_addr = qemu_ram_alloc(dev, name, size);
1026 d0a9b5bc Avi Kivity
    mr->ram_addr |= cpu_register_io_memory(memory_region_read_thunk,
1027 d0a9b5bc Avi Kivity
                                           memory_region_write_thunk,
1028 d0a9b5bc Avi Kivity
                                           mr,
1029 d0a9b5bc Avi Kivity
                                           mr->ops->endianness);
1030 d0a9b5bc Avi Kivity
    mr->ram_addr |= IO_MEM_ROMD;
1031 d0a9b5bc Avi Kivity
    mr->backend_registered = true;
1032 d0a9b5bc Avi Kivity
}
1033 d0a9b5bc Avi Kivity
1034 093bc2cd Avi Kivity
void memory_region_destroy(MemoryRegion *mr)
1035 093bc2cd Avi Kivity
{
1036 093bc2cd Avi Kivity
    assert(QTAILQ_EMPTY(&mr->subregions));
1037 545e92e0 Avi Kivity
    mr->destructor(mr);
1038 093bc2cd Avi Kivity
    memory_region_clear_coalescing(mr);
1039 7267c094 Anthony Liguori
    g_free((char *)mr->name);
1040 7267c094 Anthony Liguori
    g_free(mr->ioeventfds);
1041 093bc2cd Avi Kivity
}
1042 093bc2cd Avi Kivity
1043 093bc2cd Avi Kivity
uint64_t memory_region_size(MemoryRegion *mr)
1044 093bc2cd Avi Kivity
{
1045 08dafab4 Avi Kivity
    if (int128_eq(mr->size, int128_2_64())) {
1046 08dafab4 Avi Kivity
        return UINT64_MAX;
1047 08dafab4 Avi Kivity
    }
1048 08dafab4 Avi Kivity
    return int128_get64(mr->size);
1049 093bc2cd Avi Kivity
}
1050 093bc2cd Avi Kivity
1051 093bc2cd Avi Kivity
void memory_region_set_offset(MemoryRegion *mr, target_phys_addr_t offset)
1052 093bc2cd Avi Kivity
{
1053 093bc2cd Avi Kivity
    mr->offset = offset;
1054 093bc2cd Avi Kivity
}
1055 093bc2cd Avi Kivity
1056 093bc2cd Avi Kivity
void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
1057 093bc2cd Avi Kivity
{
1058 5a583347 Avi Kivity
    uint8_t mask = 1 << client;
1059 5a583347 Avi Kivity
1060 5a583347 Avi Kivity
    mr->dirty_log_mask = (mr->dirty_log_mask & ~mask) | (log * mask);
1061 5a583347 Avi Kivity
    memory_region_update_topology();
1062 093bc2cd Avi Kivity
}
1063 093bc2cd Avi Kivity
1064 093bc2cd Avi Kivity
bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr,
1065 093bc2cd Avi Kivity
                             unsigned client)
1066 093bc2cd Avi Kivity
{
1067 14a3c10a Avi Kivity
    assert(mr->terminates);
1068 5a583347 Avi Kivity
    return cpu_physical_memory_get_dirty(mr->ram_addr + addr, 1 << client);
1069 093bc2cd Avi Kivity
}
1070 093bc2cd Avi Kivity
1071 093bc2cd Avi Kivity
void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr)
1072 093bc2cd Avi Kivity
{
1073 14a3c10a Avi Kivity
    assert(mr->terminates);
1074 5a583347 Avi Kivity
    return cpu_physical_memory_set_dirty(mr->ram_addr + addr);
1075 093bc2cd Avi Kivity
}
1076 093bc2cd Avi Kivity
1077 093bc2cd Avi Kivity
void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
1078 093bc2cd Avi Kivity
{
1079 5a583347 Avi Kivity
    FlatRange *fr;
1080 5a583347 Avi Kivity
1081 cc31e6e7 Avi Kivity
    FOR_EACH_FLAT_RANGE(fr, &address_space_memory.current_map) {
1082 5a583347 Avi Kivity
        if (fr->mr == mr) {
1083 08dafab4 Avi Kivity
            cpu_physical_sync_dirty_bitmap(int128_get64(fr->addr.start),
1084 08dafab4 Avi Kivity
                                           int128_get64(addrrange_end(fr->addr)));
1085 5a583347 Avi Kivity
        }
1086 5a583347 Avi Kivity
    }
1087 093bc2cd Avi Kivity
}
1088 093bc2cd Avi Kivity
1089 093bc2cd Avi Kivity
void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
1090 093bc2cd Avi Kivity
{
1091 fb1cd6f9 Avi Kivity
    if (mr->readonly != readonly) {
1092 fb1cd6f9 Avi Kivity
        mr->readonly = readonly;
1093 fb1cd6f9 Avi Kivity
        memory_region_update_topology();
1094 fb1cd6f9 Avi Kivity
    }
1095 093bc2cd Avi Kivity
}
1096 093bc2cd Avi Kivity
1097 d0a9b5bc Avi Kivity
void memory_region_rom_device_set_readable(MemoryRegion *mr, bool readable)
1098 d0a9b5bc Avi Kivity
{
1099 d0a9b5bc Avi Kivity
    if (mr->readable != readable) {
1100 d0a9b5bc Avi Kivity
        mr->readable = readable;
1101 d0a9b5bc Avi Kivity
        memory_region_update_topology();
1102 d0a9b5bc Avi Kivity
    }
1103 d0a9b5bc Avi Kivity
}
1104 d0a9b5bc Avi Kivity
1105 093bc2cd Avi Kivity
void memory_region_reset_dirty(MemoryRegion *mr, target_phys_addr_t addr,
1106 093bc2cd Avi Kivity
                               target_phys_addr_t size, unsigned client)
1107 093bc2cd Avi Kivity
{
1108 14a3c10a Avi Kivity
    assert(mr->terminates);
1109 5a583347 Avi Kivity
    cpu_physical_memory_reset_dirty(mr->ram_addr + addr,
1110 5a583347 Avi Kivity
                                    mr->ram_addr + addr + size,
1111 5a583347 Avi Kivity
                                    1 << client);
1112 093bc2cd Avi Kivity
}
1113 093bc2cd Avi Kivity
1114 093bc2cd Avi Kivity
void *memory_region_get_ram_ptr(MemoryRegion *mr)
1115 093bc2cd Avi Kivity
{
1116 093bc2cd Avi Kivity
    if (mr->alias) {
1117 093bc2cd Avi Kivity
        return memory_region_get_ram_ptr(mr->alias) + mr->alias_offset;
1118 093bc2cd Avi Kivity
    }
1119 093bc2cd Avi Kivity
1120 14a3c10a Avi Kivity
    assert(mr->terminates);
1121 093bc2cd Avi Kivity
1122 021d26d1 Jan Kiszka
    return qemu_get_ram_ptr(mr->ram_addr & TARGET_PAGE_MASK);
1123 093bc2cd Avi Kivity
}
1124 093bc2cd Avi Kivity
1125 093bc2cd Avi Kivity
static void memory_region_update_coalesced_range(MemoryRegion *mr)
1126 093bc2cd Avi Kivity
{
1127 093bc2cd Avi Kivity
    FlatRange *fr;
1128 093bc2cd Avi Kivity
    CoalescedMemoryRange *cmr;
1129 093bc2cd Avi Kivity
    AddrRange tmp;
1130 093bc2cd Avi Kivity
1131 cc31e6e7 Avi Kivity
    FOR_EACH_FLAT_RANGE(fr, &address_space_memory.current_map) {
1132 093bc2cd Avi Kivity
        if (fr->mr == mr) {
1133 08dafab4 Avi Kivity
            qemu_unregister_coalesced_mmio(int128_get64(fr->addr.start),
1134 08dafab4 Avi Kivity
                                           int128_get64(fr->addr.size));
1135 093bc2cd Avi Kivity
            QTAILQ_FOREACH(cmr, &mr->coalesced, link) {
1136 093bc2cd Avi Kivity
                tmp = addrrange_shift(cmr->addr,
1137 08dafab4 Avi Kivity
                                      int128_sub(fr->addr.start,
1138 08dafab4 Avi Kivity
                                                 int128_make64(fr->offset_in_region)));
1139 093bc2cd Avi Kivity
                if (!addrrange_intersects(tmp, fr->addr)) {
1140 093bc2cd Avi Kivity
                    continue;
1141 093bc2cd Avi Kivity
                }
1142 093bc2cd Avi Kivity
                tmp = addrrange_intersection(tmp, fr->addr);
1143 08dafab4 Avi Kivity
                qemu_register_coalesced_mmio(int128_get64(tmp.start),
1144 08dafab4 Avi Kivity
                                             int128_get64(tmp.size));
1145 093bc2cd Avi Kivity
            }
1146 093bc2cd Avi Kivity
        }
1147 093bc2cd Avi Kivity
    }
1148 093bc2cd Avi Kivity
}
1149 093bc2cd Avi Kivity
1150 093bc2cd Avi Kivity
void memory_region_set_coalescing(MemoryRegion *mr)
1151 093bc2cd Avi Kivity
{
1152 093bc2cd Avi Kivity
    memory_region_clear_coalescing(mr);
1153 08dafab4 Avi Kivity
    memory_region_add_coalescing(mr, 0, int128_get64(mr->size));
1154 093bc2cd Avi Kivity
}
1155 093bc2cd Avi Kivity
1156 093bc2cd Avi Kivity
void memory_region_add_coalescing(MemoryRegion *mr,
1157 093bc2cd Avi Kivity
                                  target_phys_addr_t offset,
1158 093bc2cd Avi Kivity
                                  uint64_t size)
1159 093bc2cd Avi Kivity
{
1160 7267c094 Anthony Liguori
    CoalescedMemoryRange *cmr = g_malloc(sizeof(*cmr));
1161 093bc2cd Avi Kivity
1162 08dafab4 Avi Kivity
    cmr->addr = addrrange_make(int128_make64(offset), int128_make64(size));
1163 093bc2cd Avi Kivity
    QTAILQ_INSERT_TAIL(&mr->coalesced, cmr, link);
1164 093bc2cd Avi Kivity
    memory_region_update_coalesced_range(mr);
1165 093bc2cd Avi Kivity
}
1166 093bc2cd Avi Kivity
1167 093bc2cd Avi Kivity
void memory_region_clear_coalescing(MemoryRegion *mr)
1168 093bc2cd Avi Kivity
{
1169 093bc2cd Avi Kivity
    CoalescedMemoryRange *cmr;
1170 093bc2cd Avi Kivity
1171 093bc2cd Avi Kivity
    while (!QTAILQ_EMPTY(&mr->coalesced)) {
1172 093bc2cd Avi Kivity
        cmr = QTAILQ_FIRST(&mr->coalesced);
1173 093bc2cd Avi Kivity
        QTAILQ_REMOVE(&mr->coalesced, cmr, link);
1174 7267c094 Anthony Liguori
        g_free(cmr);
1175 093bc2cd Avi Kivity
    }
1176 093bc2cd Avi Kivity
    memory_region_update_coalesced_range(mr);
1177 093bc2cd Avi Kivity
}
1178 093bc2cd Avi Kivity
1179 3e9d69e7 Avi Kivity
void memory_region_add_eventfd(MemoryRegion *mr,
1180 3e9d69e7 Avi Kivity
                               target_phys_addr_t addr,
1181 3e9d69e7 Avi Kivity
                               unsigned size,
1182 3e9d69e7 Avi Kivity
                               bool match_data,
1183 3e9d69e7 Avi Kivity
                               uint64_t data,
1184 3e9d69e7 Avi Kivity
                               int fd)
1185 3e9d69e7 Avi Kivity
{
1186 3e9d69e7 Avi Kivity
    MemoryRegionIoeventfd mrfd = {
1187 08dafab4 Avi Kivity
        .addr.start = int128_make64(addr),
1188 08dafab4 Avi Kivity
        .addr.size = int128_make64(size),
1189 3e9d69e7 Avi Kivity
        .match_data = match_data,
1190 3e9d69e7 Avi Kivity
        .data = data,
1191 3e9d69e7 Avi Kivity
        .fd = fd,
1192 3e9d69e7 Avi Kivity
    };
1193 3e9d69e7 Avi Kivity
    unsigned i;
1194 3e9d69e7 Avi Kivity
1195 3e9d69e7 Avi Kivity
    for (i = 0; i < mr->ioeventfd_nb; ++i) {
1196 3e9d69e7 Avi Kivity
        if (memory_region_ioeventfd_before(mrfd, mr->ioeventfds[i])) {
1197 3e9d69e7 Avi Kivity
            break;
1198 3e9d69e7 Avi Kivity
        }
1199 3e9d69e7 Avi Kivity
    }
1200 3e9d69e7 Avi Kivity
    ++mr->ioeventfd_nb;
1201 7267c094 Anthony Liguori
    mr->ioeventfds = g_realloc(mr->ioeventfds,
1202 3e9d69e7 Avi Kivity
                                  sizeof(*mr->ioeventfds) * mr->ioeventfd_nb);
1203 3e9d69e7 Avi Kivity
    memmove(&mr->ioeventfds[i+1], &mr->ioeventfds[i],
1204 3e9d69e7 Avi Kivity
            sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb-1 - i));
1205 3e9d69e7 Avi Kivity
    mr->ioeventfds[i] = mrfd;
1206 3e9d69e7 Avi Kivity
    memory_region_update_topology();
1207 3e9d69e7 Avi Kivity
}
1208 3e9d69e7 Avi Kivity
1209 3e9d69e7 Avi Kivity
void memory_region_del_eventfd(MemoryRegion *mr,
1210 3e9d69e7 Avi Kivity
                               target_phys_addr_t addr,
1211 3e9d69e7 Avi Kivity
                               unsigned size,
1212 3e9d69e7 Avi Kivity
                               bool match_data,
1213 3e9d69e7 Avi Kivity
                               uint64_t data,
1214 3e9d69e7 Avi Kivity
                               int fd)
1215 3e9d69e7 Avi Kivity
{
1216 3e9d69e7 Avi Kivity
    MemoryRegionIoeventfd mrfd = {
1217 08dafab4 Avi Kivity
        .addr.start = int128_make64(addr),
1218 08dafab4 Avi Kivity
        .addr.size = int128_make64(size),
1219 3e9d69e7 Avi Kivity
        .match_data = match_data,
1220 3e9d69e7 Avi Kivity
        .data = data,
1221 3e9d69e7 Avi Kivity
        .fd = fd,
1222 3e9d69e7 Avi Kivity
    };
1223 3e9d69e7 Avi Kivity
    unsigned i;
1224 3e9d69e7 Avi Kivity
1225 3e9d69e7 Avi Kivity
    for (i = 0; i < mr->ioeventfd_nb; ++i) {
1226 3e9d69e7 Avi Kivity
        if (memory_region_ioeventfd_equal(mrfd, mr->ioeventfds[i])) {
1227 3e9d69e7 Avi Kivity
            break;
1228 3e9d69e7 Avi Kivity
        }
1229 3e9d69e7 Avi Kivity
    }
1230 3e9d69e7 Avi Kivity
    assert(i != mr->ioeventfd_nb);
1231 3e9d69e7 Avi Kivity
    memmove(&mr->ioeventfds[i], &mr->ioeventfds[i+1],
1232 3e9d69e7 Avi Kivity
            sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb - (i+1)));
1233 3e9d69e7 Avi Kivity
    --mr->ioeventfd_nb;
1234 7267c094 Anthony Liguori
    mr->ioeventfds = g_realloc(mr->ioeventfds,
1235 3e9d69e7 Avi Kivity
                                  sizeof(*mr->ioeventfds)*mr->ioeventfd_nb + 1);
1236 3e9d69e7 Avi Kivity
    memory_region_update_topology();
1237 3e9d69e7 Avi Kivity
}
1238 3e9d69e7 Avi Kivity
1239 093bc2cd Avi Kivity
static void memory_region_add_subregion_common(MemoryRegion *mr,
1240 093bc2cd Avi Kivity
                                               target_phys_addr_t offset,
1241 093bc2cd Avi Kivity
                                               MemoryRegion *subregion)
1242 093bc2cd Avi Kivity
{
1243 093bc2cd Avi Kivity
    MemoryRegion *other;
1244 093bc2cd Avi Kivity
1245 093bc2cd Avi Kivity
    assert(!subregion->parent);
1246 093bc2cd Avi Kivity
    subregion->parent = mr;
1247 093bc2cd Avi Kivity
    subregion->addr = offset;
1248 093bc2cd Avi Kivity
    QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
1249 093bc2cd Avi Kivity
        if (subregion->may_overlap || other->may_overlap) {
1250 093bc2cd Avi Kivity
            continue;
1251 093bc2cd Avi Kivity
        }
1252 08dafab4 Avi Kivity
        if (int128_gt(int128_make64(offset),
1253 08dafab4 Avi Kivity
                      int128_add(int128_make64(other->addr), other->size))
1254 08dafab4 Avi Kivity
            || int128_le(int128_add(int128_make64(offset), subregion->size),
1255 08dafab4 Avi Kivity
                         int128_make64(other->addr))) {
1256 093bc2cd Avi Kivity
            continue;
1257 093bc2cd Avi Kivity
        }
1258 a5e1cbc8 Anthony Liguori
#if 0
1259 860329b2 Michael Walle
        printf("warning: subregion collision %llx/%llx (%s) "
1260 860329b2 Michael Walle
               "vs %llx/%llx (%s)\n",
1261 093bc2cd Avi Kivity
               (unsigned long long)offset,
1262 08dafab4 Avi Kivity
               (unsigned long long)int128_get64(subregion->size),
1263 860329b2 Michael Walle
               subregion->name,
1264 860329b2 Michael Walle
               (unsigned long long)other->addr,
1265 08dafab4 Avi Kivity
               (unsigned long long)int128_get64(other->size),
1266 860329b2 Michael Walle
               other->name);
1267 a5e1cbc8 Anthony Liguori
#endif
1268 093bc2cd Avi Kivity
    }
1269 093bc2cd Avi Kivity
    QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
1270 093bc2cd Avi Kivity
        if (subregion->priority >= other->priority) {
1271 093bc2cd Avi Kivity
            QTAILQ_INSERT_BEFORE(other, subregion, subregions_link);
1272 093bc2cd Avi Kivity
            goto done;
1273 093bc2cd Avi Kivity
        }
1274 093bc2cd Avi Kivity
    }
1275 093bc2cd Avi Kivity
    QTAILQ_INSERT_TAIL(&mr->subregions, subregion, subregions_link);
1276 093bc2cd Avi Kivity
done:
1277 093bc2cd Avi Kivity
    memory_region_update_topology();
1278 093bc2cd Avi Kivity
}
1279 093bc2cd Avi Kivity
1280 093bc2cd Avi Kivity
1281 093bc2cd Avi Kivity
void memory_region_add_subregion(MemoryRegion *mr,
1282 093bc2cd Avi Kivity
                                 target_phys_addr_t offset,
1283 093bc2cd Avi Kivity
                                 MemoryRegion *subregion)
1284 093bc2cd Avi Kivity
{
1285 093bc2cd Avi Kivity
    subregion->may_overlap = false;
1286 093bc2cd Avi Kivity
    subregion->priority = 0;
1287 093bc2cd Avi Kivity
    memory_region_add_subregion_common(mr, offset, subregion);
1288 093bc2cd Avi Kivity
}
1289 093bc2cd Avi Kivity
1290 093bc2cd Avi Kivity
void memory_region_add_subregion_overlap(MemoryRegion *mr,
1291 093bc2cd Avi Kivity
                                         target_phys_addr_t offset,
1292 093bc2cd Avi Kivity
                                         MemoryRegion *subregion,
1293 093bc2cd Avi Kivity
                                         unsigned priority)
1294 093bc2cd Avi Kivity
{
1295 093bc2cd Avi Kivity
    subregion->may_overlap = true;
1296 093bc2cd Avi Kivity
    subregion->priority = priority;
1297 093bc2cd Avi Kivity
    memory_region_add_subregion_common(mr, offset, subregion);
1298 093bc2cd Avi Kivity
}
1299 093bc2cd Avi Kivity
1300 093bc2cd Avi Kivity
void memory_region_del_subregion(MemoryRegion *mr,
1301 093bc2cd Avi Kivity
                                 MemoryRegion *subregion)
1302 093bc2cd Avi Kivity
{
1303 093bc2cd Avi Kivity
    assert(subregion->parent == mr);
1304 093bc2cd Avi Kivity
    subregion->parent = NULL;
1305 093bc2cd Avi Kivity
    QTAILQ_REMOVE(&mr->subregions, subregion, subregions_link);
1306 093bc2cd Avi Kivity
    memory_region_update_topology();
1307 093bc2cd Avi Kivity
}
1308 1c0ffa58 Avi Kivity
1309 1c0ffa58 Avi Kivity
void set_system_memory_map(MemoryRegion *mr)
1310 1c0ffa58 Avi Kivity
{
1311 cc31e6e7 Avi Kivity
    address_space_memory.root = mr;
1312 1c0ffa58 Avi Kivity
    memory_region_update_topology();
1313 1c0ffa58 Avi Kivity
}
1314 658b2224 Avi Kivity
1315 658b2224 Avi Kivity
void set_system_io_map(MemoryRegion *mr)
1316 658b2224 Avi Kivity
{
1317 658b2224 Avi Kivity
    address_space_io.root = mr;
1318 658b2224 Avi Kivity
    memory_region_update_topology();
1319 658b2224 Avi Kivity
}
1320 314e2987 Blue Swirl
1321 314e2987 Blue Swirl
typedef struct MemoryRegionList MemoryRegionList;
1322 314e2987 Blue Swirl
1323 314e2987 Blue Swirl
struct MemoryRegionList {
1324 314e2987 Blue Swirl
    const MemoryRegion *mr;
1325 314e2987 Blue Swirl
    bool printed;
1326 314e2987 Blue Swirl
    QTAILQ_ENTRY(MemoryRegionList) queue;
1327 314e2987 Blue Swirl
};
1328 314e2987 Blue Swirl
1329 314e2987 Blue Swirl
typedef QTAILQ_HEAD(queue, MemoryRegionList) MemoryRegionListHead;
1330 314e2987 Blue Swirl
1331 314e2987 Blue Swirl
static void mtree_print_mr(fprintf_function mon_printf, void *f,
1332 314e2987 Blue Swirl
                           const MemoryRegion *mr, unsigned int level,
1333 314e2987 Blue Swirl
                           target_phys_addr_t base,
1334 9479c57a Jan Kiszka
                           MemoryRegionListHead *alias_print_queue)
1335 314e2987 Blue Swirl
{
1336 9479c57a Jan Kiszka
    MemoryRegionList *new_ml, *ml, *next_ml;
1337 9479c57a Jan Kiszka
    MemoryRegionListHead submr_print_queue;
1338 314e2987 Blue Swirl
    const MemoryRegion *submr;
1339 314e2987 Blue Swirl
    unsigned int i;
1340 314e2987 Blue Swirl
1341 314e2987 Blue Swirl
    if (!mr) {
1342 314e2987 Blue Swirl
        return;
1343 314e2987 Blue Swirl
    }
1344 314e2987 Blue Swirl
1345 314e2987 Blue Swirl
    for (i = 0; i < level; i++) {
1346 314e2987 Blue Swirl
        mon_printf(f, "  ");
1347 314e2987 Blue Swirl
    }
1348 314e2987 Blue Swirl
1349 314e2987 Blue Swirl
    if (mr->alias) {
1350 314e2987 Blue Swirl
        MemoryRegionList *ml;
1351 314e2987 Blue Swirl
        bool found = false;
1352 314e2987 Blue Swirl
1353 314e2987 Blue Swirl
        /* check if the alias is already in the queue */
1354 9479c57a Jan Kiszka
        QTAILQ_FOREACH(ml, alias_print_queue, queue) {
1355 314e2987 Blue Swirl
            if (ml->mr == mr->alias && !ml->printed) {
1356 314e2987 Blue Swirl
                found = true;
1357 314e2987 Blue Swirl
            }
1358 314e2987 Blue Swirl
        }
1359 314e2987 Blue Swirl
1360 314e2987 Blue Swirl
        if (!found) {
1361 314e2987 Blue Swirl
            ml = g_new(MemoryRegionList, 1);
1362 314e2987 Blue Swirl
            ml->mr = mr->alias;
1363 314e2987 Blue Swirl
            ml->printed = false;
1364 9479c57a Jan Kiszka
            QTAILQ_INSERT_TAIL(alias_print_queue, ml, queue);
1365 314e2987 Blue Swirl
        }
1366 4b474ba7 Jan Kiszka
        mon_printf(f, TARGET_FMT_plx "-" TARGET_FMT_plx " (prio %d): alias %s @%s "
1367 314e2987 Blue Swirl
                   TARGET_FMT_plx "-" TARGET_FMT_plx "\n",
1368 314e2987 Blue Swirl
                   base + mr->addr,
1369 08dafab4 Avi Kivity
                   base + mr->addr
1370 08dafab4 Avi Kivity
                   + (target_phys_addr_t)int128_get64(mr->size) - 1,
1371 4b474ba7 Jan Kiszka
                   mr->priority,
1372 314e2987 Blue Swirl
                   mr->name,
1373 314e2987 Blue Swirl
                   mr->alias->name,
1374 314e2987 Blue Swirl
                   mr->alias_offset,
1375 08dafab4 Avi Kivity
                   mr->alias_offset
1376 08dafab4 Avi Kivity
                   + (target_phys_addr_t)int128_get64(mr->size) - 1);
1377 314e2987 Blue Swirl
    } else {
1378 4b474ba7 Jan Kiszka
        mon_printf(f, TARGET_FMT_plx "-" TARGET_FMT_plx " (prio %d): %s\n",
1379 314e2987 Blue Swirl
                   base + mr->addr,
1380 08dafab4 Avi Kivity
                   base + mr->addr
1381 08dafab4 Avi Kivity
                   + (target_phys_addr_t)int128_get64(mr->size) - 1,
1382 4b474ba7 Jan Kiszka
                   mr->priority,
1383 314e2987 Blue Swirl
                   mr->name);
1384 314e2987 Blue Swirl
    }
1385 9479c57a Jan Kiszka
1386 9479c57a Jan Kiszka
    QTAILQ_INIT(&submr_print_queue);
1387 9479c57a Jan Kiszka
1388 314e2987 Blue Swirl
    QTAILQ_FOREACH(submr, &mr->subregions, subregions_link) {
1389 9479c57a Jan Kiszka
        new_ml = g_new(MemoryRegionList, 1);
1390 9479c57a Jan Kiszka
        new_ml->mr = submr;
1391 9479c57a Jan Kiszka
        QTAILQ_FOREACH(ml, &submr_print_queue, queue) {
1392 9479c57a Jan Kiszka
            if (new_ml->mr->addr < ml->mr->addr ||
1393 9479c57a Jan Kiszka
                (new_ml->mr->addr == ml->mr->addr &&
1394 9479c57a Jan Kiszka
                 new_ml->mr->priority > ml->mr->priority)) {
1395 9479c57a Jan Kiszka
                QTAILQ_INSERT_BEFORE(ml, new_ml, queue);
1396 9479c57a Jan Kiszka
                new_ml = NULL;
1397 9479c57a Jan Kiszka
                break;
1398 9479c57a Jan Kiszka
            }
1399 9479c57a Jan Kiszka
        }
1400 9479c57a Jan Kiszka
        if (new_ml) {
1401 9479c57a Jan Kiszka
            QTAILQ_INSERT_TAIL(&submr_print_queue, new_ml, queue);
1402 9479c57a Jan Kiszka
        }
1403 9479c57a Jan Kiszka
    }
1404 9479c57a Jan Kiszka
1405 9479c57a Jan Kiszka
    QTAILQ_FOREACH(ml, &submr_print_queue, queue) {
1406 9479c57a Jan Kiszka
        mtree_print_mr(mon_printf, f, ml->mr, level + 1, base + mr->addr,
1407 9479c57a Jan Kiszka
                       alias_print_queue);
1408 9479c57a Jan Kiszka
    }
1409 9479c57a Jan Kiszka
1410 88365e47 Avi Kivity
    QTAILQ_FOREACH_SAFE(ml, &submr_print_queue, queue, next_ml) {
1411 9479c57a Jan Kiszka
        g_free(ml);
1412 314e2987 Blue Swirl
    }
1413 314e2987 Blue Swirl
}
1414 314e2987 Blue Swirl
1415 314e2987 Blue Swirl
void mtree_info(fprintf_function mon_printf, void *f)
1416 314e2987 Blue Swirl
{
1417 314e2987 Blue Swirl
    MemoryRegionListHead ml_head;
1418 314e2987 Blue Swirl
    MemoryRegionList *ml, *ml2;
1419 314e2987 Blue Swirl
1420 314e2987 Blue Swirl
    QTAILQ_INIT(&ml_head);
1421 314e2987 Blue Swirl
1422 314e2987 Blue Swirl
    mon_printf(f, "memory\n");
1423 314e2987 Blue Swirl
    mtree_print_mr(mon_printf, f, address_space_memory.root, 0, 0, &ml_head);
1424 314e2987 Blue Swirl
1425 314e2987 Blue Swirl
    /* print aliased regions */
1426 314e2987 Blue Swirl
    QTAILQ_FOREACH(ml, &ml_head, queue) {
1427 314e2987 Blue Swirl
        if (!ml->printed) {
1428 314e2987 Blue Swirl
            mon_printf(f, "%s\n", ml->mr->name);
1429 314e2987 Blue Swirl
            mtree_print_mr(mon_printf, f, ml->mr, 0, 0, &ml_head);
1430 314e2987 Blue Swirl
        }
1431 314e2987 Blue Swirl
    }
1432 314e2987 Blue Swirl
1433 314e2987 Blue Swirl
    QTAILQ_FOREACH_SAFE(ml, &ml_head, queue, ml2) {
1434 88365e47 Avi Kivity
        g_free(ml);
1435 314e2987 Blue Swirl
    }
1436 314e2987 Blue Swirl
1437 06631810 Jan Kiszka
    if (address_space_io.root &&
1438 06631810 Jan Kiszka
        !QTAILQ_EMPTY(&address_space_io.root->subregions)) {
1439 06631810 Jan Kiszka
        QTAILQ_INIT(&ml_head);
1440 06631810 Jan Kiszka
        mon_printf(f, "I/O\n");
1441 06631810 Jan Kiszka
        mtree_print_mr(mon_printf, f, address_space_io.root, 0, 0, &ml_head);
1442 06631810 Jan Kiszka
    }
1443 314e2987 Blue Swirl
}