diff --git a/cpu-common.h b/cpu-common.h index 48f4c01a3f..72eb731c3e 100644 --- a/cpu-common.h +++ b/cpu-common.h @@ -61,9 +61,12 @@ static inline void cpu_register_physical_memory(target_phys_addr_t start_addr, } ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr); +struct MemoryRegion; 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(DeviceState *dev, const char *name, ram_addr_t size); + ram_addr_t size, void *host, + struct MemoryRegion *mr); +ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size, + struct MemoryRegion *mr); void qemu_ram_free(ram_addr_t addr); void qemu_ram_free_from_ptr(ram_addr_t addr); void qemu_ram_remap(ram_addr_t addr, ram_addr_t length); diff --git a/exec.c b/exec.c index 06889bdf18..fbcb1bf028 100644 --- a/exec.c +++ b/exec.c @@ -2916,7 +2916,8 @@ static ram_addr_t last_ram_offset(void) } ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name, - ram_addr_t size, void *host) + ram_addr_t size, void *host, + MemoryRegion *mr) { RAMBlock *new_block, *block; @@ -2972,7 +2973,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name, } #else if (xen_enabled()) { - xen_ram_alloc(new_block->offset, size); + xen_ram_alloc(new_block->offset, size, mr); } else { new_block->host = qemu_vmalloc(size); } @@ -2995,9 +2996,10 @@ 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) +ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size, + MemoryRegion *mr) { - return qemu_ram_alloc_from_ptr(dev, name, size, NULL); + return qemu_ram_alloc_from_ptr(dev, name, size, NULL, mr); } void qemu_ram_free_from_ptr(ram_addr_t addr) diff --git a/hw/xen.h b/hw/xen.h index 21621115e4..f9f66e83ef 100644 --- a/hw/xen.h +++ b/hw/xen.h @@ -44,7 +44,9 @@ void xen_vcpu_init(void); void xenstore_store_pv_console_info(int i, struct CharDriverState *chr); #if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY) -void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size); +struct MemoryRegion; +void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, + struct MemoryRegion *mr); #endif #if defined(CONFIG_XEN) && CONFIG_XEN_CTRL_INTERFACE_VERSION < 400 diff --git a/memory.c b/memory.c index 87639ab6ea..37e4f0905b 100644 --- a/memory.c +++ b/memory.c @@ -997,7 +997,7 @@ void memory_region_init_ram(MemoryRegion *mr, memory_region_init(mr, name, size); mr->terminates = true; mr->destructor = memory_region_destructor_ram; - mr->ram_addr = qemu_ram_alloc(dev, name, size); + mr->ram_addr = qemu_ram_alloc(dev, name, size, mr); mr->backend_registered = true; } @@ -1010,7 +1010,7 @@ void memory_region_init_ram_ptr(MemoryRegion *mr, memory_region_init(mr, name, size); mr->terminates = true; mr->destructor = memory_region_destructor_ram_from_ptr; - mr->ram_addr = qemu_ram_alloc_from_ptr(dev, name, size, ptr); + mr->ram_addr = qemu_ram_alloc_from_ptr(dev, name, size, ptr, mr); mr->backend_registered = true; } @@ -1037,7 +1037,7 @@ void memory_region_init_rom_device(MemoryRegion *mr, mr->opaque = opaque; mr->terminates = true; mr->destructor = memory_region_destructor_rom_device; - mr->ram_addr = qemu_ram_alloc(dev, name, size); + mr->ram_addr = qemu_ram_alloc(dev, name, size, mr); mr->ram_addr |= cpu_register_io_memory(memory_region_read_thunk, memory_region_write_thunk, mr, diff --git a/xen-all.c b/xen-all.c index b5e28abd40..bd89889502 100644 --- a/xen-all.c +++ b/xen-all.c @@ -16,6 +16,7 @@ #include "range.h" #include "xen-mapcache.h" #include "trace.h" +#include "exec-memory.h" #include #include @@ -31,6 +32,8 @@ do { } while (0) #endif +static MemoryRegion ram_memory, ram_640k, ram_lo, ram_hi; + /* Compatibility with older version */ #if __XEN_LATEST_INTERFACE_VERSION__ < 0x0003020a static inline uint32_t xen_vcpu_eport(shared_iopage_t *shared_page, int i) @@ -137,27 +140,18 @@ qemu_irq *xen_interrupt_controller_init(void) static void xen_ram_init(ram_addr_t ram_size) { - RAMBlock *new_block; + MemoryRegion *sysmem = get_system_memory(); ram_addr_t below_4g_mem_size, above_4g_mem_size = 0; + ram_addr_t block_len; - new_block = g_malloc0(sizeof (*new_block)); - pstrcpy(new_block->idstr, sizeof (new_block->idstr), "xen.ram"); - new_block->host = NULL; - new_block->offset = 0; - new_block->length = ram_size; + block_len = ram_size; if (ram_size >= HVM_BELOW_4G_RAM_END) { /* Xen does not allocate the memory continuously, and keep a hole at * HVM_BELOW_4G_MMIO_START of HVM_BELOW_4G_MMIO_LENGTH */ - new_block->length += HVM_BELOW_4G_MMIO_LENGTH; + block_len += HVM_BELOW_4G_MMIO_LENGTH; } - - QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next); - - ram_list.phys_dirty = g_realloc(ram_list.phys_dirty, - new_block->length >> TARGET_PAGE_BITS); - memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS), - 0xff, new_block->length >> TARGET_PAGE_BITS); + memory_region_init_ram(&ram_memory, NULL, "xen.ram", block_len); if (ram_size >= HVM_BELOW_4G_RAM_END) { above_4g_mem_size = ram_size - HVM_BELOW_4G_RAM_END; @@ -166,27 +160,36 @@ static void xen_ram_init(ram_addr_t ram_size) below_4g_mem_size = ram_size; } - cpu_register_physical_memory(0, 0xa0000, 0); + memory_region_init_alias(&ram_640k, "xen.ram.640k", + &ram_memory, 0, 0xa0000); + memory_region_add_subregion(sysmem, 0, &ram_640k); /* Skip of the VGA IO memory space, it will be registered later by the VGA * emulated device. * * The area between 0xc0000 and 0x100000 will be used by SeaBIOS to load * the Options ROM, so it is registered here as RAM. */ - cpu_register_physical_memory(0xc0000, below_4g_mem_size - 0xc0000, - 0xc0000); + memory_region_init_alias(&ram_lo, "xen.ram.lo", + &ram_memory, 0xc0000, below_4g_mem_size - 0xc0000); + memory_region_add_subregion(sysmem, 0xc0000, &ram_lo); if (above_4g_mem_size > 0) { - cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size, - 0x100000000ULL); + memory_region_init_alias(&ram_hi, "xen.ram.hi", + &ram_memory, 0x100000000ULL, + above_4g_mem_size); + memory_region_add_subregion(sysmem, 0x100000000ULL, &ram_hi); } } -void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size) +void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr) { unsigned long nr_pfn; xen_pfn_t *pfn_list; int i; + if (mr == &ram_memory) { + return; + } + trace_xen_ram_alloc(ram_addr, size); nr_pfn = size >> TARGET_PAGE_BITS; diff --git a/xen-stub.c b/xen-stub.c index efe2ab55f2..5fa400faae 100644 --- a/xen-stub.c +++ b/xen-stub.c @@ -8,6 +8,7 @@ #include "qemu-common.h" #include "hw/xen.h" +#include "memory.h" void xenstore_store_pv_console_info(int i, CharDriverState *chr) { @@ -30,7 +31,7 @@ void xen_cmos_set_s3_resume(void *opaque, int irq, int level) { } -void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size) +void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr) { }