aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cpu-all.h1
-rw-r--r--exec.c29
2 files changed, 28 insertions, 2 deletions
diff --git a/cpu-all.h b/cpu-all.h
index dbb2139..5d8342b 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -865,6 +865,7 @@ typedef struct RAMBlock {
uint8_t *host;
ram_addr_t offset;
ram_addr_t length;
+ char idstr[256];
QLIST_ENTRY(RAMBlock) next;
} RAMBlock;
diff --git a/exec.c b/exec.c
index 164ba16..fd47d5b 100644
--- a/exec.c
+++ b/exec.c
@@ -36,6 +36,7 @@
#include "qemu-common.h"
#include "tcg.h"
#include "hw/hw.h"
+#include "hw/qdev.h"
#include "osdep.h"
#include "kvm.h"
#include "qemu-timer.h"
@@ -2780,10 +2781,34 @@ static ram_addr_t find_ram_offset(ram_addr_t size)
ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size)
{
- RAMBlock *new_block;
+ RAMBlock *new_block, *block;
size = TARGET_PAGE_ALIGN(size);
- new_block = qemu_malloc(sizeof(*new_block));
+ new_block = qemu_mallocz(sizeof(*new_block));
+
+ if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
+ char *id = dev->parent_bus->info->get_dev_path(dev);
+ if (id) {
+ snprintf(new_block->idstr, sizeof(new_block->idstr), "%s/", id);
+ qemu_free(id);
+ }
+ }
+ 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->length == new_block->length) {
+ fprintf(stderr, "RAMBlock \"%s\" exists, assuming lack of"
+ "free.\n", new_block->idstr);
+ qemu_free(new_block);
+ return block->offset;
+ } else {
+ fprintf(stderr, "RAMBlock \"%s\" already registered with"
+ "different size, abort\n", new_block->idstr);
+ abort();
+ }
+ }
+ }
if (mem_path) {
#if defined (__linux__) && !defined(TARGET_S390X)