Commit c5705a77 authored by Avi Kivity's avatar Avi Kivity
Browse files

vmstate, memory: decouple vmstate from memory API



Currently creating a memory region automatically registers it for
live migration.  This differs from other state (which is enumerated
in a VMStateDescription structure) and ties the live migration code
into the memory core.

Decouple the two by introducing a separate API, vmstate_register_ram(),
for registering a RAM block for migration.  Currently the same
implementation is reused, but later it can be moved into a separate list,
and registrations can be moved to VMStateDescription blocks.
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent 8991c79b
......@@ -109,7 +109,7 @@ common-obj-$(CONFIG_SD) += sd.o
common-obj-y += bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o
common-obj-y += bt-hci-csr.o
common-obj-y += buffered_file.o migration.o migration-tcp.o
common-obj-y += qemu-char.o savevm.o #aio.o
common-obj-y += qemu-char.o #aio.o
common-obj-y += msmouse.o ps2.o
common-obj-y += qdev.o qdev-properties.o
common-obj-y += block-migration.o iohandler.o
......
......@@ -196,7 +196,7 @@ obj-$(CONFIG_VHOST_NET) += vhost.o
obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
obj-$(CONFIG_KVM) += kvm.o kvm-all.o
obj-$(CONFIG_NO_KVM) += kvm-stub.o
obj-y += memory.o
obj-y += memory.o savevm.o
LIBS+=-lz
QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
......
......@@ -49,6 +49,7 @@ void qemu_put_ram_ptr(void *addr);
/* This should not be used by devices. */
int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr);
void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev);
void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
int len, int is_write);
......
......@@ -25,11 +25,9 @@
#ifndef CONFIG_USER_ONLY
ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
ram_addr_t size, void *host,
ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
MemoryRegion *mr);
ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size,
MemoryRegion *mr);
ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
void qemu_ram_free(ram_addr_t addr);
void qemu_ram_free_from_ptr(ram_addr_t addr);
......
......@@ -2753,14 +2753,19 @@ static ram_addr_t last_ram_offset(void)
return last;
}
ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
ram_addr_t size, void *host,
MemoryRegion *mr)
void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
{
RAMBlock *new_block, *block;
size = TARGET_PAGE_ALIGN(size);
new_block = g_malloc0(sizeof(*new_block));
new_block = NULL;
QLIST_FOREACH(block, &ram_list.blocks, next) {
if (block->offset == addr) {
new_block = block;
break;
}
}
assert(new_block);
assert(!new_block->idstr[0]);
if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
char *id = dev->parent_bus->info->get_dev_path(dev);
......@@ -2772,12 +2777,21 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
pstrcat(new_block->idstr, sizeof(new_block->idstr), name);
QLIST_FOREACH(block, &ram_list.blocks, next) {
if (!strcmp(block->idstr, new_block->idstr)) {
if (block != new_block && !strcmp(block->idstr, new_block->idstr)) {
fprintf(stderr, "RAMBlock \"%s\" already registered, abort!\n",
new_block->idstr);
abort();
}
}
}
ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
MemoryRegion *mr)
{
RAMBlock *new_block;
size = TARGET_PAGE_ALIGN(size);
new_block = g_malloc0(sizeof(*new_block));
new_block->offset = find_ram_offset(size);
if (host) {
......@@ -2834,10 +2848,9 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
return new_block->offset;
}
ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size,
MemoryRegion *mr)
ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr)
{
return qemu_ram_alloc_from_ptr(dev, name, size, NULL, mr);
return qemu_ram_alloc_from_ptr(size, NULL, mr);
}
void qemu_ram_free_from_ptr(ram_addr_t addr)
......
......@@ -726,7 +726,8 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
/* Main memory region, 0x00.0000.0000. Real hardware supports 32GB,
but the address space hole reserved at this point is 8TB. */
memory_region_init_ram(&s->ram_region, NULL, "ram", ram_size);
memory_region_init_ram(&s->ram_region, "ram", ram_size);
vmstate_register_ram_global(&s->ram_region);
memory_region_add_subregion(addr_space, 0, &s->ram_region);
/* TIGbus, 0x801.0000.0000, 1GB. */
......
......@@ -46,11 +46,13 @@ static void an5206_init(ram_addr_t ram_size,
env->rambar0 = AN5206_RAMBAR_ADDR | 1;
/* DRAM at address zero */
memory_region_init_ram(ram, NULL, "an5206.ram", ram_size);
memory_region_init_ram(ram, "an5206.ram", ram_size);
vmstate_register_ram_global(ram);
memory_region_add_subregion(address_space_mem, 0, ram);
/* Internal SRAM. */
memory_region_init_ram(sram, NULL, "an5206.sram", 512);
memory_region_init_ram(sram, "an5206.sram", 512);
vmstate_register_ram_global(sram);
memory_region_add_subregion(address_space_mem, AN5206_RAMBAR_ADDR, sram);
mcf5206_init(address_space_mem, AN5206_MBAR_ADDR, env);
......
......@@ -198,10 +198,12 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
#endif
/* Flash programming is done via the SCU, so pretend it is ROM. */
memory_region_init_ram(flash, NULL, "armv7m.flash", flash_size);
memory_region_init_ram(flash, "armv7m.flash", flash_size);
vmstate_register_ram_global(flash);
memory_region_set_readonly(flash, true);
memory_region_add_subregion(address_space_mem, 0, flash);
memory_region_init_ram(sram, NULL, "armv7m.sram", sram_size);
memory_region_init_ram(sram, "armv7m.sram", sram_size);
vmstate_register_ram_global(sram);
memory_region_add_subregion(address_space_mem, 0x20000000, sram);
armv7m_bitband_init();
......@@ -235,7 +237,8 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
/* Hack to map an additional page of ram at the top of the address
space. This stops qemu complaining about executing code outside RAM
when returning from an exception. */
memory_region_init_ram(hack, NULL, "armv7m.hack", 0x1000);
memory_region_init_ram(hack, "armv7m.hack", 0x1000);
vmstate_register_ram_global(hack);
memory_region_add_subregion(address_space_mem, 0xfffff000, hack);
qemu_register_reset(armv7m_reset, env);
......
......@@ -266,12 +266,14 @@ void axisdev88_init (ram_addr_t ram_size,
env = cpu_init(cpu_model);
/* allocate RAM */
memory_region_init_ram(phys_ram, NULL, "axisdev88.ram", ram_size);
memory_region_init_ram(phys_ram, "axisdev88.ram", ram_size);
vmstate_register_ram_global(phys_ram);
memory_region_add_subregion(address_space_mem, 0x40000000, phys_ram);
/* The ETRAX-FS has 128Kb on chip ram, the docs refer to it as the
internal memory. */
memory_region_init_ram(phys_intmem, NULL, "axisdev88.chipram", INTMEM_SIZE);
memory_region_init_ram(phys_intmem, "axisdev88.chipram", INTMEM_SIZE);
vmstate_register_ram_global(phys_intmem);
memory_region_add_subregion(address_space_mem, 0x38000000, phys_intmem);
/* Attach a NAND flash to CS1. */
......
......@@ -40,7 +40,8 @@ static void dummy_m68k_init(ram_addr_t ram_size,
env->vbr = 0;
/* RAM at address zero */
memory_region_init_ram(ram, NULL, "dummy_m68k.ram", ram_size);
memory_region_init_ram(ram, "dummy_m68k.ram", ram_size);
vmstate_register_ram_global(ram);
memory_region_add_subregion(address_space_mem, 0, ram);
/* Load kernel. */
......
......@@ -524,8 +524,9 @@ static void g364fb_init(DeviceState *dev, G364State *s)
g364fb_screen_dump, NULL, s);
memory_region_init_io(&s->mem_ctrl, &g364fb_ctrl_ops, s, "ctrl", 0x180000);
memory_region_init_ram_ptr(&s->mem_vram, dev, "vram",
memory_region_init_ram_ptr(&s->mem_vram, "vram",
s->vram_size, s->vram);
vmstate_register_ram(&s->mem_vram, dev);
memory_region_set_coalescing(&s->mem_vram);
}
......
......@@ -949,4 +949,9 @@ int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
int required_for_version);
void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
void *opaque);
struct MemoryRegion;
void vmstate_register_ram(struct MemoryRegion *memory, DeviceState *dev);
void vmstate_unregister_ram(struct MemoryRegion *memory, DeviceState *dev);
void vmstate_register_ram_global(struct MemoryRegion *memory);
#endif
......@@ -261,7 +261,8 @@ static int integratorcm_init(SysBusDevice *dev)
}
memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
s->cm_init = 0x00000112;
memory_region_init_ram(&s->flash, NULL, "integrator.flash", 0x100000);
memory_region_init_ram(&s->flash, "integrator.flash", 0x100000);
vmstate_register_ram_global(&s->flash);
s->flash_mapped = false;
memory_region_init_io(&s->iomem, &integratorcm_ops, s,
......@@ -471,7 +472,8 @@ static void integratorcp_init(ram_addr_t ram_size,
fprintf(stderr, "Unable to find CPU definition\n");
exit(1);
}
memory_region_init_ram(ram, NULL, "integrator.ram", ram_size);
memory_region_init_ram(ram, "integrator.ram", ram_size);
vmstate_register_ram_global(ram);
/* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash. */
/* ??? RAM should repeat to fill physical memory space. */
/* SDRAM at address zero*/
......
......@@ -335,8 +335,9 @@ static void create_shared_memory_BAR(IVShmemState *s, int fd) {
ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
memory_region_init_ram_ptr(&s->ivshmem, &s->dev.qdev, "ivshmem.bar2",
memory_region_init_ram_ptr(&s->ivshmem, "ivshmem.bar2",
s->ivshmem_size, ptr);
vmstate_register_ram(&s->ivshmem, &s->dev.qdev);
memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
/* region for shared memory */
......@@ -451,8 +452,9 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
/* mmap the region and map into the BAR2 */
map_ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED,
incoming_fd, 0);
memory_region_init_ram_ptr(&s->ivshmem, &s->dev.qdev,
memory_region_init_ram_ptr(&s->ivshmem,
"ivshmem.bar2", s->ivshmem_size, map_ptr);
vmstate_register_ram(&s->ivshmem, &s->dev.qdev);
IVSHMEM_DPRINTF("guest h/w addr = %" PRIu64 ", size = %" PRIu64 "\n",
s->ivshmem_offset, s->ivshmem_size);
......@@ -753,6 +755,7 @@ static int pci_ivshmem_uninit(PCIDevice *dev)
memory_region_destroy(&s->ivshmem_mmio);
memory_region_del_subregion(&s->bar, &s->ivshmem);
vmstate_unregister_ram(&s->ivshmem, &s->dev.qdev);
memory_region_destroy(&s->ivshmem);
memory_region_destroy(&s->bar);
unregister_savevm(&dev->qdev, "ivshmem", s);
......
......@@ -142,12 +142,14 @@ static void leon3_generic_hw_init(ram_addr_t ram_size,
exit(1);
}
memory_region_init_ram(ram, NULL, "leon3.ram", ram_size);
memory_region_init_ram(ram, "leon3.ram", ram_size);
vmstate_register_ram_global(ram);
memory_region_add_subregion(address_space_mem, 0x40000000, ram);
/* Allocate BIOS */
prom_size = 8 * 1024 * 1024; /* 8Mb */
memory_region_init_ram(prom, NULL, "Leon3.bios", prom_size);
memory_region_init_ram(prom, "Leon3.bios", prom_size);
vmstate_register_ram_global(prom);
memory_region_set_readonly(prom, true);
memory_region_add_subregion(address_space_mem, 0x00000000, prom);
......
......@@ -106,7 +106,8 @@ static void lm32_evr_init(ram_addr_t ram_size_not_used,
reset_info->flash_base = flash_base;
memory_region_init_ram(phys_ram, NULL, "lm32_evr.sdram", ram_size);
memory_region_init_ram(phys_ram, "lm32_evr.sdram", ram_size);
vmstate_register_ram_global(phys_ram);
memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
dinfo = drive_get(IF_PFLASH, 0, 0);
......@@ -200,7 +201,8 @@ static void lm32_uclinux_init(ram_addr_t ram_size_not_used,
reset_info->flash_base = flash_base;
memory_region_init_ram(phys_ram, NULL, "lm32_uclinux.sdram", ram_size);
memory_region_init_ram(phys_ram, "lm32_uclinux.sdram", ram_size);
vmstate_register_ram_global(phys_ram);
memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
dinfo = drive_get(IF_PFLASH, 0, 0);
......
......@@ -111,7 +111,8 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
/* Setup CPU & memory */
cpu = pxa270_init(address_space_mem, mainstone_binfo.ram_size, cpu_model);
memory_region_init_ram(rom, NULL, "mainstone.rom", MAINSTONE_ROM);
memory_region_init_ram(rom, "mainstone.rom", MAINSTONE_ROM);
vmstate_register_ram_global(rom);
memory_region_set_readonly(rom, true);
memory_region_add_subregion(address_space_mem, 0, rom);
......
......@@ -213,11 +213,13 @@ static void mcf5208evb_init(ram_addr_t ram_size,
/* TODO: Configure BARs. */
/* DRAM at 0x40000000 */
memory_region_init_ram(ram, NULL, "mcf5208.ram", ram_size);
memory_region_init_ram(ram, "mcf5208.ram", ram_size);
vmstate_register_ram_global(ram);
memory_region_add_subregion(address_space_mem, 0x40000000, ram);
/* Internal SRAM. */
memory_region_init_ram(sram, NULL, "mcf5208.sram", 16384);
memory_region_init_ram(sram, "mcf5208.sram", 16384);
vmstate_register_ram_global(sram);
memory_region_add_subregion(address_space_mem, 0x80000000, sram);
/* Internal peripherals. */
......
......@@ -468,8 +468,9 @@ static int milkymist_minimac2_init(SysBusDevice *dev)
sysbus_init_mmio(dev, &s->regs_region);
/* register buffers memory */
memory_region_init_ram(&s->buffers, NULL, "milkymist-minimac2.buffers",
memory_region_init_ram(&s->buffers, "milkymist-minimac2.buffers",
buffers_size);
vmstate_register_ram_global(&s->buffers);
s->rx0_buf = memory_region_get_ram_ptr(&s->buffers);
s->rx1_buf = s->rx0_buf + MINIMAC2_BUFFER_SIZE;
s->tx_buf = s->rx1_buf + MINIMAC2_BUFFER_SIZE;
......
......@@ -267,11 +267,13 @@ static int milkymist_softusb_init(SysBusDevice *dev)
sysbus_init_mmio(dev, &s->regs_region);
/* register pmem and dmem */
memory_region_init_ram(&s->pmem, NULL, "milkymist-softusb.pmem",
memory_region_init_ram(&s->pmem, "milkymist-softusb.pmem",
s->pmem_size);
vmstate_register_ram_global(&s->pmem);
sysbus_add_memory(dev, s->pmem_base, &s->pmem);
memory_region_init_ram(&s->dmem, NULL, "milkymist-softusb.dmem",
memory_region_init_ram(&s->dmem, "milkymist-softusb.dmem",
s->dmem_size);
vmstate_register_ram_global(&s->dmem);
sysbus_add_memory(dev, s->dmem_base, &s->dmem);
hid_init(&s->hid_kbd, HID_KEYBOARD, softusb_kbd_hid_datain);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment