Statistics
| Branch: | Revision:

root / memory.c @ 5a37532d

History | View | Annotate | Download (53.7 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 6b620ca3 Paolo Bonzini
 * Contributions after 2012-01-13 are licensed under the terms of the
13 6b620ca3 Paolo Bonzini
 * GNU GPL, version 2 or (at your option) any later version.
14 093bc2cd Avi Kivity
 */
15 093bc2cd Avi Kivity
16 022c62cb Paolo Bonzini
#include "exec/memory.h"
17 022c62cb Paolo Bonzini
#include "exec/address-spaces.h"
18 022c62cb Paolo Bonzini
#include "exec/ioport.h"
19 1de7afc9 Paolo Bonzini
#include "qemu/bitops.h"
20 9c17d615 Paolo Bonzini
#include "sysemu/kvm.h"
21 093bc2cd Avi Kivity
#include <assert.h>
22 093bc2cd Avi Kivity
23 022c62cb Paolo Bonzini
#include "exec/memory-internal.h"
24 67d95c15 Avi Kivity
25 22bde714 Jan Kiszka
static unsigned memory_region_transaction_depth;
26 22bde714 Jan Kiszka
static bool memory_region_update_pending;
27 7664e80c Avi Kivity
static bool global_dirty_log = false;
28 7664e80c Avi Kivity
29 72e22d2f Avi Kivity
static QTAILQ_HEAD(memory_listeners, MemoryListener) memory_listeners
30 72e22d2f Avi Kivity
    = QTAILQ_HEAD_INITIALIZER(memory_listeners);
31 4ef4db86 Avi Kivity
32 0d673e36 Avi Kivity
static QTAILQ_HEAD(, AddressSpace) address_spaces
33 0d673e36 Avi Kivity
    = QTAILQ_HEAD_INITIALIZER(address_spaces);
34 0d673e36 Avi Kivity
35 093bc2cd Avi Kivity
typedef struct AddrRange AddrRange;
36 093bc2cd Avi Kivity
37 8417cebf Avi Kivity
/*
38 8417cebf Avi Kivity
 * Note using signed integers limits us to physical addresses at most
39 8417cebf Avi Kivity
 * 63 bits wide.  They are needed for negative offsetting in aliases
40 8417cebf Avi Kivity
 * (large MemoryRegion::alias_offset).
41 8417cebf Avi Kivity
 */
42 093bc2cd Avi Kivity
struct AddrRange {
43 08dafab4 Avi Kivity
    Int128 start;
44 08dafab4 Avi Kivity
    Int128 size;
45 093bc2cd Avi Kivity
};
46 093bc2cd Avi Kivity
47 08dafab4 Avi Kivity
static AddrRange addrrange_make(Int128 start, Int128 size)
48 093bc2cd Avi Kivity
{
49 093bc2cd Avi Kivity
    return (AddrRange) { start, size };
50 093bc2cd Avi Kivity
}
51 093bc2cd Avi Kivity
52 093bc2cd Avi Kivity
static bool addrrange_equal(AddrRange r1, AddrRange r2)
53 093bc2cd Avi Kivity
{
54 08dafab4 Avi Kivity
    return int128_eq(r1.start, r2.start) && int128_eq(r1.size, r2.size);
55 093bc2cd Avi Kivity
}
56 093bc2cd Avi Kivity
57 08dafab4 Avi Kivity
static Int128 addrrange_end(AddrRange r)
58 093bc2cd Avi Kivity
{
59 08dafab4 Avi Kivity
    return int128_add(r.start, r.size);
60 093bc2cd Avi Kivity
}
61 093bc2cd Avi Kivity
62 08dafab4 Avi Kivity
static AddrRange addrrange_shift(AddrRange range, Int128 delta)
63 093bc2cd Avi Kivity
{
64 08dafab4 Avi Kivity
    int128_addto(&range.start, delta);
65 093bc2cd Avi Kivity
    return range;
66 093bc2cd Avi Kivity
}
67 093bc2cd Avi Kivity
68 08dafab4 Avi Kivity
static bool addrrange_contains(AddrRange range, Int128 addr)
69 08dafab4 Avi Kivity
{
70 08dafab4 Avi Kivity
    return int128_ge(addr, range.start)
71 08dafab4 Avi Kivity
        && int128_lt(addr, addrrange_end(range));
72 08dafab4 Avi Kivity
}
73 08dafab4 Avi Kivity
74 093bc2cd Avi Kivity
static bool addrrange_intersects(AddrRange r1, AddrRange r2)
75 093bc2cd Avi Kivity
{
76 08dafab4 Avi Kivity
    return addrrange_contains(r1, r2.start)
77 08dafab4 Avi Kivity
        || addrrange_contains(r2, r1.start);
78 093bc2cd Avi Kivity
}
79 093bc2cd Avi Kivity
80 093bc2cd Avi Kivity
static AddrRange addrrange_intersection(AddrRange r1, AddrRange r2)
81 093bc2cd Avi Kivity
{
82 08dafab4 Avi Kivity
    Int128 start = int128_max(r1.start, r2.start);
83 08dafab4 Avi Kivity
    Int128 end = int128_min(addrrange_end(r1), addrrange_end(r2));
84 08dafab4 Avi Kivity
    return addrrange_make(start, int128_sub(end, start));
85 093bc2cd Avi Kivity
}
86 093bc2cd Avi Kivity
87 0e0d36b4 Avi Kivity
enum ListenerDirection { Forward, Reverse };
88 0e0d36b4 Avi Kivity
89 7376e582 Avi Kivity
static bool memory_listener_match(MemoryListener *listener,
90 7376e582 Avi Kivity
                                  MemoryRegionSection *section)
91 7376e582 Avi Kivity
{
92 7376e582 Avi Kivity
    return !listener->address_space_filter
93 7376e582 Avi Kivity
        || listener->address_space_filter == section->address_space;
94 7376e582 Avi Kivity
}
95 7376e582 Avi Kivity
96 7376e582 Avi Kivity
#define MEMORY_LISTENER_CALL_GLOBAL(_callback, _direction, _args...)    \
97 0e0d36b4 Avi Kivity
    do {                                                                \
98 0e0d36b4 Avi Kivity
        MemoryListener *_listener;                                      \
99 0e0d36b4 Avi Kivity
                                                                        \
100 0e0d36b4 Avi Kivity
        switch (_direction) {                                           \
101 0e0d36b4 Avi Kivity
        case Forward:                                                   \
102 0e0d36b4 Avi Kivity
            QTAILQ_FOREACH(_listener, &memory_listeners, link) {        \
103 975aefe0 Avi Kivity
                if (_listener->_callback) {                             \
104 975aefe0 Avi Kivity
                    _listener->_callback(_listener, ##_args);           \
105 975aefe0 Avi Kivity
                }                                                       \
106 0e0d36b4 Avi Kivity
            }                                                           \
107 0e0d36b4 Avi Kivity
            break;                                                      \
108 0e0d36b4 Avi Kivity
        case Reverse:                                                   \
109 0e0d36b4 Avi Kivity
            QTAILQ_FOREACH_REVERSE(_listener, &memory_listeners,        \
110 0e0d36b4 Avi Kivity
                                   memory_listeners, link) {            \
111 975aefe0 Avi Kivity
                if (_listener->_callback) {                             \
112 975aefe0 Avi Kivity
                    _listener->_callback(_listener, ##_args);           \
113 975aefe0 Avi Kivity
                }                                                       \
114 0e0d36b4 Avi Kivity
            }                                                           \
115 0e0d36b4 Avi Kivity
            break;                                                      \
116 0e0d36b4 Avi Kivity
        default:                                                        \
117 0e0d36b4 Avi Kivity
            abort();                                                    \
118 0e0d36b4 Avi Kivity
        }                                                               \
119 0e0d36b4 Avi Kivity
    } while (0)
120 0e0d36b4 Avi Kivity
121 7376e582 Avi Kivity
#define MEMORY_LISTENER_CALL(_callback, _direction, _section, _args...) \
122 7376e582 Avi Kivity
    do {                                                                \
123 7376e582 Avi Kivity
        MemoryListener *_listener;                                      \
124 7376e582 Avi Kivity
                                                                        \
125 7376e582 Avi Kivity
        switch (_direction) {                                           \
126 7376e582 Avi Kivity
        case Forward:                                                   \
127 7376e582 Avi Kivity
            QTAILQ_FOREACH(_listener, &memory_listeners, link) {        \
128 975aefe0 Avi Kivity
                if (_listener->_callback                                \
129 975aefe0 Avi Kivity
                    && memory_listener_match(_listener, _section)) {    \
130 7376e582 Avi Kivity
                    _listener->_callback(_listener, _section, ##_args); \
131 7376e582 Avi Kivity
                }                                                       \
132 7376e582 Avi Kivity
            }                                                           \
133 7376e582 Avi Kivity
            break;                                                      \
134 7376e582 Avi Kivity
        case Reverse:                                                   \
135 7376e582 Avi Kivity
            QTAILQ_FOREACH_REVERSE(_listener, &memory_listeners,        \
136 7376e582 Avi Kivity
                                   memory_listeners, link) {            \
137 975aefe0 Avi Kivity
                if (_listener->_callback                                \
138 975aefe0 Avi Kivity
                    && memory_listener_match(_listener, _section)) {    \
139 7376e582 Avi Kivity
                    _listener->_callback(_listener, _section, ##_args); \
140 7376e582 Avi Kivity
                }                                                       \
141 7376e582 Avi Kivity
            }                                                           \
142 7376e582 Avi Kivity
            break;                                                      \
143 7376e582 Avi Kivity
        default:                                                        \
144 7376e582 Avi Kivity
            abort();                                                    \
145 7376e582 Avi Kivity
        }                                                               \
146 7376e582 Avi Kivity
    } while (0)
147 7376e582 Avi Kivity
148 0e0d36b4 Avi Kivity
#define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback)            \
149 7376e582 Avi Kivity
    MEMORY_LISTENER_CALL(callback, dir, (&(MemoryRegionSection) {       \
150 0e0d36b4 Avi Kivity
        .mr = (fr)->mr,                                                 \
151 f6790af6 Avi Kivity
        .address_space = (as),                                          \
152 0e0d36b4 Avi Kivity
        .offset_within_region = (fr)->offset_in_region,                 \
153 0e0d36b4 Avi Kivity
        .size = int128_get64((fr)->addr.size),                          \
154 0e0d36b4 Avi Kivity
        .offset_within_address_space = int128_get64((fr)->addr.start),  \
155 7a8499e8 Avi Kivity
        .readonly = (fr)->readonly,                                     \
156 7376e582 Avi Kivity
              }))
157 0e0d36b4 Avi Kivity
158 093bc2cd Avi Kivity
struct CoalescedMemoryRange {
159 093bc2cd Avi Kivity
    AddrRange addr;
160 093bc2cd Avi Kivity
    QTAILQ_ENTRY(CoalescedMemoryRange) link;
161 093bc2cd Avi Kivity
};
162 093bc2cd Avi Kivity
163 3e9d69e7 Avi Kivity
struct MemoryRegionIoeventfd {
164 3e9d69e7 Avi Kivity
    AddrRange addr;
165 3e9d69e7 Avi Kivity
    bool match_data;
166 3e9d69e7 Avi Kivity
    uint64_t data;
167 753d5e14 Paolo Bonzini
    EventNotifier *e;
168 3e9d69e7 Avi Kivity
};
169 3e9d69e7 Avi Kivity
170 3e9d69e7 Avi Kivity
static bool memory_region_ioeventfd_before(MemoryRegionIoeventfd a,
171 3e9d69e7 Avi Kivity
                                           MemoryRegionIoeventfd b)
172 3e9d69e7 Avi Kivity
{
173 08dafab4 Avi Kivity
    if (int128_lt(a.addr.start, b.addr.start)) {
174 3e9d69e7 Avi Kivity
        return true;
175 08dafab4 Avi Kivity
    } else if (int128_gt(a.addr.start, b.addr.start)) {
176 3e9d69e7 Avi Kivity
        return false;
177 08dafab4 Avi Kivity
    } else if (int128_lt(a.addr.size, b.addr.size)) {
178 3e9d69e7 Avi Kivity
        return true;
179 08dafab4 Avi Kivity
    } else if (int128_gt(a.addr.size, b.addr.size)) {
180 3e9d69e7 Avi Kivity
        return false;
181 3e9d69e7 Avi Kivity
    } else if (a.match_data < b.match_data) {
182 3e9d69e7 Avi Kivity
        return true;
183 3e9d69e7 Avi Kivity
    } else  if (a.match_data > b.match_data) {
184 3e9d69e7 Avi Kivity
        return false;
185 3e9d69e7 Avi Kivity
    } else if (a.match_data) {
186 3e9d69e7 Avi Kivity
        if (a.data < b.data) {
187 3e9d69e7 Avi Kivity
            return true;
188 3e9d69e7 Avi Kivity
        } else if (a.data > b.data) {
189 3e9d69e7 Avi Kivity
            return false;
190 3e9d69e7 Avi Kivity
        }
191 3e9d69e7 Avi Kivity
    }
192 753d5e14 Paolo Bonzini
    if (a.e < b.e) {
193 3e9d69e7 Avi Kivity
        return true;
194 753d5e14 Paolo Bonzini
    } else if (a.e > b.e) {
195 3e9d69e7 Avi Kivity
        return false;
196 3e9d69e7 Avi Kivity
    }
197 3e9d69e7 Avi Kivity
    return false;
198 3e9d69e7 Avi Kivity
}
199 3e9d69e7 Avi Kivity
200 3e9d69e7 Avi Kivity
static bool memory_region_ioeventfd_equal(MemoryRegionIoeventfd a,
201 3e9d69e7 Avi Kivity
                                          MemoryRegionIoeventfd b)
202 3e9d69e7 Avi Kivity
{
203 3e9d69e7 Avi Kivity
    return !memory_region_ioeventfd_before(a, b)
204 3e9d69e7 Avi Kivity
        && !memory_region_ioeventfd_before(b, a);
205 3e9d69e7 Avi Kivity
}
206 3e9d69e7 Avi Kivity
207 093bc2cd Avi Kivity
typedef struct FlatRange FlatRange;
208 093bc2cd Avi Kivity
typedef struct FlatView FlatView;
209 093bc2cd Avi Kivity
210 093bc2cd Avi Kivity
/* Range of memory in the global map.  Addresses are absolute. */
211 093bc2cd Avi Kivity
struct FlatRange {
212 093bc2cd Avi Kivity
    MemoryRegion *mr;
213 a8170e5e Avi Kivity
    hwaddr offset_in_region;
214 093bc2cd Avi Kivity
    AddrRange addr;
215 5a583347 Avi Kivity
    uint8_t dirty_log_mask;
216 d0a9b5bc Avi Kivity
    bool readable;
217 fb1cd6f9 Avi Kivity
    bool readonly;
218 093bc2cd Avi Kivity
};
219 093bc2cd Avi Kivity
220 093bc2cd Avi Kivity
/* Flattened global view of current active memory hierarchy.  Kept in sorted
221 093bc2cd Avi Kivity
 * order.
222 093bc2cd Avi Kivity
 */
223 093bc2cd Avi Kivity
struct FlatView {
224 093bc2cd Avi Kivity
    FlatRange *ranges;
225 093bc2cd Avi Kivity
    unsigned nr;
226 093bc2cd Avi Kivity
    unsigned nr_allocated;
227 093bc2cd Avi Kivity
};
228 093bc2cd Avi Kivity
229 cc31e6e7 Avi Kivity
typedef struct AddressSpaceOps AddressSpaceOps;
230 cc31e6e7 Avi Kivity
231 093bc2cd Avi Kivity
#define FOR_EACH_FLAT_RANGE(var, view)          \
232 093bc2cd Avi Kivity
    for (var = (view)->ranges; var < (view)->ranges + (view)->nr; ++var)
233 093bc2cd Avi Kivity
234 093bc2cd Avi Kivity
static bool flatrange_equal(FlatRange *a, FlatRange *b)
235 093bc2cd Avi Kivity
{
236 093bc2cd Avi Kivity
    return a->mr == b->mr
237 093bc2cd Avi Kivity
        && addrrange_equal(a->addr, b->addr)
238 d0a9b5bc Avi Kivity
        && a->offset_in_region == b->offset_in_region
239 fb1cd6f9 Avi Kivity
        && a->readable == b->readable
240 fb1cd6f9 Avi Kivity
        && a->readonly == b->readonly;
241 093bc2cd Avi Kivity
}
242 093bc2cd Avi Kivity
243 093bc2cd Avi Kivity
static void flatview_init(FlatView *view)
244 093bc2cd Avi Kivity
{
245 093bc2cd Avi Kivity
    view->ranges = NULL;
246 093bc2cd Avi Kivity
    view->nr = 0;
247 093bc2cd Avi Kivity
    view->nr_allocated = 0;
248 093bc2cd Avi Kivity
}
249 093bc2cd Avi Kivity
250 093bc2cd Avi Kivity
/* Insert a range into a given position.  Caller is responsible for maintaining
251 093bc2cd Avi Kivity
 * sorting order.
252 093bc2cd Avi Kivity
 */
253 093bc2cd Avi Kivity
static void flatview_insert(FlatView *view, unsigned pos, FlatRange *range)
254 093bc2cd Avi Kivity
{
255 093bc2cd Avi Kivity
    if (view->nr == view->nr_allocated) {
256 093bc2cd Avi Kivity
        view->nr_allocated = MAX(2 * view->nr, 10);
257 7267c094 Anthony Liguori
        view->ranges = g_realloc(view->ranges,
258 093bc2cd Avi Kivity
                                    view->nr_allocated * sizeof(*view->ranges));
259 093bc2cd Avi Kivity
    }
260 093bc2cd Avi Kivity
    memmove(view->ranges + pos + 1, view->ranges + pos,
261 093bc2cd Avi Kivity
            (view->nr - pos) * sizeof(FlatRange));
262 093bc2cd Avi Kivity
    view->ranges[pos] = *range;
263 093bc2cd Avi Kivity
    ++view->nr;
264 093bc2cd Avi Kivity
}
265 093bc2cd Avi Kivity
266 093bc2cd Avi Kivity
static void flatview_destroy(FlatView *view)
267 093bc2cd Avi Kivity
{
268 7267c094 Anthony Liguori
    g_free(view->ranges);
269 093bc2cd Avi Kivity
}
270 093bc2cd Avi Kivity
271 3d8e6bf9 Avi Kivity
static bool can_merge(FlatRange *r1, FlatRange *r2)
272 3d8e6bf9 Avi Kivity
{
273 08dafab4 Avi Kivity
    return int128_eq(addrrange_end(r1->addr), r2->addr.start)
274 3d8e6bf9 Avi Kivity
        && r1->mr == r2->mr
275 08dafab4 Avi Kivity
        && int128_eq(int128_add(int128_make64(r1->offset_in_region),
276 08dafab4 Avi Kivity
                                r1->addr.size),
277 08dafab4 Avi Kivity
                     int128_make64(r2->offset_in_region))
278 d0a9b5bc Avi Kivity
        && r1->dirty_log_mask == r2->dirty_log_mask
279 fb1cd6f9 Avi Kivity
        && r1->readable == r2->readable
280 fb1cd6f9 Avi Kivity
        && r1->readonly == r2->readonly;
281 3d8e6bf9 Avi Kivity
}
282 3d8e6bf9 Avi Kivity
283 3d8e6bf9 Avi Kivity
/* Attempt to simplify a view by merging ajacent ranges */
284 3d8e6bf9 Avi Kivity
static void flatview_simplify(FlatView *view)
285 3d8e6bf9 Avi Kivity
{
286 3d8e6bf9 Avi Kivity
    unsigned i, j;
287 3d8e6bf9 Avi Kivity
288 3d8e6bf9 Avi Kivity
    i = 0;
289 3d8e6bf9 Avi Kivity
    while (i < view->nr) {
290 3d8e6bf9 Avi Kivity
        j = i + 1;
291 3d8e6bf9 Avi Kivity
        while (j < view->nr
292 3d8e6bf9 Avi Kivity
               && can_merge(&view->ranges[j-1], &view->ranges[j])) {
293 08dafab4 Avi Kivity
            int128_addto(&view->ranges[i].addr.size, view->ranges[j].addr.size);
294 3d8e6bf9 Avi Kivity
            ++j;
295 3d8e6bf9 Avi Kivity
        }
296 3d8e6bf9 Avi Kivity
        ++i;
297 3d8e6bf9 Avi Kivity
        memmove(&view->ranges[i], &view->ranges[j],
298 3d8e6bf9 Avi Kivity
                (view->nr - j) * sizeof(view->ranges[j]));
299 3d8e6bf9 Avi Kivity
        view->nr -= j - i;
300 3d8e6bf9 Avi Kivity
    }
301 3d8e6bf9 Avi Kivity
}
302 3d8e6bf9 Avi Kivity
303 164a4dcd Avi Kivity
static void memory_region_read_accessor(void *opaque,
304 a8170e5e Avi Kivity
                                        hwaddr addr,
305 164a4dcd Avi Kivity
                                        uint64_t *value,
306 164a4dcd Avi Kivity
                                        unsigned size,
307 164a4dcd Avi Kivity
                                        unsigned shift,
308 164a4dcd Avi Kivity
                                        uint64_t mask)
309 164a4dcd Avi Kivity
{
310 164a4dcd Avi Kivity
    MemoryRegion *mr = opaque;
311 164a4dcd Avi Kivity
    uint64_t tmp;
312 164a4dcd Avi Kivity
313 d410515e Jan Kiszka
    if (mr->flush_coalesced_mmio) {
314 d410515e Jan Kiszka
        qemu_flush_coalesced_mmio_buffer();
315 d410515e Jan Kiszka
    }
316 164a4dcd Avi Kivity
    tmp = mr->ops->read(mr->opaque, addr, size);
317 164a4dcd Avi Kivity
    *value |= (tmp & mask) << shift;
318 164a4dcd Avi Kivity
}
319 164a4dcd Avi Kivity
320 164a4dcd Avi Kivity
static void memory_region_write_accessor(void *opaque,
321 a8170e5e Avi Kivity
                                         hwaddr addr,
322 164a4dcd Avi Kivity
                                         uint64_t *value,
323 164a4dcd Avi Kivity
                                         unsigned size,
324 164a4dcd Avi Kivity
                                         unsigned shift,
325 164a4dcd Avi Kivity
                                         uint64_t mask)
326 164a4dcd Avi Kivity
{
327 164a4dcd Avi Kivity
    MemoryRegion *mr = opaque;
328 164a4dcd Avi Kivity
    uint64_t tmp;
329 164a4dcd Avi Kivity
330 d410515e Jan Kiszka
    if (mr->flush_coalesced_mmio) {
331 d410515e Jan Kiszka
        qemu_flush_coalesced_mmio_buffer();
332 d410515e Jan Kiszka
    }
333 164a4dcd Avi Kivity
    tmp = (*value >> shift) & mask;
334 164a4dcd Avi Kivity
    mr->ops->write(mr->opaque, addr, tmp, size);
335 164a4dcd Avi Kivity
}
336 164a4dcd Avi Kivity
337 a8170e5e Avi Kivity
static void access_with_adjusted_size(hwaddr addr,
338 164a4dcd Avi Kivity
                                      uint64_t *value,
339 164a4dcd Avi Kivity
                                      unsigned size,
340 164a4dcd Avi Kivity
                                      unsigned access_size_min,
341 164a4dcd Avi Kivity
                                      unsigned access_size_max,
342 164a4dcd Avi Kivity
                                      void (*access)(void *opaque,
343 a8170e5e Avi Kivity
                                                     hwaddr addr,
344 164a4dcd Avi Kivity
                                                     uint64_t *value,
345 164a4dcd Avi Kivity
                                                     unsigned size,
346 164a4dcd Avi Kivity
                                                     unsigned shift,
347 164a4dcd Avi Kivity
                                                     uint64_t mask),
348 164a4dcd Avi Kivity
                                      void *opaque)
349 164a4dcd Avi Kivity
{
350 164a4dcd Avi Kivity
    uint64_t access_mask;
351 164a4dcd Avi Kivity
    unsigned access_size;
352 164a4dcd Avi Kivity
    unsigned i;
353 164a4dcd Avi Kivity
354 164a4dcd Avi Kivity
    if (!access_size_min) {
355 164a4dcd Avi Kivity
        access_size_min = 1;
356 164a4dcd Avi Kivity
    }
357 164a4dcd Avi Kivity
    if (!access_size_max) {
358 164a4dcd Avi Kivity
        access_size_max = 4;
359 164a4dcd Avi Kivity
    }
360 164a4dcd Avi Kivity
    access_size = MAX(MIN(size, access_size_max), access_size_min);
361 164a4dcd Avi Kivity
    access_mask = -1ULL >> (64 - access_size * 8);
362 164a4dcd Avi Kivity
    for (i = 0; i < size; i += access_size) {
363 164a4dcd Avi Kivity
        /* FIXME: big-endian support */
364 164a4dcd Avi Kivity
        access(opaque, addr + i, value, access_size, i * 8, access_mask);
365 164a4dcd Avi Kivity
    }
366 164a4dcd Avi Kivity
}
367 164a4dcd Avi Kivity
368 627a0e90 Avi Kivity
static const MemoryRegionPortio *find_portio(MemoryRegion *mr, uint64_t offset,
369 627a0e90 Avi Kivity
                                             unsigned width, bool write)
370 627a0e90 Avi Kivity
{
371 627a0e90 Avi Kivity
    const MemoryRegionPortio *mrp;
372 627a0e90 Avi Kivity
373 627a0e90 Avi Kivity
    for (mrp = mr->ops->old_portio; mrp->size; ++mrp) {
374 627a0e90 Avi Kivity
        if (offset >= mrp->offset && offset < mrp->offset + mrp->len
375 627a0e90 Avi Kivity
            && width == mrp->size
376 627a0e90 Avi Kivity
            && (write ? (bool)mrp->write : (bool)mrp->read)) {
377 627a0e90 Avi Kivity
            return mrp;
378 627a0e90 Avi Kivity
        }
379 627a0e90 Avi Kivity
    }
380 627a0e90 Avi Kivity
    return NULL;
381 627a0e90 Avi Kivity
}
382 627a0e90 Avi Kivity
383 658b2224 Avi Kivity
static void memory_region_iorange_read(IORange *iorange,
384 658b2224 Avi Kivity
                                       uint64_t offset,
385 658b2224 Avi Kivity
                                       unsigned width,
386 658b2224 Avi Kivity
                                       uint64_t *data)
387 658b2224 Avi Kivity
{
388 a2d33521 Avi Kivity
    MemoryRegionIORange *mrio
389 a2d33521 Avi Kivity
        = container_of(iorange, MemoryRegionIORange, iorange);
390 a2d33521 Avi Kivity
    MemoryRegion *mr = mrio->mr;
391 658b2224 Avi Kivity
392 a2d33521 Avi Kivity
    offset += mrio->offset;
393 627a0e90 Avi Kivity
    if (mr->ops->old_portio) {
394 a2d33521 Avi Kivity
        const MemoryRegionPortio *mrp = find_portio(mr, offset - mrio->offset,
395 a2d33521 Avi Kivity
                                                    width, false);
396 627a0e90 Avi Kivity
397 627a0e90 Avi Kivity
        *data = ((uint64_t)1 << (width * 8)) - 1;
398 627a0e90 Avi Kivity
        if (mrp) {
399 2b50aa1f Avi Kivity
            *data = mrp->read(mr->opaque, offset);
400 03808f58 Jan Kiszka
        } else if (width == 2) {
401 a2d33521 Avi Kivity
            mrp = find_portio(mr, offset - mrio->offset, 1, false);
402 03808f58 Jan Kiszka
            assert(mrp);
403 2b50aa1f Avi Kivity
            *data = mrp->read(mr->opaque, offset) |
404 2b50aa1f Avi Kivity
                    (mrp->read(mr->opaque, offset + 1) << 8);
405 627a0e90 Avi Kivity
        }
406 627a0e90 Avi Kivity
        return;
407 627a0e90 Avi Kivity
    }
408 3a130f4e Avi Kivity
    *data = 0;
409 2b50aa1f Avi Kivity
    access_with_adjusted_size(offset, data, width,
410 3a130f4e Avi Kivity
                              mr->ops->impl.min_access_size,
411 3a130f4e Avi Kivity
                              mr->ops->impl.max_access_size,
412 3a130f4e Avi Kivity
                              memory_region_read_accessor, mr);
413 658b2224 Avi Kivity
}
414 658b2224 Avi Kivity
415 658b2224 Avi Kivity
static void memory_region_iorange_write(IORange *iorange,
416 658b2224 Avi Kivity
                                        uint64_t offset,
417 658b2224 Avi Kivity
                                        unsigned width,
418 658b2224 Avi Kivity
                                        uint64_t data)
419 658b2224 Avi Kivity
{
420 a2d33521 Avi Kivity
    MemoryRegionIORange *mrio
421 a2d33521 Avi Kivity
        = container_of(iorange, MemoryRegionIORange, iorange);
422 a2d33521 Avi Kivity
    MemoryRegion *mr = mrio->mr;
423 658b2224 Avi Kivity
424 a2d33521 Avi Kivity
    offset += mrio->offset;
425 627a0e90 Avi Kivity
    if (mr->ops->old_portio) {
426 a2d33521 Avi Kivity
        const MemoryRegionPortio *mrp = find_portio(mr, offset - mrio->offset,
427 a2d33521 Avi Kivity
                                                    width, true);
428 627a0e90 Avi Kivity
429 627a0e90 Avi Kivity
        if (mrp) {
430 2b50aa1f Avi Kivity
            mrp->write(mr->opaque, offset, data);
431 03808f58 Jan Kiszka
        } else if (width == 2) {
432 7e2a62d8 Jan Kiszka
            mrp = find_portio(mr, offset - mrio->offset, 1, true);
433 03808f58 Jan Kiszka
            assert(mrp);
434 2b50aa1f Avi Kivity
            mrp->write(mr->opaque, offset, data & 0xff);
435 2b50aa1f Avi Kivity
            mrp->write(mr->opaque, offset + 1, data >> 8);
436 627a0e90 Avi Kivity
        }
437 627a0e90 Avi Kivity
        return;
438 627a0e90 Avi Kivity
    }
439 2b50aa1f Avi Kivity
    access_with_adjusted_size(offset, &data, width,
440 3a130f4e Avi Kivity
                              mr->ops->impl.min_access_size,
441 3a130f4e Avi Kivity
                              mr->ops->impl.max_access_size,
442 3a130f4e Avi Kivity
                              memory_region_write_accessor, mr);
443 658b2224 Avi Kivity
}
444 658b2224 Avi Kivity
445 a2d33521 Avi Kivity
static void memory_region_iorange_destructor(IORange *iorange)
446 a2d33521 Avi Kivity
{
447 a2d33521 Avi Kivity
    g_free(container_of(iorange, MemoryRegionIORange, iorange));
448 a2d33521 Avi Kivity
}
449 a2d33521 Avi Kivity
450 93632747 Avi Kivity
const IORangeOps memory_region_iorange_ops = {
451 658b2224 Avi Kivity
    .read = memory_region_iorange_read,
452 658b2224 Avi Kivity
    .write = memory_region_iorange_write,
453 a2d33521 Avi Kivity
    .destructor = memory_region_iorange_destructor,
454 658b2224 Avi Kivity
};
455 658b2224 Avi Kivity
456 e2177955 Avi Kivity
static AddressSpace *memory_region_to_address_space(MemoryRegion *mr)
457 e2177955 Avi Kivity
{
458 0d673e36 Avi Kivity
    AddressSpace *as;
459 0d673e36 Avi Kivity
460 e2177955 Avi Kivity
    while (mr->parent) {
461 e2177955 Avi Kivity
        mr = mr->parent;
462 e2177955 Avi Kivity
    }
463 0d673e36 Avi Kivity
    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
464 0d673e36 Avi Kivity
        if (mr == as->root) {
465 0d673e36 Avi Kivity
            return as;
466 0d673e36 Avi Kivity
        }
467 e2177955 Avi Kivity
    }
468 e2177955 Avi Kivity
    abort();
469 e2177955 Avi Kivity
}
470 e2177955 Avi Kivity
471 093bc2cd Avi Kivity
/* Render a memory region into the global view.  Ranges in @view obscure
472 093bc2cd Avi Kivity
 * ranges in @mr.
473 093bc2cd Avi Kivity
 */
474 093bc2cd Avi Kivity
static void render_memory_region(FlatView *view,
475 093bc2cd Avi Kivity
                                 MemoryRegion *mr,
476 08dafab4 Avi Kivity
                                 Int128 base,
477 fb1cd6f9 Avi Kivity
                                 AddrRange clip,
478 fb1cd6f9 Avi Kivity
                                 bool readonly)
479 093bc2cd Avi Kivity
{
480 093bc2cd Avi Kivity
    MemoryRegion *subregion;
481 093bc2cd Avi Kivity
    unsigned i;
482 a8170e5e Avi Kivity
    hwaddr offset_in_region;
483 08dafab4 Avi Kivity
    Int128 remain;
484 08dafab4 Avi Kivity
    Int128 now;
485 093bc2cd Avi Kivity
    FlatRange fr;
486 093bc2cd Avi Kivity
    AddrRange tmp;
487 093bc2cd Avi Kivity
488 6bba19ba Avi Kivity
    if (!mr->enabled) {
489 6bba19ba Avi Kivity
        return;
490 6bba19ba Avi Kivity
    }
491 6bba19ba Avi Kivity
492 08dafab4 Avi Kivity
    int128_addto(&base, int128_make64(mr->addr));
493 fb1cd6f9 Avi Kivity
    readonly |= mr->readonly;
494 093bc2cd Avi Kivity
495 093bc2cd Avi Kivity
    tmp = addrrange_make(base, mr->size);
496 093bc2cd Avi Kivity
497 093bc2cd Avi Kivity
    if (!addrrange_intersects(tmp, clip)) {
498 093bc2cd Avi Kivity
        return;
499 093bc2cd Avi Kivity
    }
500 093bc2cd Avi Kivity
501 093bc2cd Avi Kivity
    clip = addrrange_intersection(tmp, clip);
502 093bc2cd Avi Kivity
503 093bc2cd Avi Kivity
    if (mr->alias) {
504 08dafab4 Avi Kivity
        int128_subfrom(&base, int128_make64(mr->alias->addr));
505 08dafab4 Avi Kivity
        int128_subfrom(&base, int128_make64(mr->alias_offset));
506 fb1cd6f9 Avi Kivity
        render_memory_region(view, mr->alias, base, clip, readonly);
507 093bc2cd Avi Kivity
        return;
508 093bc2cd Avi Kivity
    }
509 093bc2cd Avi Kivity
510 093bc2cd Avi Kivity
    /* Render subregions in priority order. */
511 093bc2cd Avi Kivity
    QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {
512 fb1cd6f9 Avi Kivity
        render_memory_region(view, subregion, base, clip, readonly);
513 093bc2cd Avi Kivity
    }
514 093bc2cd Avi Kivity
515 14a3c10a Avi Kivity
    if (!mr->terminates) {
516 093bc2cd Avi Kivity
        return;
517 093bc2cd Avi Kivity
    }
518 093bc2cd Avi Kivity
519 08dafab4 Avi Kivity
    offset_in_region = int128_get64(int128_sub(clip.start, base));
520 093bc2cd Avi Kivity
    base = clip.start;
521 093bc2cd Avi Kivity
    remain = clip.size;
522 093bc2cd Avi Kivity
523 093bc2cd Avi Kivity
    /* Render the region itself into any gaps left by the current view. */
524 08dafab4 Avi Kivity
    for (i = 0; i < view->nr && int128_nz(remain); ++i) {
525 08dafab4 Avi Kivity
        if (int128_ge(base, addrrange_end(view->ranges[i].addr))) {
526 093bc2cd Avi Kivity
            continue;
527 093bc2cd Avi Kivity
        }
528 08dafab4 Avi Kivity
        if (int128_lt(base, view->ranges[i].addr.start)) {
529 08dafab4 Avi Kivity
            now = int128_min(remain,
530 08dafab4 Avi Kivity
                             int128_sub(view->ranges[i].addr.start, base));
531 093bc2cd Avi Kivity
            fr.mr = mr;
532 093bc2cd Avi Kivity
            fr.offset_in_region = offset_in_region;
533 093bc2cd Avi Kivity
            fr.addr = addrrange_make(base, now);
534 5a583347 Avi Kivity
            fr.dirty_log_mask = mr->dirty_log_mask;
535 d0a9b5bc Avi Kivity
            fr.readable = mr->readable;
536 fb1cd6f9 Avi Kivity
            fr.readonly = readonly;
537 093bc2cd Avi Kivity
            flatview_insert(view, i, &fr);
538 093bc2cd Avi Kivity
            ++i;
539 08dafab4 Avi Kivity
            int128_addto(&base, now);
540 08dafab4 Avi Kivity
            offset_in_region += int128_get64(now);
541 08dafab4 Avi Kivity
            int128_subfrom(&remain, now);
542 093bc2cd Avi Kivity
        }
543 d26a8cae Avi Kivity
        now = int128_sub(int128_min(int128_add(base, remain),
544 d26a8cae Avi Kivity
                                    addrrange_end(view->ranges[i].addr)),
545 d26a8cae Avi Kivity
                         base);
546 d26a8cae Avi Kivity
        int128_addto(&base, now);
547 d26a8cae Avi Kivity
        offset_in_region += int128_get64(now);
548 d26a8cae Avi Kivity
        int128_subfrom(&remain, now);
549 093bc2cd Avi Kivity
    }
550 08dafab4 Avi Kivity
    if (int128_nz(remain)) {
551 093bc2cd Avi Kivity
        fr.mr = mr;
552 093bc2cd Avi Kivity
        fr.offset_in_region = offset_in_region;
553 093bc2cd Avi Kivity
        fr.addr = addrrange_make(base, remain);
554 5a583347 Avi Kivity
        fr.dirty_log_mask = mr->dirty_log_mask;
555 d0a9b5bc Avi Kivity
        fr.readable = mr->readable;
556 fb1cd6f9 Avi Kivity
        fr.readonly = readonly;
557 093bc2cd Avi Kivity
        flatview_insert(view, i, &fr);
558 093bc2cd Avi Kivity
    }
559 093bc2cd Avi Kivity
}
560 093bc2cd Avi Kivity
561 093bc2cd Avi Kivity
/* Render a memory topology into a list of disjoint absolute ranges. */
562 093bc2cd Avi Kivity
static FlatView generate_memory_topology(MemoryRegion *mr)
563 093bc2cd Avi Kivity
{
564 093bc2cd Avi Kivity
    FlatView view;
565 093bc2cd Avi Kivity
566 093bc2cd Avi Kivity
    flatview_init(&view);
567 093bc2cd Avi Kivity
568 83f3c251 Avi Kivity
    if (mr) {
569 83f3c251 Avi Kivity
        render_memory_region(&view, mr, int128_zero(),
570 83f3c251 Avi Kivity
                             addrrange_make(int128_zero(), int128_2_64()), false);
571 83f3c251 Avi Kivity
    }
572 3d8e6bf9 Avi Kivity
    flatview_simplify(&view);
573 093bc2cd Avi Kivity
574 093bc2cd Avi Kivity
    return view;
575 093bc2cd Avi Kivity
}
576 093bc2cd Avi Kivity
577 3e9d69e7 Avi Kivity
static void address_space_add_del_ioeventfds(AddressSpace *as,
578 3e9d69e7 Avi Kivity
                                             MemoryRegionIoeventfd *fds_new,
579 3e9d69e7 Avi Kivity
                                             unsigned fds_new_nb,
580 3e9d69e7 Avi Kivity
                                             MemoryRegionIoeventfd *fds_old,
581 3e9d69e7 Avi Kivity
                                             unsigned fds_old_nb)
582 3e9d69e7 Avi Kivity
{
583 3e9d69e7 Avi Kivity
    unsigned iold, inew;
584 80a1ea37 Avi Kivity
    MemoryRegionIoeventfd *fd;
585 80a1ea37 Avi Kivity
    MemoryRegionSection section;
586 3e9d69e7 Avi Kivity
587 3e9d69e7 Avi Kivity
    /* Generate a symmetric difference of the old and new fd sets, adding
588 3e9d69e7 Avi Kivity
     * and deleting as necessary.
589 3e9d69e7 Avi Kivity
     */
590 3e9d69e7 Avi Kivity
591 3e9d69e7 Avi Kivity
    iold = inew = 0;
592 3e9d69e7 Avi Kivity
    while (iold < fds_old_nb || inew < fds_new_nb) {
593 3e9d69e7 Avi Kivity
        if (iold < fds_old_nb
594 3e9d69e7 Avi Kivity
            && (inew == fds_new_nb
595 3e9d69e7 Avi Kivity
                || memory_region_ioeventfd_before(fds_old[iold],
596 3e9d69e7 Avi Kivity
                                                  fds_new[inew]))) {
597 80a1ea37 Avi Kivity
            fd = &fds_old[iold];
598 80a1ea37 Avi Kivity
            section = (MemoryRegionSection) {
599 f6790af6 Avi Kivity
                .address_space = as,
600 80a1ea37 Avi Kivity
                .offset_within_address_space = int128_get64(fd->addr.start),
601 80a1ea37 Avi Kivity
                .size = int128_get64(fd->addr.size),
602 80a1ea37 Avi Kivity
            };
603 80a1ea37 Avi Kivity
            MEMORY_LISTENER_CALL(eventfd_del, Forward, &section,
604 753d5e14 Paolo Bonzini
                                 fd->match_data, fd->data, fd->e);
605 3e9d69e7 Avi Kivity
            ++iold;
606 3e9d69e7 Avi Kivity
        } else if (inew < fds_new_nb
607 3e9d69e7 Avi Kivity
                   && (iold == fds_old_nb
608 3e9d69e7 Avi Kivity
                       || memory_region_ioeventfd_before(fds_new[inew],
609 3e9d69e7 Avi Kivity
                                                         fds_old[iold]))) {
610 80a1ea37 Avi Kivity
            fd = &fds_new[inew];
611 80a1ea37 Avi Kivity
            section = (MemoryRegionSection) {
612 f6790af6 Avi Kivity
                .address_space = as,
613 80a1ea37 Avi Kivity
                .offset_within_address_space = int128_get64(fd->addr.start),
614 80a1ea37 Avi Kivity
                .size = int128_get64(fd->addr.size),
615 80a1ea37 Avi Kivity
            };
616 80a1ea37 Avi Kivity
            MEMORY_LISTENER_CALL(eventfd_add, Reverse, &section,
617 753d5e14 Paolo Bonzini
                                 fd->match_data, fd->data, fd->e);
618 3e9d69e7 Avi Kivity
            ++inew;
619 3e9d69e7 Avi Kivity
        } else {
620 3e9d69e7 Avi Kivity
            ++iold;
621 3e9d69e7 Avi Kivity
            ++inew;
622 3e9d69e7 Avi Kivity
        }
623 3e9d69e7 Avi Kivity
    }
624 3e9d69e7 Avi Kivity
}
625 3e9d69e7 Avi Kivity
626 3e9d69e7 Avi Kivity
static void address_space_update_ioeventfds(AddressSpace *as)
627 3e9d69e7 Avi Kivity
{
628 3e9d69e7 Avi Kivity
    FlatRange *fr;
629 3e9d69e7 Avi Kivity
    unsigned ioeventfd_nb = 0;
630 3e9d69e7 Avi Kivity
    MemoryRegionIoeventfd *ioeventfds = NULL;
631 3e9d69e7 Avi Kivity
    AddrRange tmp;
632 3e9d69e7 Avi Kivity
    unsigned i;
633 3e9d69e7 Avi Kivity
634 8786db7c Avi Kivity
    FOR_EACH_FLAT_RANGE(fr, as->current_map) {
635 3e9d69e7 Avi Kivity
        for (i = 0; i < fr->mr->ioeventfd_nb; ++i) {
636 3e9d69e7 Avi Kivity
            tmp = addrrange_shift(fr->mr->ioeventfds[i].addr,
637 08dafab4 Avi Kivity
                                  int128_sub(fr->addr.start,
638 08dafab4 Avi Kivity
                                             int128_make64(fr->offset_in_region)));
639 3e9d69e7 Avi Kivity
            if (addrrange_intersects(fr->addr, tmp)) {
640 3e9d69e7 Avi Kivity
                ++ioeventfd_nb;
641 7267c094 Anthony Liguori
                ioeventfds = g_realloc(ioeventfds,
642 3e9d69e7 Avi Kivity
                                          ioeventfd_nb * sizeof(*ioeventfds));
643 3e9d69e7 Avi Kivity
                ioeventfds[ioeventfd_nb-1] = fr->mr->ioeventfds[i];
644 3e9d69e7 Avi Kivity
                ioeventfds[ioeventfd_nb-1].addr = tmp;
645 3e9d69e7 Avi Kivity
            }
646 3e9d69e7 Avi Kivity
        }
647 3e9d69e7 Avi Kivity
    }
648 3e9d69e7 Avi Kivity
649 3e9d69e7 Avi Kivity
    address_space_add_del_ioeventfds(as, ioeventfds, ioeventfd_nb,
650 3e9d69e7 Avi Kivity
                                     as->ioeventfds, as->ioeventfd_nb);
651 3e9d69e7 Avi Kivity
652 7267c094 Anthony Liguori
    g_free(as->ioeventfds);
653 3e9d69e7 Avi Kivity
    as->ioeventfds = ioeventfds;
654 3e9d69e7 Avi Kivity
    as->ioeventfd_nb = ioeventfd_nb;
655 3e9d69e7 Avi Kivity
}
656 3e9d69e7 Avi Kivity
657 b8af1afb Avi Kivity
static void address_space_update_topology_pass(AddressSpace *as,
658 b8af1afb Avi Kivity
                                               FlatView old_view,
659 b8af1afb Avi Kivity
                                               FlatView new_view,
660 b8af1afb Avi Kivity
                                               bool adding)
661 093bc2cd Avi Kivity
{
662 093bc2cd Avi Kivity
    unsigned iold, inew;
663 093bc2cd Avi Kivity
    FlatRange *frold, *frnew;
664 093bc2cd Avi Kivity
665 093bc2cd Avi Kivity
    /* Generate a symmetric difference of the old and new memory maps.
666 093bc2cd Avi Kivity
     * Kill ranges in the old map, and instantiate ranges in the new map.
667 093bc2cd Avi Kivity
     */
668 093bc2cd Avi Kivity
    iold = inew = 0;
669 093bc2cd Avi Kivity
    while (iold < old_view.nr || inew < new_view.nr) {
670 093bc2cd Avi Kivity
        if (iold < old_view.nr) {
671 093bc2cd Avi Kivity
            frold = &old_view.ranges[iold];
672 093bc2cd Avi Kivity
        } else {
673 093bc2cd Avi Kivity
            frold = NULL;
674 093bc2cd Avi Kivity
        }
675 093bc2cd Avi Kivity
        if (inew < new_view.nr) {
676 093bc2cd Avi Kivity
            frnew = &new_view.ranges[inew];
677 093bc2cd Avi Kivity
        } else {
678 093bc2cd Avi Kivity
            frnew = NULL;
679 093bc2cd Avi Kivity
        }
680 093bc2cd Avi Kivity
681 093bc2cd Avi Kivity
        if (frold
682 093bc2cd Avi Kivity
            && (!frnew
683 08dafab4 Avi Kivity
                || int128_lt(frold->addr.start, frnew->addr.start)
684 08dafab4 Avi Kivity
                || (int128_eq(frold->addr.start, frnew->addr.start)
685 093bc2cd Avi Kivity
                    && !flatrange_equal(frold, frnew)))) {
686 093bc2cd Avi Kivity
            /* In old, but (not in new, or in new but attributes changed). */
687 093bc2cd Avi Kivity
688 b8af1afb Avi Kivity
            if (!adding) {
689 72e22d2f Avi Kivity
                MEMORY_LISTENER_UPDATE_REGION(frold, as, Reverse, region_del);
690 b8af1afb Avi Kivity
            }
691 b8af1afb Avi Kivity
692 093bc2cd Avi Kivity
            ++iold;
693 093bc2cd Avi Kivity
        } else if (frold && frnew && flatrange_equal(frold, frnew)) {
694 093bc2cd Avi Kivity
            /* In both (logging may have changed) */
695 093bc2cd Avi Kivity
696 b8af1afb Avi Kivity
            if (adding) {
697 50c1e149 Avi Kivity
                MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, region_nop);
698 b8af1afb Avi Kivity
                if (frold->dirty_log_mask && !frnew->dirty_log_mask) {
699 72e22d2f Avi Kivity
                    MEMORY_LISTENER_UPDATE_REGION(frnew, as, Reverse, log_stop);
700 b8af1afb Avi Kivity
                } else if (frnew->dirty_log_mask && !frold->dirty_log_mask) {
701 72e22d2f Avi Kivity
                    MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, log_start);
702 b8af1afb Avi Kivity
                }
703 5a583347 Avi Kivity
            }
704 5a583347 Avi Kivity
705 093bc2cd Avi Kivity
            ++iold;
706 093bc2cd Avi Kivity
            ++inew;
707 093bc2cd Avi Kivity
        } else {
708 093bc2cd Avi Kivity
            /* In new */
709 093bc2cd Avi Kivity
710 b8af1afb Avi Kivity
            if (adding) {
711 72e22d2f Avi Kivity
                MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, region_add);
712 b8af1afb Avi Kivity
            }
713 b8af1afb Avi Kivity
714 093bc2cd Avi Kivity
            ++inew;
715 093bc2cd Avi Kivity
        }
716 093bc2cd Avi Kivity
    }
717 b8af1afb Avi Kivity
}
718 b8af1afb Avi Kivity
719 b8af1afb Avi Kivity
720 b8af1afb Avi Kivity
static void address_space_update_topology(AddressSpace *as)
721 b8af1afb Avi Kivity
{
722 8786db7c Avi Kivity
    FlatView old_view = *as->current_map;
723 b8af1afb Avi Kivity
    FlatView new_view = generate_memory_topology(as->root);
724 b8af1afb Avi Kivity
725 b8af1afb Avi Kivity
    address_space_update_topology_pass(as, old_view, new_view, false);
726 b8af1afb Avi Kivity
    address_space_update_topology_pass(as, old_view, new_view, true);
727 b8af1afb Avi Kivity
728 8786db7c Avi Kivity
    *as->current_map = new_view;
729 093bc2cd Avi Kivity
    flatview_destroy(&old_view);
730 3e9d69e7 Avi Kivity
    address_space_update_ioeventfds(as);
731 093bc2cd Avi Kivity
}
732 093bc2cd Avi Kivity
733 4ef4db86 Avi Kivity
void memory_region_transaction_begin(void)
734 4ef4db86 Avi Kivity
{
735 bb880ded Jan Kiszka
    qemu_flush_coalesced_mmio_buffer();
736 4ef4db86 Avi Kivity
    ++memory_region_transaction_depth;
737 4ef4db86 Avi Kivity
}
738 4ef4db86 Avi Kivity
739 4ef4db86 Avi Kivity
void memory_region_transaction_commit(void)
740 4ef4db86 Avi Kivity
{
741 0d673e36 Avi Kivity
    AddressSpace *as;
742 0d673e36 Avi Kivity
743 4ef4db86 Avi Kivity
    assert(memory_region_transaction_depth);
744 4ef4db86 Avi Kivity
    --memory_region_transaction_depth;
745 22bde714 Jan Kiszka
    if (!memory_region_transaction_depth && memory_region_update_pending) {
746 22bde714 Jan Kiszka
        memory_region_update_pending = false;
747 02e2b95f Jan Kiszka
        MEMORY_LISTENER_CALL_GLOBAL(begin, Forward);
748 02e2b95f Jan Kiszka
749 0d673e36 Avi Kivity
        QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
750 0d673e36 Avi Kivity
            address_space_update_topology(as);
751 02e2b95f Jan Kiszka
        }
752 02e2b95f Jan Kiszka
753 02e2b95f Jan Kiszka
        MEMORY_LISTENER_CALL_GLOBAL(commit, Forward);
754 e87c099f Avi Kivity
    }
755 4ef4db86 Avi Kivity
}
756 4ef4db86 Avi Kivity
757 545e92e0 Avi Kivity
static void memory_region_destructor_none(MemoryRegion *mr)
758 545e92e0 Avi Kivity
{
759 545e92e0 Avi Kivity
}
760 545e92e0 Avi Kivity
761 545e92e0 Avi Kivity
static void memory_region_destructor_ram(MemoryRegion *mr)
762 545e92e0 Avi Kivity
{
763 545e92e0 Avi Kivity
    qemu_ram_free(mr->ram_addr);
764 545e92e0 Avi Kivity
}
765 545e92e0 Avi Kivity
766 545e92e0 Avi Kivity
static void memory_region_destructor_ram_from_ptr(MemoryRegion *mr)
767 545e92e0 Avi Kivity
{
768 545e92e0 Avi Kivity
    qemu_ram_free_from_ptr(mr->ram_addr);
769 545e92e0 Avi Kivity
}
770 545e92e0 Avi Kivity
771 545e92e0 Avi Kivity
static void memory_region_destructor_iomem(MemoryRegion *mr)
772 545e92e0 Avi Kivity
{
773 545e92e0 Avi Kivity
}
774 545e92e0 Avi Kivity
775 d0a9b5bc Avi Kivity
static void memory_region_destructor_rom_device(MemoryRegion *mr)
776 d0a9b5bc Avi Kivity
{
777 d0a9b5bc Avi Kivity
    qemu_ram_free(mr->ram_addr & TARGET_PAGE_MASK);
778 d0a9b5bc Avi Kivity
}
779 d0a9b5bc Avi Kivity
780 be675c97 Avi Kivity
static bool memory_region_wrong_endianness(MemoryRegion *mr)
781 be675c97 Avi Kivity
{
782 2c3579ab Andreas Fรคrber
#ifdef TARGET_WORDS_BIGENDIAN
783 be675c97 Avi Kivity
    return mr->ops->endianness == DEVICE_LITTLE_ENDIAN;
784 be675c97 Avi Kivity
#else
785 be675c97 Avi Kivity
    return mr->ops->endianness == DEVICE_BIG_ENDIAN;
786 be675c97 Avi Kivity
#endif
787 be675c97 Avi Kivity
}
788 be675c97 Avi Kivity
789 093bc2cd Avi Kivity
void memory_region_init(MemoryRegion *mr,
790 093bc2cd Avi Kivity
                        const char *name,
791 093bc2cd Avi Kivity
                        uint64_t size)
792 093bc2cd Avi Kivity
{
793 093bc2cd Avi Kivity
    mr->ops = NULL;
794 093bc2cd Avi Kivity
    mr->parent = NULL;
795 08dafab4 Avi Kivity
    mr->size = int128_make64(size);
796 08dafab4 Avi Kivity
    if (size == UINT64_MAX) {
797 08dafab4 Avi Kivity
        mr->size = int128_2_64();
798 08dafab4 Avi Kivity
    }
799 093bc2cd Avi Kivity
    mr->addr = 0;
800 b3b00c78 Avi Kivity
    mr->subpage = false;
801 6bba19ba Avi Kivity
    mr->enabled = true;
802 14a3c10a Avi Kivity
    mr->terminates = false;
803 8ea9252a Avi Kivity
    mr->ram = false;
804 d0a9b5bc Avi Kivity
    mr->readable = true;
805 fb1cd6f9 Avi Kivity
    mr->readonly = false;
806 75c578dc Avi Kivity
    mr->rom_device = false;
807 545e92e0 Avi Kivity
    mr->destructor = memory_region_destructor_none;
808 093bc2cd Avi Kivity
    mr->priority = 0;
809 093bc2cd Avi Kivity
    mr->may_overlap = false;
810 093bc2cd Avi Kivity
    mr->alias = NULL;
811 093bc2cd Avi Kivity
    QTAILQ_INIT(&mr->subregions);
812 093bc2cd Avi Kivity
    memset(&mr->subregions_link, 0, sizeof mr->subregions_link);
813 093bc2cd Avi Kivity
    QTAILQ_INIT(&mr->coalesced);
814 7267c094 Anthony Liguori
    mr->name = g_strdup(name);
815 5a583347 Avi Kivity
    mr->dirty_log_mask = 0;
816 3e9d69e7 Avi Kivity
    mr->ioeventfd_nb = 0;
817 3e9d69e7 Avi Kivity
    mr->ioeventfds = NULL;
818 d410515e Jan Kiszka
    mr->flush_coalesced_mmio = false;
819 093bc2cd Avi Kivity
}
820 093bc2cd Avi Kivity
821 093bc2cd Avi Kivity
static bool memory_region_access_valid(MemoryRegion *mr,
822 a8170e5e Avi Kivity
                                       hwaddr addr,
823 897fa7cf Avi Kivity
                                       unsigned size,
824 897fa7cf Avi Kivity
                                       bool is_write)
825 093bc2cd Avi Kivity
{
826 897fa7cf Avi Kivity
    if (mr->ops->valid.accepts
827 897fa7cf Avi Kivity
        && !mr->ops->valid.accepts(mr->opaque, addr, size, is_write)) {
828 897fa7cf Avi Kivity
        return false;
829 897fa7cf Avi Kivity
    }
830 897fa7cf Avi Kivity
831 093bc2cd Avi Kivity
    if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
832 093bc2cd Avi Kivity
        return false;
833 093bc2cd Avi Kivity
    }
834 093bc2cd Avi Kivity
835 093bc2cd Avi Kivity
    /* Treat zero as compatibility all valid */
836 093bc2cd Avi Kivity
    if (!mr->ops->valid.max_access_size) {
837 093bc2cd Avi Kivity
        return true;
838 093bc2cd Avi Kivity
    }
839 093bc2cd Avi Kivity
840 093bc2cd Avi Kivity
    if (size > mr->ops->valid.max_access_size
841 093bc2cd Avi Kivity
        || size < mr->ops->valid.min_access_size) {
842 093bc2cd Avi Kivity
        return false;
843 093bc2cd Avi Kivity
    }
844 093bc2cd Avi Kivity
    return true;
845 093bc2cd Avi Kivity
}
846 093bc2cd Avi Kivity
847 a621f38d Avi Kivity
static uint64_t memory_region_dispatch_read1(MemoryRegion *mr,
848 a8170e5e Avi Kivity
                                             hwaddr addr,
849 a621f38d Avi Kivity
                                             unsigned size)
850 093bc2cd Avi Kivity
{
851 164a4dcd Avi Kivity
    uint64_t data = 0;
852 093bc2cd Avi Kivity
853 897fa7cf Avi Kivity
    if (!memory_region_access_valid(mr, addr, size, false)) {
854 093bc2cd Avi Kivity
        return -1U; /* FIXME: better signalling */
855 093bc2cd Avi Kivity
    }
856 093bc2cd Avi Kivity
857 74901c3b Avi Kivity
    if (!mr->ops->read) {
858 5bbf90be Richard Henderson
        return mr->ops->old_mmio.read[ctz32(size)](mr->opaque, addr);
859 74901c3b Avi Kivity
    }
860 74901c3b Avi Kivity
861 093bc2cd Avi Kivity
    /* FIXME: support unaligned access */
862 2b50aa1f Avi Kivity
    access_with_adjusted_size(addr, &data, size,
863 164a4dcd Avi Kivity
                              mr->ops->impl.min_access_size,
864 164a4dcd Avi Kivity
                              mr->ops->impl.max_access_size,
865 164a4dcd Avi Kivity
                              memory_region_read_accessor, mr);
866 093bc2cd Avi Kivity
867 093bc2cd Avi Kivity
    return data;
868 093bc2cd Avi Kivity
}
869 093bc2cd Avi Kivity
870 a621f38d Avi Kivity
static void adjust_endianness(MemoryRegion *mr, uint64_t *data, unsigned size)
871 093bc2cd Avi Kivity
{
872 a621f38d Avi Kivity
    if (memory_region_wrong_endianness(mr)) {
873 a621f38d Avi Kivity
        switch (size) {
874 a621f38d Avi Kivity
        case 1:
875 a621f38d Avi Kivity
            break;
876 a621f38d Avi Kivity
        case 2:
877 a621f38d Avi Kivity
            *data = bswap16(*data);
878 a621f38d Avi Kivity
            break;
879 a621f38d Avi Kivity
        case 4:
880 a621f38d Avi Kivity
            *data = bswap32(*data);
881 1470a0cd Andreas Fรคrber
            break;
882 a621f38d Avi Kivity
        default:
883 a621f38d Avi Kivity
            abort();
884 a621f38d Avi Kivity
        }
885 a621f38d Avi Kivity
    }
886 a621f38d Avi Kivity
}
887 a621f38d Avi Kivity
888 a621f38d Avi Kivity
static uint64_t memory_region_dispatch_read(MemoryRegion *mr,
889 a8170e5e Avi Kivity
                                            hwaddr addr,
890 a621f38d Avi Kivity
                                            unsigned size)
891 a621f38d Avi Kivity
{
892 a621f38d Avi Kivity
    uint64_t ret;
893 a621f38d Avi Kivity
894 a621f38d Avi Kivity
    ret = memory_region_dispatch_read1(mr, addr, size);
895 a621f38d Avi Kivity
    adjust_endianness(mr, &ret, size);
896 a621f38d Avi Kivity
    return ret;
897 a621f38d Avi Kivity
}
898 093bc2cd Avi Kivity
899 a621f38d Avi Kivity
static void memory_region_dispatch_write(MemoryRegion *mr,
900 a8170e5e Avi Kivity
                                         hwaddr addr,
901 a621f38d Avi Kivity
                                         uint64_t data,
902 a621f38d Avi Kivity
                                         unsigned size)
903 a621f38d Avi Kivity
{
904 897fa7cf Avi Kivity
    if (!memory_region_access_valid(mr, addr, size, true)) {
905 093bc2cd Avi Kivity
        return; /* FIXME: better signalling */
906 093bc2cd Avi Kivity
    }
907 093bc2cd Avi Kivity
908 a621f38d Avi Kivity
    adjust_endianness(mr, &data, size);
909 a621f38d Avi Kivity
910 74901c3b Avi Kivity
    if (!mr->ops->write) {
911 5bbf90be Richard Henderson
        mr->ops->old_mmio.write[ctz32(size)](mr->opaque, addr, data);
912 74901c3b Avi Kivity
        return;
913 74901c3b Avi Kivity
    }
914 74901c3b Avi Kivity
915 093bc2cd Avi Kivity
    /* FIXME: support unaligned access */
916 2b50aa1f Avi Kivity
    access_with_adjusted_size(addr, &data, size,
917 164a4dcd Avi Kivity
                              mr->ops->impl.min_access_size,
918 164a4dcd Avi Kivity
                              mr->ops->impl.max_access_size,
919 164a4dcd Avi Kivity
                              memory_region_write_accessor, mr);
920 093bc2cd Avi Kivity
}
921 093bc2cd Avi Kivity
922 093bc2cd Avi Kivity
void memory_region_init_io(MemoryRegion *mr,
923 093bc2cd Avi Kivity
                           const MemoryRegionOps *ops,
924 093bc2cd Avi Kivity
                           void *opaque,
925 093bc2cd Avi Kivity
                           const char *name,
926 093bc2cd Avi Kivity
                           uint64_t size)
927 093bc2cd Avi Kivity
{
928 093bc2cd Avi Kivity
    memory_region_init(mr, name, size);
929 093bc2cd Avi Kivity
    mr->ops = ops;
930 093bc2cd Avi Kivity
    mr->opaque = opaque;
931 14a3c10a Avi Kivity
    mr->terminates = true;
932 26a83ad0 Avi Kivity
    mr->destructor = memory_region_destructor_iomem;
933 97161e17 Avi Kivity
    mr->ram_addr = ~(ram_addr_t)0;
934 093bc2cd Avi Kivity
}
935 093bc2cd Avi Kivity
936 093bc2cd Avi Kivity
void memory_region_init_ram(MemoryRegion *mr,
937 093bc2cd Avi Kivity
                            const char *name,
938 093bc2cd Avi Kivity
                            uint64_t size)
939 093bc2cd Avi Kivity
{
940 093bc2cd Avi Kivity
    memory_region_init(mr, name, size);
941 8ea9252a Avi Kivity
    mr->ram = true;
942 14a3c10a Avi Kivity
    mr->terminates = true;
943 545e92e0 Avi Kivity
    mr->destructor = memory_region_destructor_ram;
944 c5705a77 Avi Kivity
    mr->ram_addr = qemu_ram_alloc(size, mr);
945 093bc2cd Avi Kivity
}
946 093bc2cd Avi Kivity
947 093bc2cd Avi Kivity
void memory_region_init_ram_ptr(MemoryRegion *mr,
948 093bc2cd Avi Kivity
                                const char *name,
949 093bc2cd Avi Kivity
                                uint64_t size,
950 093bc2cd Avi Kivity
                                void *ptr)
951 093bc2cd Avi Kivity
{
952 093bc2cd Avi Kivity
    memory_region_init(mr, name, size);
953 8ea9252a Avi Kivity
    mr->ram = true;
954 14a3c10a Avi Kivity
    mr->terminates = true;
955 545e92e0 Avi Kivity
    mr->destructor = memory_region_destructor_ram_from_ptr;
956 c5705a77 Avi Kivity
    mr->ram_addr = qemu_ram_alloc_from_ptr(size, ptr, mr);
957 093bc2cd Avi Kivity
}
958 093bc2cd Avi Kivity
959 093bc2cd Avi Kivity
void memory_region_init_alias(MemoryRegion *mr,
960 093bc2cd Avi Kivity
                              const char *name,
961 093bc2cd Avi Kivity
                              MemoryRegion *orig,
962 a8170e5e Avi Kivity
                              hwaddr offset,
963 093bc2cd Avi Kivity
                              uint64_t size)
964 093bc2cd Avi Kivity
{
965 093bc2cd Avi Kivity
    memory_region_init(mr, name, size);
966 093bc2cd Avi Kivity
    mr->alias = orig;
967 093bc2cd Avi Kivity
    mr->alias_offset = offset;
968 093bc2cd Avi Kivity
}
969 093bc2cd Avi Kivity
970 d0a9b5bc Avi Kivity
void memory_region_init_rom_device(MemoryRegion *mr,
971 d0a9b5bc Avi Kivity
                                   const MemoryRegionOps *ops,
972 75f5941c Avi Kivity
                                   void *opaque,
973 d0a9b5bc Avi Kivity
                                   const char *name,
974 d0a9b5bc Avi Kivity
                                   uint64_t size)
975 d0a9b5bc Avi Kivity
{
976 d0a9b5bc Avi Kivity
    memory_region_init(mr, name, size);
977 7bc2b9cd Avi Kivity
    mr->ops = ops;
978 75f5941c Avi Kivity
    mr->opaque = opaque;
979 d0a9b5bc Avi Kivity
    mr->terminates = true;
980 75c578dc Avi Kivity
    mr->rom_device = true;
981 d0a9b5bc Avi Kivity
    mr->destructor = memory_region_destructor_rom_device;
982 c5705a77 Avi Kivity
    mr->ram_addr = qemu_ram_alloc(size, mr);
983 d0a9b5bc Avi Kivity
}
984 d0a9b5bc Avi Kivity
985 a8170e5e Avi Kivity
static uint64_t invalid_read(void *opaque, hwaddr addr,
986 1660e72d Jan Kiszka
                             unsigned size)
987 1660e72d Jan Kiszka
{
988 1660e72d Jan Kiszka
    MemoryRegion *mr = opaque;
989 1660e72d Jan Kiszka
990 1660e72d Jan Kiszka
    if (!mr->warning_printed) {
991 1660e72d Jan Kiszka
        fprintf(stderr, "Invalid read from memory region %s\n", mr->name);
992 1660e72d Jan Kiszka
        mr->warning_printed = true;
993 1660e72d Jan Kiszka
    }
994 1660e72d Jan Kiszka
    return -1U;
995 1660e72d Jan Kiszka
}
996 1660e72d Jan Kiszka
997 a8170e5e Avi Kivity
static void invalid_write(void *opaque, hwaddr addr, uint64_t data,
998 1660e72d Jan Kiszka
                          unsigned size)
999 1660e72d Jan Kiszka
{
1000 1660e72d Jan Kiszka
    MemoryRegion *mr = opaque;
1001 1660e72d Jan Kiszka
1002 1660e72d Jan Kiszka
    if (!mr->warning_printed) {
1003 1660e72d Jan Kiszka
        fprintf(stderr, "Invalid write to memory region %s\n", mr->name);
1004 1660e72d Jan Kiszka
        mr->warning_printed = true;
1005 1660e72d Jan Kiszka
    }
1006 1660e72d Jan Kiszka
}
1007 1660e72d Jan Kiszka
1008 1660e72d Jan Kiszka
static const MemoryRegionOps reservation_ops = {
1009 1660e72d Jan Kiszka
    .read = invalid_read,
1010 1660e72d Jan Kiszka
    .write = invalid_write,
1011 1660e72d Jan Kiszka
    .endianness = DEVICE_NATIVE_ENDIAN,
1012 1660e72d Jan Kiszka
};
1013 1660e72d Jan Kiszka
1014 1660e72d Jan Kiszka
void memory_region_init_reservation(MemoryRegion *mr,
1015 1660e72d Jan Kiszka
                                    const char *name,
1016 1660e72d Jan Kiszka
                                    uint64_t size)
1017 1660e72d Jan Kiszka
{
1018 1660e72d Jan Kiszka
    memory_region_init_io(mr, &reservation_ops, mr, name, size);
1019 1660e72d Jan Kiszka
}
1020 1660e72d Jan Kiszka
1021 093bc2cd Avi Kivity
void memory_region_destroy(MemoryRegion *mr)
1022 093bc2cd Avi Kivity
{
1023 093bc2cd Avi Kivity
    assert(QTAILQ_EMPTY(&mr->subregions));
1024 2be0e25f Avi Kivity
    assert(memory_region_transaction_depth == 0);
1025 545e92e0 Avi Kivity
    mr->destructor(mr);
1026 093bc2cd Avi Kivity
    memory_region_clear_coalescing(mr);
1027 7267c094 Anthony Liguori
    g_free((char *)mr->name);
1028 7267c094 Anthony Liguori
    g_free(mr->ioeventfds);
1029 093bc2cd Avi Kivity
}
1030 093bc2cd Avi Kivity
1031 093bc2cd Avi Kivity
uint64_t memory_region_size(MemoryRegion *mr)
1032 093bc2cd Avi Kivity
{
1033 08dafab4 Avi Kivity
    if (int128_eq(mr->size, int128_2_64())) {
1034 08dafab4 Avi Kivity
        return UINT64_MAX;
1035 08dafab4 Avi Kivity
    }
1036 08dafab4 Avi Kivity
    return int128_get64(mr->size);
1037 093bc2cd Avi Kivity
}
1038 093bc2cd Avi Kivity
1039 8991c79b Avi Kivity
const char *memory_region_name(MemoryRegion *mr)
1040 8991c79b Avi Kivity
{
1041 8991c79b Avi Kivity
    return mr->name;
1042 8991c79b Avi Kivity
}
1043 8991c79b Avi Kivity
1044 8ea9252a Avi Kivity
bool memory_region_is_ram(MemoryRegion *mr)
1045 8ea9252a Avi Kivity
{
1046 8ea9252a Avi Kivity
    return mr->ram;
1047 8ea9252a Avi Kivity
}
1048 8ea9252a Avi Kivity
1049 55043ba3 Avi Kivity
bool memory_region_is_logging(MemoryRegion *mr)
1050 55043ba3 Avi Kivity
{
1051 55043ba3 Avi Kivity
    return mr->dirty_log_mask;
1052 55043ba3 Avi Kivity
}
1053 55043ba3 Avi Kivity
1054 ce7923da Avi Kivity
bool memory_region_is_rom(MemoryRegion *mr)
1055 ce7923da Avi Kivity
{
1056 ce7923da Avi Kivity
    return mr->ram && mr->readonly;
1057 ce7923da Avi Kivity
}
1058 ce7923da Avi Kivity
1059 093bc2cd Avi Kivity
void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
1060 093bc2cd Avi Kivity
{
1061 5a583347 Avi Kivity
    uint8_t mask = 1 << client;
1062 5a583347 Avi Kivity
1063 59023ef4 Jan Kiszka
    memory_region_transaction_begin();
1064 5a583347 Avi Kivity
    mr->dirty_log_mask = (mr->dirty_log_mask & ~mask) | (log * mask);
1065 22bde714 Jan Kiszka
    memory_region_update_pending |= mr->enabled;
1066 59023ef4 Jan Kiszka
    memory_region_transaction_commit();
1067 093bc2cd Avi Kivity
}
1068 093bc2cd Avi Kivity
1069 a8170e5e Avi Kivity
bool memory_region_get_dirty(MemoryRegion *mr, hwaddr addr,
1070 a8170e5e Avi Kivity
                             hwaddr size, unsigned client)
1071 093bc2cd Avi Kivity
{
1072 14a3c10a Avi Kivity
    assert(mr->terminates);
1073 cd7a45c9 Blue Swirl
    return cpu_physical_memory_get_dirty(mr->ram_addr + addr, size,
1074 cd7a45c9 Blue Swirl
                                         1 << client);
1075 093bc2cd Avi Kivity
}
1076 093bc2cd Avi Kivity
1077 a8170e5e Avi Kivity
void memory_region_set_dirty(MemoryRegion *mr, hwaddr addr,
1078 a8170e5e Avi Kivity
                             hwaddr size)
1079 093bc2cd Avi Kivity
{
1080 14a3c10a Avi Kivity
    assert(mr->terminates);
1081 fd4aa979 Blue Swirl
    return cpu_physical_memory_set_dirty_range(mr->ram_addr + addr, size, -1);
1082 093bc2cd Avi Kivity
}
1083 093bc2cd Avi Kivity
1084 6c279db8 Juan Quintela
bool memory_region_test_and_clear_dirty(MemoryRegion *mr, hwaddr addr,
1085 6c279db8 Juan Quintela
                                        hwaddr size, unsigned client)
1086 6c279db8 Juan Quintela
{
1087 6c279db8 Juan Quintela
    bool ret;
1088 6c279db8 Juan Quintela
    assert(mr->terminates);
1089 6c279db8 Juan Quintela
    ret = cpu_physical_memory_get_dirty(mr->ram_addr + addr, size,
1090 6c279db8 Juan Quintela
                                        1 << client);
1091 6c279db8 Juan Quintela
    if (ret) {
1092 6c279db8 Juan Quintela
        cpu_physical_memory_reset_dirty(mr->ram_addr + addr,
1093 6c279db8 Juan Quintela
                                        mr->ram_addr + addr + size,
1094 6c279db8 Juan Quintela
                                        1 << client);
1095 6c279db8 Juan Quintela
    }
1096 6c279db8 Juan Quintela
    return ret;
1097 6c279db8 Juan Quintela
}
1098 6c279db8 Juan Quintela
1099 6c279db8 Juan Quintela
1100 093bc2cd Avi Kivity
void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
1101 093bc2cd Avi Kivity
{
1102 0d673e36 Avi Kivity
    AddressSpace *as;
1103 5a583347 Avi Kivity
    FlatRange *fr;
1104 5a583347 Avi Kivity
1105 0d673e36 Avi Kivity
    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
1106 0d673e36 Avi Kivity
        FOR_EACH_FLAT_RANGE(fr, as->current_map) {
1107 0d673e36 Avi Kivity
            if (fr->mr == mr) {
1108 0d673e36 Avi Kivity
                MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, log_sync);
1109 0d673e36 Avi Kivity
            }
1110 5a583347 Avi Kivity
        }
1111 5a583347 Avi Kivity
    }
1112 093bc2cd Avi Kivity
}
1113 093bc2cd Avi Kivity
1114 093bc2cd Avi Kivity
void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
1115 093bc2cd Avi Kivity
{
1116 fb1cd6f9 Avi Kivity
    if (mr->readonly != readonly) {
1117 59023ef4 Jan Kiszka
        memory_region_transaction_begin();
1118 fb1cd6f9 Avi Kivity
        mr->readonly = readonly;
1119 22bde714 Jan Kiszka
        memory_region_update_pending |= mr->enabled;
1120 59023ef4 Jan Kiszka
        memory_region_transaction_commit();
1121 fb1cd6f9 Avi Kivity
    }
1122 093bc2cd Avi Kivity
}
1123 093bc2cd Avi Kivity
1124 d0a9b5bc Avi Kivity
void memory_region_rom_device_set_readable(MemoryRegion *mr, bool readable)
1125 d0a9b5bc Avi Kivity
{
1126 d0a9b5bc Avi Kivity
    if (mr->readable != readable) {
1127 59023ef4 Jan Kiszka
        memory_region_transaction_begin();
1128 d0a9b5bc Avi Kivity
        mr->readable = readable;
1129 22bde714 Jan Kiszka
        memory_region_update_pending |= mr->enabled;
1130 59023ef4 Jan Kiszka
        memory_region_transaction_commit();
1131 d0a9b5bc Avi Kivity
    }
1132 d0a9b5bc Avi Kivity
}
1133 d0a9b5bc Avi Kivity
1134 a8170e5e Avi Kivity
void memory_region_reset_dirty(MemoryRegion *mr, hwaddr addr,
1135 a8170e5e Avi Kivity
                               hwaddr size, unsigned client)
1136 093bc2cd Avi Kivity
{
1137 14a3c10a Avi Kivity
    assert(mr->terminates);
1138 5a583347 Avi Kivity
    cpu_physical_memory_reset_dirty(mr->ram_addr + addr,
1139 5a583347 Avi Kivity
                                    mr->ram_addr + addr + size,
1140 5a583347 Avi Kivity
                                    1 << client);
1141 093bc2cd Avi Kivity
}
1142 093bc2cd Avi Kivity
1143 093bc2cd Avi Kivity
void *memory_region_get_ram_ptr(MemoryRegion *mr)
1144 093bc2cd Avi Kivity
{
1145 093bc2cd Avi Kivity
    if (mr->alias) {
1146 093bc2cd Avi Kivity
        return memory_region_get_ram_ptr(mr->alias) + mr->alias_offset;
1147 093bc2cd Avi Kivity
    }
1148 093bc2cd Avi Kivity
1149 14a3c10a Avi Kivity
    assert(mr->terminates);
1150 093bc2cd Avi Kivity
1151 021d26d1 Jan Kiszka
    return qemu_get_ram_ptr(mr->ram_addr & TARGET_PAGE_MASK);
1152 093bc2cd Avi Kivity
}
1153 093bc2cd Avi Kivity
1154 0d673e36 Avi Kivity
static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpace *as)
1155 093bc2cd Avi Kivity
{
1156 093bc2cd Avi Kivity
    FlatRange *fr;
1157 093bc2cd Avi Kivity
    CoalescedMemoryRange *cmr;
1158 093bc2cd Avi Kivity
    AddrRange tmp;
1159 95d2994a Avi Kivity
    MemoryRegionSection section;
1160 093bc2cd Avi Kivity
1161 0d673e36 Avi Kivity
    FOR_EACH_FLAT_RANGE(fr, as->current_map) {
1162 093bc2cd Avi Kivity
        if (fr->mr == mr) {
1163 95d2994a Avi Kivity
            section = (MemoryRegionSection) {
1164 f6790af6 Avi Kivity
                .address_space = as,
1165 95d2994a Avi Kivity
                .offset_within_address_space = int128_get64(fr->addr.start),
1166 95d2994a Avi Kivity
                .size = int128_get64(fr->addr.size),
1167 95d2994a Avi Kivity
            };
1168 95d2994a Avi Kivity
1169 95d2994a Avi Kivity
            MEMORY_LISTENER_CALL(coalesced_mmio_del, Reverse, &section,
1170 95d2994a Avi Kivity
                                 int128_get64(fr->addr.start),
1171 95d2994a Avi Kivity
                                 int128_get64(fr->addr.size));
1172 093bc2cd Avi Kivity
            QTAILQ_FOREACH(cmr, &mr->coalesced, link) {
1173 093bc2cd Avi Kivity
                tmp = addrrange_shift(cmr->addr,
1174 08dafab4 Avi Kivity
                                      int128_sub(fr->addr.start,
1175 08dafab4 Avi Kivity
                                                 int128_make64(fr->offset_in_region)));
1176 093bc2cd Avi Kivity
                if (!addrrange_intersects(tmp, fr->addr)) {
1177 093bc2cd Avi Kivity
                    continue;
1178 093bc2cd Avi Kivity
                }
1179 093bc2cd Avi Kivity
                tmp = addrrange_intersection(tmp, fr->addr);
1180 95d2994a Avi Kivity
                MEMORY_LISTENER_CALL(coalesced_mmio_add, Forward, &section,
1181 95d2994a Avi Kivity
                                     int128_get64(tmp.start),
1182 95d2994a Avi Kivity
                                     int128_get64(tmp.size));
1183 093bc2cd Avi Kivity
            }
1184 093bc2cd Avi Kivity
        }
1185 093bc2cd Avi Kivity
    }
1186 093bc2cd Avi Kivity
}
1187 093bc2cd Avi Kivity
1188 0d673e36 Avi Kivity
static void memory_region_update_coalesced_range(MemoryRegion *mr)
1189 0d673e36 Avi Kivity
{
1190 0d673e36 Avi Kivity
    AddressSpace *as;
1191 0d673e36 Avi Kivity
1192 0d673e36 Avi Kivity
    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
1193 0d673e36 Avi Kivity
        memory_region_update_coalesced_range_as(mr, as);
1194 0d673e36 Avi Kivity
    }
1195 0d673e36 Avi Kivity
}
1196 0d673e36 Avi Kivity
1197 093bc2cd Avi Kivity
void memory_region_set_coalescing(MemoryRegion *mr)
1198 093bc2cd Avi Kivity
{
1199 093bc2cd Avi Kivity
    memory_region_clear_coalescing(mr);
1200 08dafab4 Avi Kivity
    memory_region_add_coalescing(mr, 0, int128_get64(mr->size));
1201 093bc2cd Avi Kivity
}
1202 093bc2cd Avi Kivity
1203 093bc2cd Avi Kivity
void memory_region_add_coalescing(MemoryRegion *mr,
1204 a8170e5e Avi Kivity
                                  hwaddr offset,
1205 093bc2cd Avi Kivity
                                  uint64_t size)
1206 093bc2cd Avi Kivity
{
1207 7267c094 Anthony Liguori
    CoalescedMemoryRange *cmr = g_malloc(sizeof(*cmr));
1208 093bc2cd Avi Kivity
1209 08dafab4 Avi Kivity
    cmr->addr = addrrange_make(int128_make64(offset), int128_make64(size));
1210 093bc2cd Avi Kivity
    QTAILQ_INSERT_TAIL(&mr->coalesced, cmr, link);
1211 093bc2cd Avi Kivity
    memory_region_update_coalesced_range(mr);
1212 d410515e Jan Kiszka
    memory_region_set_flush_coalesced(mr);
1213 093bc2cd Avi Kivity
}
1214 093bc2cd Avi Kivity
1215 093bc2cd Avi Kivity
void memory_region_clear_coalescing(MemoryRegion *mr)
1216 093bc2cd Avi Kivity
{
1217 093bc2cd Avi Kivity
    CoalescedMemoryRange *cmr;
1218 093bc2cd Avi Kivity
1219 d410515e Jan Kiszka
    qemu_flush_coalesced_mmio_buffer();
1220 d410515e Jan Kiszka
    mr->flush_coalesced_mmio = false;
1221 d410515e Jan Kiszka
1222 093bc2cd Avi Kivity
    while (!QTAILQ_EMPTY(&mr->coalesced)) {
1223 093bc2cd Avi Kivity
        cmr = QTAILQ_FIRST(&mr->coalesced);
1224 093bc2cd Avi Kivity
        QTAILQ_REMOVE(&mr->coalesced, cmr, link);
1225 7267c094 Anthony Liguori
        g_free(cmr);
1226 093bc2cd Avi Kivity
    }
1227 093bc2cd Avi Kivity
    memory_region_update_coalesced_range(mr);
1228 093bc2cd Avi Kivity
}
1229 093bc2cd Avi Kivity
1230 d410515e Jan Kiszka
void memory_region_set_flush_coalesced(MemoryRegion *mr)
1231 d410515e Jan Kiszka
{
1232 d410515e Jan Kiszka
    mr->flush_coalesced_mmio = true;
1233 d410515e Jan Kiszka
}
1234 d410515e Jan Kiszka
1235 d410515e Jan Kiszka
void memory_region_clear_flush_coalesced(MemoryRegion *mr)
1236 d410515e Jan Kiszka
{
1237 d410515e Jan Kiszka
    qemu_flush_coalesced_mmio_buffer();
1238 d410515e Jan Kiszka
    if (QTAILQ_EMPTY(&mr->coalesced)) {
1239 d410515e Jan Kiszka
        mr->flush_coalesced_mmio = false;
1240 d410515e Jan Kiszka
    }
1241 d410515e Jan Kiszka
}
1242 d410515e Jan Kiszka
1243 3e9d69e7 Avi Kivity
void memory_region_add_eventfd(MemoryRegion *mr,
1244 a8170e5e Avi Kivity
                               hwaddr addr,
1245 3e9d69e7 Avi Kivity
                               unsigned size,
1246 3e9d69e7 Avi Kivity
                               bool match_data,
1247 3e9d69e7 Avi Kivity
                               uint64_t data,
1248 753d5e14 Paolo Bonzini
                               EventNotifier *e)
1249 3e9d69e7 Avi Kivity
{
1250 3e9d69e7 Avi Kivity
    MemoryRegionIoeventfd mrfd = {
1251 08dafab4 Avi Kivity
        .addr.start = int128_make64(addr),
1252 08dafab4 Avi Kivity
        .addr.size = int128_make64(size),
1253 3e9d69e7 Avi Kivity
        .match_data = match_data,
1254 3e9d69e7 Avi Kivity
        .data = data,
1255 753d5e14 Paolo Bonzini
        .e = e,
1256 3e9d69e7 Avi Kivity
    };
1257 3e9d69e7 Avi Kivity
    unsigned i;
1258 3e9d69e7 Avi Kivity
1259 28f362be Alexander Graf
    adjust_endianness(mr, &mrfd.data, size);
1260 59023ef4 Jan Kiszka
    memory_region_transaction_begin();
1261 3e9d69e7 Avi Kivity
    for (i = 0; i < mr->ioeventfd_nb; ++i) {
1262 3e9d69e7 Avi Kivity
        if (memory_region_ioeventfd_before(mrfd, mr->ioeventfds[i])) {
1263 3e9d69e7 Avi Kivity
            break;
1264 3e9d69e7 Avi Kivity
        }
1265 3e9d69e7 Avi Kivity
    }
1266 3e9d69e7 Avi Kivity
    ++mr->ioeventfd_nb;
1267 7267c094 Anthony Liguori
    mr->ioeventfds = g_realloc(mr->ioeventfds,
1268 3e9d69e7 Avi Kivity
                                  sizeof(*mr->ioeventfds) * mr->ioeventfd_nb);
1269 3e9d69e7 Avi Kivity
    memmove(&mr->ioeventfds[i+1], &mr->ioeventfds[i],
1270 3e9d69e7 Avi Kivity
            sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb-1 - i));
1271 3e9d69e7 Avi Kivity
    mr->ioeventfds[i] = mrfd;
1272 22bde714 Jan Kiszka
    memory_region_update_pending |= mr->enabled;
1273 59023ef4 Jan Kiszka
    memory_region_transaction_commit();
1274 3e9d69e7 Avi Kivity
}
1275 3e9d69e7 Avi Kivity
1276 3e9d69e7 Avi Kivity
void memory_region_del_eventfd(MemoryRegion *mr,
1277 a8170e5e Avi Kivity
                               hwaddr addr,
1278 3e9d69e7 Avi Kivity
                               unsigned size,
1279 3e9d69e7 Avi Kivity
                               bool match_data,
1280 3e9d69e7 Avi Kivity
                               uint64_t data,
1281 753d5e14 Paolo Bonzini
                               EventNotifier *e)
1282 3e9d69e7 Avi Kivity
{
1283 3e9d69e7 Avi Kivity
    MemoryRegionIoeventfd mrfd = {
1284 08dafab4 Avi Kivity
        .addr.start = int128_make64(addr),
1285 08dafab4 Avi Kivity
        .addr.size = int128_make64(size),
1286 3e9d69e7 Avi Kivity
        .match_data = match_data,
1287 3e9d69e7 Avi Kivity
        .data = data,
1288 753d5e14 Paolo Bonzini
        .e = e,
1289 3e9d69e7 Avi Kivity
    };
1290 3e9d69e7 Avi Kivity
    unsigned i;
1291 3e9d69e7 Avi Kivity
1292 28f362be Alexander Graf
    adjust_endianness(mr, &mrfd.data, size);
1293 59023ef4 Jan Kiszka
    memory_region_transaction_begin();
1294 3e9d69e7 Avi Kivity
    for (i = 0; i < mr->ioeventfd_nb; ++i) {
1295 3e9d69e7 Avi Kivity
        if (memory_region_ioeventfd_equal(mrfd, mr->ioeventfds[i])) {
1296 3e9d69e7 Avi Kivity
            break;
1297 3e9d69e7 Avi Kivity
        }
1298 3e9d69e7 Avi Kivity
    }
1299 3e9d69e7 Avi Kivity
    assert(i != mr->ioeventfd_nb);
1300 3e9d69e7 Avi Kivity
    memmove(&mr->ioeventfds[i], &mr->ioeventfds[i+1],
1301 3e9d69e7 Avi Kivity
            sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb - (i+1)));
1302 3e9d69e7 Avi Kivity
    --mr->ioeventfd_nb;
1303 7267c094 Anthony Liguori
    mr->ioeventfds = g_realloc(mr->ioeventfds,
1304 3e9d69e7 Avi Kivity
                                  sizeof(*mr->ioeventfds)*mr->ioeventfd_nb + 1);
1305 22bde714 Jan Kiszka
    memory_region_update_pending |= mr->enabled;
1306 59023ef4 Jan Kiszka
    memory_region_transaction_commit();
1307 3e9d69e7 Avi Kivity
}
1308 3e9d69e7 Avi Kivity
1309 093bc2cd Avi Kivity
static void memory_region_add_subregion_common(MemoryRegion *mr,
1310 a8170e5e Avi Kivity
                                               hwaddr offset,
1311 093bc2cd Avi Kivity
                                               MemoryRegion *subregion)
1312 093bc2cd Avi Kivity
{
1313 093bc2cd Avi Kivity
    MemoryRegion *other;
1314 093bc2cd Avi Kivity
1315 59023ef4 Jan Kiszka
    memory_region_transaction_begin();
1316 59023ef4 Jan Kiszka
1317 093bc2cd Avi Kivity
    assert(!subregion->parent);
1318 093bc2cd Avi Kivity
    subregion->parent = mr;
1319 093bc2cd Avi Kivity
    subregion->addr = offset;
1320 093bc2cd Avi Kivity
    QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
1321 093bc2cd Avi Kivity
        if (subregion->may_overlap || other->may_overlap) {
1322 093bc2cd Avi Kivity
            continue;
1323 093bc2cd Avi Kivity
        }
1324 2c7cfd65 Hu Tao
        if (int128_ge(int128_make64(offset),
1325 08dafab4 Avi Kivity
                      int128_add(int128_make64(other->addr), other->size))
1326 08dafab4 Avi Kivity
            || int128_le(int128_add(int128_make64(offset), subregion->size),
1327 08dafab4 Avi Kivity
                         int128_make64(other->addr))) {
1328 093bc2cd Avi Kivity
            continue;
1329 093bc2cd Avi Kivity
        }
1330 a5e1cbc8 Anthony Liguori
#if 0
1331 860329b2 Michael Walle
        printf("warning: subregion collision %llx/%llx (%s) "
1332 860329b2 Michael Walle
               "vs %llx/%llx (%s)\n",
1333 093bc2cd Avi Kivity
               (unsigned long long)offset,
1334 08dafab4 Avi Kivity
               (unsigned long long)int128_get64(subregion->size),
1335 860329b2 Michael Walle
               subregion->name,
1336 860329b2 Michael Walle
               (unsigned long long)other->addr,
1337 08dafab4 Avi Kivity
               (unsigned long long)int128_get64(other->size),
1338 860329b2 Michael Walle
               other->name);
1339 a5e1cbc8 Anthony Liguori
#endif
1340 093bc2cd Avi Kivity
    }
1341 093bc2cd Avi Kivity
    QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
1342 093bc2cd Avi Kivity
        if (subregion->priority >= other->priority) {
1343 093bc2cd Avi Kivity
            QTAILQ_INSERT_BEFORE(other, subregion, subregions_link);
1344 093bc2cd Avi Kivity
            goto done;
1345 093bc2cd Avi Kivity
        }
1346 093bc2cd Avi Kivity
    }
1347 093bc2cd Avi Kivity
    QTAILQ_INSERT_TAIL(&mr->subregions, subregion, subregions_link);
1348 093bc2cd Avi Kivity
done:
1349 22bde714 Jan Kiszka
    memory_region_update_pending |= mr->enabled && subregion->enabled;
1350 59023ef4 Jan Kiszka
    memory_region_transaction_commit();
1351 093bc2cd Avi Kivity
}
1352 093bc2cd Avi Kivity
1353 093bc2cd Avi Kivity
1354 093bc2cd Avi Kivity
void memory_region_add_subregion(MemoryRegion *mr,
1355 a8170e5e Avi Kivity
                                 hwaddr offset,
1356 093bc2cd Avi Kivity
                                 MemoryRegion *subregion)
1357 093bc2cd Avi Kivity
{
1358 093bc2cd Avi Kivity
    subregion->may_overlap = false;
1359 093bc2cd Avi Kivity
    subregion->priority = 0;
1360 093bc2cd Avi Kivity
    memory_region_add_subregion_common(mr, offset, subregion);
1361 093bc2cd Avi Kivity
}
1362 093bc2cd Avi Kivity
1363 093bc2cd Avi Kivity
void memory_region_add_subregion_overlap(MemoryRegion *mr,
1364 a8170e5e Avi Kivity
                                         hwaddr offset,
1365 093bc2cd Avi Kivity
                                         MemoryRegion *subregion,
1366 093bc2cd Avi Kivity
                                         unsigned priority)
1367 093bc2cd Avi Kivity
{
1368 093bc2cd Avi Kivity
    subregion->may_overlap = true;
1369 093bc2cd Avi Kivity
    subregion->priority = priority;
1370 093bc2cd Avi Kivity
    memory_region_add_subregion_common(mr, offset, subregion);
1371 093bc2cd Avi Kivity
}
1372 093bc2cd Avi Kivity
1373 093bc2cd Avi Kivity
void memory_region_del_subregion(MemoryRegion *mr,
1374 093bc2cd Avi Kivity
                                 MemoryRegion *subregion)
1375 093bc2cd Avi Kivity
{
1376 59023ef4 Jan Kiszka
    memory_region_transaction_begin();
1377 093bc2cd Avi Kivity
    assert(subregion->parent == mr);
1378 093bc2cd Avi Kivity
    subregion->parent = NULL;
1379 093bc2cd Avi Kivity
    QTAILQ_REMOVE(&mr->subregions, subregion, subregions_link);
1380 22bde714 Jan Kiszka
    memory_region_update_pending |= mr->enabled && subregion->enabled;
1381 59023ef4 Jan Kiszka
    memory_region_transaction_commit();
1382 6bba19ba Avi Kivity
}
1383 6bba19ba Avi Kivity
1384 6bba19ba Avi Kivity
void memory_region_set_enabled(MemoryRegion *mr, bool enabled)
1385 6bba19ba Avi Kivity
{
1386 6bba19ba Avi Kivity
    if (enabled == mr->enabled) {
1387 6bba19ba Avi Kivity
        return;
1388 6bba19ba Avi Kivity
    }
1389 59023ef4 Jan Kiszka
    memory_region_transaction_begin();
1390 6bba19ba Avi Kivity
    mr->enabled = enabled;
1391 22bde714 Jan Kiszka
    memory_region_update_pending = true;
1392 59023ef4 Jan Kiszka
    memory_region_transaction_commit();
1393 093bc2cd Avi Kivity
}
1394 1c0ffa58 Avi Kivity
1395 a8170e5e Avi Kivity
void memory_region_set_address(MemoryRegion *mr, hwaddr addr)
1396 2282e1af Avi Kivity
{
1397 2282e1af Avi Kivity
    MemoryRegion *parent = mr->parent;
1398 2282e1af Avi Kivity
    unsigned priority = mr->priority;
1399 2282e1af Avi Kivity
    bool may_overlap = mr->may_overlap;
1400 2282e1af Avi Kivity
1401 2282e1af Avi Kivity
    if (addr == mr->addr || !parent) {
1402 2282e1af Avi Kivity
        mr->addr = addr;
1403 2282e1af Avi Kivity
        return;
1404 2282e1af Avi Kivity
    }
1405 2282e1af Avi Kivity
1406 2282e1af Avi Kivity
    memory_region_transaction_begin();
1407 2282e1af Avi Kivity
    memory_region_del_subregion(parent, mr);
1408 2282e1af Avi Kivity
    if (may_overlap) {
1409 2282e1af Avi Kivity
        memory_region_add_subregion_overlap(parent, addr, mr, priority);
1410 2282e1af Avi Kivity
    } else {
1411 2282e1af Avi Kivity
        memory_region_add_subregion(parent, addr, mr);
1412 2282e1af Avi Kivity
    }
1413 2282e1af Avi Kivity
    memory_region_transaction_commit();
1414 2282e1af Avi Kivity
}
1415 2282e1af Avi Kivity
1416 a8170e5e Avi Kivity
void memory_region_set_alias_offset(MemoryRegion *mr, hwaddr offset)
1417 4703359e Avi Kivity
{
1418 4703359e Avi Kivity
    assert(mr->alias);
1419 4703359e Avi Kivity
1420 59023ef4 Jan Kiszka
    if (offset == mr->alias_offset) {
1421 4703359e Avi Kivity
        return;
1422 4703359e Avi Kivity
    }
1423 4703359e Avi Kivity
1424 59023ef4 Jan Kiszka
    memory_region_transaction_begin();
1425 59023ef4 Jan Kiszka
    mr->alias_offset = offset;
1426 22bde714 Jan Kiszka
    memory_region_update_pending |= mr->enabled;
1427 59023ef4 Jan Kiszka
    memory_region_transaction_commit();
1428 4703359e Avi Kivity
}
1429 4703359e Avi Kivity
1430 e34911c4 Avi Kivity
ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr)
1431 e34911c4 Avi Kivity
{
1432 e34911c4 Avi Kivity
    return mr->ram_addr;
1433 e34911c4 Avi Kivity
}
1434 e34911c4 Avi Kivity
1435 e2177955 Avi Kivity
static int cmp_flatrange_addr(const void *addr_, const void *fr_)
1436 e2177955 Avi Kivity
{
1437 e2177955 Avi Kivity
    const AddrRange *addr = addr_;
1438 e2177955 Avi Kivity
    const FlatRange *fr = fr_;
1439 e2177955 Avi Kivity
1440 e2177955 Avi Kivity
    if (int128_le(addrrange_end(*addr), fr->addr.start)) {
1441 e2177955 Avi Kivity
        return -1;
1442 e2177955 Avi Kivity
    } else if (int128_ge(addr->start, addrrange_end(fr->addr))) {
1443 e2177955 Avi Kivity
        return 1;
1444 e2177955 Avi Kivity
    }
1445 e2177955 Avi Kivity
    return 0;
1446 e2177955 Avi Kivity
}
1447 e2177955 Avi Kivity
1448 e2177955 Avi Kivity
static FlatRange *address_space_lookup(AddressSpace *as, AddrRange addr)
1449 e2177955 Avi Kivity
{
1450 8786db7c Avi Kivity
    return bsearch(&addr, as->current_map->ranges, as->current_map->nr,
1451 e2177955 Avi Kivity
                   sizeof(FlatRange), cmp_flatrange_addr);
1452 e2177955 Avi Kivity
}
1453 e2177955 Avi Kivity
1454 e2177955 Avi Kivity
MemoryRegionSection memory_region_find(MemoryRegion *address_space,
1455 a8170e5e Avi Kivity
                                       hwaddr addr, uint64_t size)
1456 e2177955 Avi Kivity
{
1457 e2177955 Avi Kivity
    AddressSpace *as = memory_region_to_address_space(address_space);
1458 e2177955 Avi Kivity
    AddrRange range = addrrange_make(int128_make64(addr),
1459 e2177955 Avi Kivity
                                     int128_make64(size));
1460 e2177955 Avi Kivity
    FlatRange *fr = address_space_lookup(as, range);
1461 e2177955 Avi Kivity
    MemoryRegionSection ret = { .mr = NULL, .size = 0 };
1462 e2177955 Avi Kivity
1463 e2177955 Avi Kivity
    if (!fr) {
1464 e2177955 Avi Kivity
        return ret;
1465 e2177955 Avi Kivity
    }
1466 e2177955 Avi Kivity
1467 8786db7c Avi Kivity
    while (fr > as->current_map->ranges
1468 e2177955 Avi Kivity
           && addrrange_intersects(fr[-1].addr, range)) {
1469 e2177955 Avi Kivity
        --fr;
1470 e2177955 Avi Kivity
    }
1471 e2177955 Avi Kivity
1472 e2177955 Avi Kivity
    ret.mr = fr->mr;
1473 e2177955 Avi Kivity
    range = addrrange_intersection(range, fr->addr);
1474 e2177955 Avi Kivity
    ret.offset_within_region = fr->offset_in_region;
1475 e2177955 Avi Kivity
    ret.offset_within_region += int128_get64(int128_sub(range.start,
1476 e2177955 Avi Kivity
                                                        fr->addr.start));
1477 e2177955 Avi Kivity
    ret.size = int128_get64(range.size);
1478 e2177955 Avi Kivity
    ret.offset_within_address_space = int128_get64(range.start);
1479 7a8499e8 Avi Kivity
    ret.readonly = fr->readonly;
1480 e2177955 Avi Kivity
    return ret;
1481 e2177955 Avi Kivity
}
1482 e2177955 Avi Kivity
1483 86e775c6 Avi Kivity
void memory_global_sync_dirty_bitmap(MemoryRegion *address_space)
1484 86e775c6 Avi Kivity
{
1485 7664e80c Avi Kivity
    AddressSpace *as = memory_region_to_address_space(address_space);
1486 7664e80c Avi Kivity
    FlatRange *fr;
1487 7664e80c Avi Kivity
1488 8786db7c Avi Kivity
    FOR_EACH_FLAT_RANGE(fr, as->current_map) {
1489 72e22d2f Avi Kivity
        MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, log_sync);
1490 7664e80c Avi Kivity
    }
1491 7664e80c Avi Kivity
}
1492 7664e80c Avi Kivity
1493 7664e80c Avi Kivity
void memory_global_dirty_log_start(void)
1494 7664e80c Avi Kivity
{
1495 7664e80c Avi Kivity
    global_dirty_log = true;
1496 7376e582 Avi Kivity
    MEMORY_LISTENER_CALL_GLOBAL(log_global_start, Forward);
1497 7664e80c Avi Kivity
}
1498 7664e80c Avi Kivity
1499 7664e80c Avi Kivity
void memory_global_dirty_log_stop(void)
1500 7664e80c Avi Kivity
{
1501 7664e80c Avi Kivity
    global_dirty_log = false;
1502 7376e582 Avi Kivity
    MEMORY_LISTENER_CALL_GLOBAL(log_global_stop, Reverse);
1503 7664e80c Avi Kivity
}
1504 7664e80c Avi Kivity
1505 7664e80c Avi Kivity
static void listener_add_address_space(MemoryListener *listener,
1506 7664e80c Avi Kivity
                                       AddressSpace *as)
1507 7664e80c Avi Kivity
{
1508 7664e80c Avi Kivity
    FlatRange *fr;
1509 7664e80c Avi Kivity
1510 221b3a3f Julien Grall
    if (listener->address_space_filter
1511 f6790af6 Avi Kivity
        && listener->address_space_filter != as) {
1512 221b3a3f Julien Grall
        return;
1513 221b3a3f Julien Grall
    }
1514 221b3a3f Julien Grall
1515 7664e80c Avi Kivity
    if (global_dirty_log) {
1516 975aefe0 Avi Kivity
        if (listener->log_global_start) {
1517 975aefe0 Avi Kivity
            listener->log_global_start(listener);
1518 975aefe0 Avi Kivity
        }
1519 7664e80c Avi Kivity
    }
1520 975aefe0 Avi Kivity
1521 8786db7c Avi Kivity
    FOR_EACH_FLAT_RANGE(fr, as->current_map) {
1522 7664e80c Avi Kivity
        MemoryRegionSection section = {
1523 7664e80c Avi Kivity
            .mr = fr->mr,
1524 f6790af6 Avi Kivity
            .address_space = as,
1525 7664e80c Avi Kivity
            .offset_within_region = fr->offset_in_region,
1526 7664e80c Avi Kivity
            .size = int128_get64(fr->addr.size),
1527 7664e80c Avi Kivity
            .offset_within_address_space = int128_get64(fr->addr.start),
1528 7a8499e8 Avi Kivity
            .readonly = fr->readonly,
1529 7664e80c Avi Kivity
        };
1530 975aefe0 Avi Kivity
        if (listener->region_add) {
1531 975aefe0 Avi Kivity
            listener->region_add(listener, &section);
1532 975aefe0 Avi Kivity
        }
1533 7664e80c Avi Kivity
    }
1534 7664e80c Avi Kivity
}
1535 7664e80c Avi Kivity
1536 f6790af6 Avi Kivity
void memory_listener_register(MemoryListener *listener, AddressSpace *filter)
1537 7664e80c Avi Kivity
{
1538 72e22d2f Avi Kivity
    MemoryListener *other = NULL;
1539 0d673e36 Avi Kivity
    AddressSpace *as;
1540 72e22d2f Avi Kivity
1541 7376e582 Avi Kivity
    listener->address_space_filter = filter;
1542 72e22d2f Avi Kivity
    if (QTAILQ_EMPTY(&memory_listeners)
1543 72e22d2f Avi Kivity
        || listener->priority >= QTAILQ_LAST(&memory_listeners,
1544 72e22d2f Avi Kivity
                                             memory_listeners)->priority) {
1545 72e22d2f Avi Kivity
        QTAILQ_INSERT_TAIL(&memory_listeners, listener, link);
1546 72e22d2f Avi Kivity
    } else {
1547 72e22d2f Avi Kivity
        QTAILQ_FOREACH(other, &memory_listeners, link) {
1548 72e22d2f Avi Kivity
            if (listener->priority < other->priority) {
1549 72e22d2f Avi Kivity
                break;
1550 72e22d2f Avi Kivity
            }
1551 72e22d2f Avi Kivity
        }
1552 72e22d2f Avi Kivity
        QTAILQ_INSERT_BEFORE(other, listener, link);
1553 72e22d2f Avi Kivity
    }
1554 0d673e36 Avi Kivity
1555 0d673e36 Avi Kivity
    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
1556 0d673e36 Avi Kivity
        listener_add_address_space(listener, as);
1557 0d673e36 Avi Kivity
    }
1558 7664e80c Avi Kivity
}
1559 7664e80c Avi Kivity
1560 7664e80c Avi Kivity
void memory_listener_unregister(MemoryListener *listener)
1561 7664e80c Avi Kivity
{
1562 72e22d2f Avi Kivity
    QTAILQ_REMOVE(&memory_listeners, listener, link);
1563 86e775c6 Avi Kivity
}
1564 e2177955 Avi Kivity
1565 9ad2bbc1 Avi Kivity
void address_space_init(AddressSpace *as, MemoryRegion *root)
1566 1c0ffa58 Avi Kivity
{
1567 59023ef4 Jan Kiszka
    memory_region_transaction_begin();
1568 8786db7c Avi Kivity
    as->root = root;
1569 8786db7c Avi Kivity
    as->current_map = g_new(FlatView, 1);
1570 8786db7c Avi Kivity
    flatview_init(as->current_map);
1571 0d673e36 Avi Kivity
    QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
1572 0d673e36 Avi Kivity
    as->name = NULL;
1573 59023ef4 Jan Kiszka
    memory_region_transaction_commit();
1574 ac1970fb Avi Kivity
    address_space_init_dispatch(as);
1575 1c0ffa58 Avi Kivity
}
1576 658b2224 Avi Kivity
1577 83f3c251 Avi Kivity
void address_space_destroy(AddressSpace *as)
1578 83f3c251 Avi Kivity
{
1579 83f3c251 Avi Kivity
    /* Flush out anything from MemoryListeners listening in on this */
1580 83f3c251 Avi Kivity
    memory_region_transaction_begin();
1581 83f3c251 Avi Kivity
    as->root = NULL;
1582 83f3c251 Avi Kivity
    memory_region_transaction_commit();
1583 83f3c251 Avi Kivity
    QTAILQ_REMOVE(&address_spaces, as, address_spaces_link);
1584 83f3c251 Avi Kivity
    address_space_destroy_dispatch(as);
1585 83f3c251 Avi Kivity
    flatview_destroy(as->current_map);
1586 83f3c251 Avi Kivity
    g_free(as->current_map);
1587 83f3c251 Avi Kivity
}
1588 83f3c251 Avi Kivity
1589 a8170e5e Avi Kivity
uint64_t io_mem_read(MemoryRegion *mr, hwaddr addr, unsigned size)
1590 acbbec5d Avi Kivity
{
1591 37ec01d4 Avi Kivity
    return memory_region_dispatch_read(mr, addr, size);
1592 acbbec5d Avi Kivity
}
1593 acbbec5d Avi Kivity
1594 a8170e5e Avi Kivity
void io_mem_write(MemoryRegion *mr, hwaddr addr,
1595 acbbec5d Avi Kivity
                  uint64_t val, unsigned size)
1596 acbbec5d Avi Kivity
{
1597 37ec01d4 Avi Kivity
    memory_region_dispatch_write(mr, addr, val, size);
1598 acbbec5d Avi Kivity
}
1599 acbbec5d Avi Kivity
1600 314e2987 Blue Swirl
typedef struct MemoryRegionList MemoryRegionList;
1601 314e2987 Blue Swirl
1602 314e2987 Blue Swirl
struct MemoryRegionList {
1603 314e2987 Blue Swirl
    const MemoryRegion *mr;
1604 314e2987 Blue Swirl
    bool printed;
1605 314e2987 Blue Swirl
    QTAILQ_ENTRY(MemoryRegionList) queue;
1606 314e2987 Blue Swirl
};
1607 314e2987 Blue Swirl
1608 314e2987 Blue Swirl
typedef QTAILQ_HEAD(queue, MemoryRegionList) MemoryRegionListHead;
1609 314e2987 Blue Swirl
1610 314e2987 Blue Swirl
static void mtree_print_mr(fprintf_function mon_printf, void *f,
1611 314e2987 Blue Swirl
                           const MemoryRegion *mr, unsigned int level,
1612 a8170e5e Avi Kivity
                           hwaddr base,
1613 9479c57a Jan Kiszka
                           MemoryRegionListHead *alias_print_queue)
1614 314e2987 Blue Swirl
{
1615 9479c57a Jan Kiszka
    MemoryRegionList *new_ml, *ml, *next_ml;
1616 9479c57a Jan Kiszka
    MemoryRegionListHead submr_print_queue;
1617 314e2987 Blue Swirl
    const MemoryRegion *submr;
1618 314e2987 Blue Swirl
    unsigned int i;
1619 314e2987 Blue Swirl
1620 7ea692b2 Jan Kiszka
    if (!mr || !mr->enabled) {
1621 314e2987 Blue Swirl
        return;
1622 314e2987 Blue Swirl
    }
1623 314e2987 Blue Swirl
1624 314e2987 Blue Swirl
    for (i = 0; i < level; i++) {
1625 314e2987 Blue Swirl
        mon_printf(f, "  ");
1626 314e2987 Blue Swirl
    }
1627 314e2987 Blue Swirl
1628 314e2987 Blue Swirl
    if (mr->alias) {
1629 314e2987 Blue Swirl
        MemoryRegionList *ml;
1630 314e2987 Blue Swirl
        bool found = false;
1631 314e2987 Blue Swirl
1632 314e2987 Blue Swirl
        /* check if the alias is already in the queue */
1633 9479c57a Jan Kiszka
        QTAILQ_FOREACH(ml, alias_print_queue, queue) {
1634 314e2987 Blue Swirl
            if (ml->mr == mr->alias && !ml->printed) {
1635 314e2987 Blue Swirl
                found = true;
1636 314e2987 Blue Swirl
            }
1637 314e2987 Blue Swirl
        }
1638 314e2987 Blue Swirl
1639 314e2987 Blue Swirl
        if (!found) {
1640 314e2987 Blue Swirl
            ml = g_new(MemoryRegionList, 1);
1641 314e2987 Blue Swirl
            ml->mr = mr->alias;
1642 314e2987 Blue Swirl
            ml->printed = false;
1643 9479c57a Jan Kiszka
            QTAILQ_INSERT_TAIL(alias_print_queue, ml, queue);
1644 314e2987 Blue Swirl
        }
1645 4896d74b Jan Kiszka
        mon_printf(f, TARGET_FMT_plx "-" TARGET_FMT_plx
1646 4896d74b Jan Kiszka
                   " (prio %d, %c%c): alias %s @%s " TARGET_FMT_plx
1647 4896d74b Jan Kiszka
                   "-" TARGET_FMT_plx "\n",
1648 314e2987 Blue Swirl
                   base + mr->addr,
1649 08dafab4 Avi Kivity
                   base + mr->addr
1650 a8170e5e Avi Kivity
                   + (hwaddr)int128_get64(mr->size) - 1,
1651 4b474ba7 Jan Kiszka
                   mr->priority,
1652 4896d74b Jan Kiszka
                   mr->readable ? 'R' : '-',
1653 4896d74b Jan Kiszka
                   !mr->readonly && !(mr->rom_device && mr->readable) ? 'W'
1654 4896d74b Jan Kiszka
                                                                      : '-',
1655 314e2987 Blue Swirl
                   mr->name,
1656 314e2987 Blue Swirl
                   mr->alias->name,
1657 314e2987 Blue Swirl
                   mr->alias_offset,
1658 08dafab4 Avi Kivity
                   mr->alias_offset
1659 a8170e5e Avi Kivity
                   + (hwaddr)int128_get64(mr->size) - 1);
1660 314e2987 Blue Swirl
    } else {
1661 4896d74b Jan Kiszka
        mon_printf(f,
1662 4896d74b Jan Kiszka
                   TARGET_FMT_plx "-" TARGET_FMT_plx " (prio %d, %c%c): %s\n",
1663 314e2987 Blue Swirl
                   base + mr->addr,
1664 08dafab4 Avi Kivity
                   base + mr->addr
1665 a8170e5e Avi Kivity
                   + (hwaddr)int128_get64(mr->size) - 1,
1666 4b474ba7 Jan Kiszka
                   mr->priority,
1667 4896d74b Jan Kiszka
                   mr->readable ? 'R' : '-',
1668 4896d74b Jan Kiszka
                   !mr->readonly && !(mr->rom_device && mr->readable) ? 'W'
1669 4896d74b Jan Kiszka
                                                                      : '-',
1670 314e2987 Blue Swirl
                   mr->name);
1671 314e2987 Blue Swirl
    }
1672 9479c57a Jan Kiszka
1673 9479c57a Jan Kiszka
    QTAILQ_INIT(&submr_print_queue);
1674 9479c57a Jan Kiszka
1675 314e2987 Blue Swirl
    QTAILQ_FOREACH(submr, &mr->subregions, subregions_link) {
1676 9479c57a Jan Kiszka
        new_ml = g_new(MemoryRegionList, 1);
1677 9479c57a Jan Kiszka
        new_ml->mr = submr;
1678 9479c57a Jan Kiszka
        QTAILQ_FOREACH(ml, &submr_print_queue, queue) {
1679 9479c57a Jan Kiszka
            if (new_ml->mr->addr < ml->mr->addr ||
1680 9479c57a Jan Kiszka
                (new_ml->mr->addr == ml->mr->addr &&
1681 9479c57a Jan Kiszka
                 new_ml->mr->priority > ml->mr->priority)) {
1682 9479c57a Jan Kiszka
                QTAILQ_INSERT_BEFORE(ml, new_ml, queue);
1683 9479c57a Jan Kiszka
                new_ml = NULL;
1684 9479c57a Jan Kiszka
                break;
1685 9479c57a Jan Kiszka
            }
1686 9479c57a Jan Kiszka
        }
1687 9479c57a Jan Kiszka
        if (new_ml) {
1688 9479c57a Jan Kiszka
            QTAILQ_INSERT_TAIL(&submr_print_queue, new_ml, queue);
1689 9479c57a Jan Kiszka
        }
1690 9479c57a Jan Kiszka
    }
1691 9479c57a Jan Kiszka
1692 9479c57a Jan Kiszka
    QTAILQ_FOREACH(ml, &submr_print_queue, queue) {
1693 9479c57a Jan Kiszka
        mtree_print_mr(mon_printf, f, ml->mr, level + 1, base + mr->addr,
1694 9479c57a Jan Kiszka
                       alias_print_queue);
1695 9479c57a Jan Kiszka
    }
1696 9479c57a Jan Kiszka
1697 88365e47 Avi Kivity
    QTAILQ_FOREACH_SAFE(ml, &submr_print_queue, queue, next_ml) {
1698 9479c57a Jan Kiszka
        g_free(ml);
1699 314e2987 Blue Swirl
    }
1700 314e2987 Blue Swirl
}
1701 314e2987 Blue Swirl
1702 314e2987 Blue Swirl
void mtree_info(fprintf_function mon_printf, void *f)
1703 314e2987 Blue Swirl
{
1704 314e2987 Blue Swirl
    MemoryRegionListHead ml_head;
1705 314e2987 Blue Swirl
    MemoryRegionList *ml, *ml2;
1706 0d673e36 Avi Kivity
    AddressSpace *as;
1707 314e2987 Blue Swirl
1708 314e2987 Blue Swirl
    QTAILQ_INIT(&ml_head);
1709 314e2987 Blue Swirl
1710 0d673e36 Avi Kivity
    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
1711 0d673e36 Avi Kivity
        if (!as->name) {
1712 0d673e36 Avi Kivity
            continue;
1713 0d673e36 Avi Kivity
        }
1714 0d673e36 Avi Kivity
        mon_printf(f, "%s\n", as->name);
1715 0d673e36 Avi Kivity
        mtree_print_mr(mon_printf, f, as->root, 0, 0, &ml_head);
1716 b9f9be88 Blue Swirl
    }
1717 b9f9be88 Blue Swirl
1718 b9f9be88 Blue Swirl
    mon_printf(f, "aliases\n");
1719 314e2987 Blue Swirl
    /* print aliased regions */
1720 314e2987 Blue Swirl
    QTAILQ_FOREACH(ml, &ml_head, queue) {
1721 314e2987 Blue Swirl
        if (!ml->printed) {
1722 314e2987 Blue Swirl
            mon_printf(f, "%s\n", ml->mr->name);
1723 314e2987 Blue Swirl
            mtree_print_mr(mon_printf, f, ml->mr, 0, 0, &ml_head);
1724 314e2987 Blue Swirl
        }
1725 314e2987 Blue Swirl
    }
1726 314e2987 Blue Swirl
1727 314e2987 Blue Swirl
    QTAILQ_FOREACH_SAFE(ml, &ml_head, queue, ml2) {
1728 88365e47 Avi Kivity
        g_free(ml);
1729 314e2987 Blue Swirl
    }
1730 314e2987 Blue Swirl
}