#include "hw/qdev.h"
#include "qemu/osdep.h"
#include "sysemu/kvm.h"
+#include "sysemu/sysemu.h"
#include "hw/xen/xen.h"
#include "qemu/timer.h"
#include "qemu/config-file.h"
//#define DEBUG_SUBPAGE
#if !defined(CONFIG_USER_ONLY)
-int phys_ram_fd;
static int in_migration;
RAMList ram_list = { .blocks = QTAILQ_HEAD_INITIALIZER(ram_list.blocks) };
uint16_t ptr : 15;
};
+typedef PhysPageEntry Node[L2_SIZE];
+
struct AddressSpaceDispatch {
/* This is a multi-level map on the physical address space.
* The bottom level has pointers to MemoryRegionSections.
*/
PhysPageEntry phys_map;
+ Node *nodes;
+ MemoryRegionSection *sections;
AddressSpace *as;
};
#define PHYS_SECTION_ROM 2
#define PHYS_SECTION_WATCH 3
-typedef PhysPageEntry Node[L2_SIZE];
-
typedef struct PhysPageMap {
unsigned sections_nb;
unsigned sections_nb_alloc;
MemoryRegionSection *sections;
} PhysPageMap;
-static PhysPageMap cur_map;
+static PhysPageMap *prev_map;
static PhysPageMap next_map;
#define PHYS_MAP_NODE_NIL (((uint16_t)~0) >> 1)
&& mr != &io_mem_watch;
}
-static MemoryRegionSection *address_space_lookup_region(AddressSpace *as,
+static MemoryRegionSection *address_space_lookup_region(AddressSpaceDispatch *d,
hwaddr addr,
bool resolve_subpage)
{
MemoryRegionSection *section;
subpage_t *subpage;
- section = phys_page_find(as->dispatch->phys_map, addr >> TARGET_PAGE_BITS,
- cur_map.nodes, cur_map.sections);
+ section = phys_page_find(d->phys_map, addr >> TARGET_PAGE_BITS,
+ d->nodes, d->sections);
if (resolve_subpage && section->mr->subpage) {
subpage = container_of(section->mr, subpage_t, iomem);
- section = &cur_map.sections[subpage->sub_section[SUBPAGE_IDX(addr)]];
+ section = &d->sections[subpage->sub_section[SUBPAGE_IDX(addr)]];
}
return section;
}
static MemoryRegionSection *
-address_space_translate_internal(AddressSpace *as, hwaddr addr, hwaddr *xlat,
+address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *xlat,
hwaddr *plen, bool resolve_subpage)
{
MemoryRegionSection *section;
Int128 diff;
- section = address_space_lookup_region(as, addr, resolve_subpage);
+ section = address_space_lookup_region(d, addr, resolve_subpage);
/* Compute offset within MemoryRegionSection */
addr -= section->offset_within_address_space;
hwaddr len = *plen;
for (;;) {
- section = address_space_translate_internal(as, addr, &addr, plen, true);
+ section = address_space_translate_internal(as->dispatch, addr, &addr, plen, true);
mr = section->mr;
if (!mr->iommu_ops) {
hwaddr *plen)
{
MemoryRegionSection *section;
- section = address_space_translate_internal(as, addr, xlat, plen, false);
+ section = address_space_translate_internal(as->dispatch, addr, xlat, plen, false);
assert(!section->mr->iommu_ops);
return section;
iotlb |= PHYS_SECTION_ROM;
}
} else {
- iotlb = section - cur_map.sections;
+ iotlb = section - address_space_memory.dispatch->sections;
iotlb += xlat;
}
}
}
-static void phys_sections_clear(PhysPageMap *map)
+static void phys_sections_free(PhysPageMap *map)
{
while (map->sections_nb > 0) {
MemoryRegionSection *section = &map->sections[--map->sections_nb];
}
g_free(map->sections);
g_free(map->nodes);
+ g_free(map);
}
static void register_subpage(AddressSpaceDispatch *d, MemoryRegionSection *section)
static void mem_add(MemoryListener *listener, MemoryRegionSection *section)
{
AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
- AddressSpaceDispatch *d = as->dispatch;
+ AddressSpaceDispatch *d = as->next_dispatch;
MemoryRegionSection now = *section, remain = *section;
Int128 page_size = int128_make64(TARGET_PAGE_SIZE);
static void qemu_ram_setup_dump(void *addr, ram_addr_t size)
{
int ret;
- QemuOpts *machine_opts;
/* Use MADV_DONTDUMP, if user doesn't want the guest memory in the core */
- machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
- if (machine_opts &&
- !qemu_opt_get_bool(machine_opts, "dump-guest-core", true)) {
+ if (!qemu_opt_get_bool(qemu_get_machine_opts(),
+ "dump-guest-core", true)) {
ret = qemu_madvise(addr, size, QEMU_MADV_DONTDUMP);
if (ret) {
perror("qemu_madvise");
static int memory_try_enable_merging(void *addr, size_t len)
{
- QemuOpts *opts;
-
- opts = qemu_opts_find(qemu_find_opts("machine"), 0);
- if (opts && !qemu_opt_get_bool(opts, "mem-merge", true)) {
+ if (!qemu_opt_get_bool(qemu_get_machine_opts(), "mem-merge", true)) {
/* disabled by the user */
return 0;
}
MemoryRegion *iotlb_to_region(hwaddr index)
{
- return cur_map.sections[index & ~TARGET_PAGE_MASK].mr;
+ return address_space_memory.dispatch->sections[index & ~TARGET_PAGE_MASK].mr;
}
static void io_mem_init(void)
static void mem_begin(MemoryListener *listener)
{
AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
- AddressSpaceDispatch *d = as->dispatch;
+ AddressSpaceDispatch *d = g_new(AddressSpaceDispatch, 1);
+
+ d->phys_map = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .is_leaf = 0 };
+ d->as = as;
+ as->next_dispatch = d;
+}
+
+static void mem_commit(MemoryListener *listener)
+{
+ AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
+ AddressSpaceDispatch *cur = as->dispatch;
+ AddressSpaceDispatch *next = as->next_dispatch;
+
+ next->nodes = next_map.nodes;
+ next->sections = next_map.sections;
- d->phys_map.ptr = PHYS_MAP_NODE_NIL;
+ as->dispatch = next;
+ g_free(cur);
}
static void core_begin(MemoryListener *listener)
{
uint16_t n;
+ prev_map = g_new(PhysPageMap, 1);
+ *prev_map = next_map;
+
memset(&next_map, 0, sizeof(next_map));
n = dummy_section(&io_mem_unassigned);
assert(n == PHYS_SECTION_UNASSIGNED);
*/
static void core_commit(MemoryListener *listener)
{
- PhysPageMap info = cur_map;
- cur_map = next_map;
- phys_sections_clear(&info);
+ phys_sections_free(prev_map);
}
static void tcg_commit(MemoryListener *listener)
void address_space_init_dispatch(AddressSpace *as)
{
- AddressSpaceDispatch *d = g_new(AddressSpaceDispatch, 1);
-
- d->phys_map = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .is_leaf = 0 };
- d->as = as;
- as->dispatch = d;
+ as->dispatch = NULL;
as->dispatch_listener = (MemoryListener) {
.begin = mem_begin,
+ .commit = mem_commit,
.region_add = mem_add,
.region_nop = mem_add,
.priority = 0,