|
@@ -65,7 +65,7 @@ static inline ioreq_t *xen_vcpu_ioreq(shared_iopage_t *shared_page, int vcpu)
|
|
typedef struct XenPhysmap {
|
|
typedef struct XenPhysmap {
|
|
target_phys_addr_t start_addr;
|
|
target_phys_addr_t start_addr;
|
|
ram_addr_t size;
|
|
ram_addr_t size;
|
|
- MemoryRegion *mr;
|
|
|
|
|
|
+ char *name;
|
|
target_phys_addr_t phys_offset;
|
|
target_phys_addr_t phys_offset;
|
|
|
|
|
|
QLIST_ENTRY(XenPhysmap) list;
|
|
QLIST_ENTRY(XenPhysmap) list;
|
|
@@ -190,6 +190,14 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr)
|
|
xen_pfn_t *pfn_list;
|
|
xen_pfn_t *pfn_list;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
|
|
+ if (runstate_check(RUN_STATE_INMIGRATE)) {
|
|
|
|
+ /* RAM already populated in Xen */
|
|
|
|
+ fprintf(stderr, "%s: do not alloc "RAM_ADDR_FMT
|
|
|
|
+ " bytes of ram at "RAM_ADDR_FMT" when runstate is INMIGRATE\n",
|
|
|
|
+ __func__, size, ram_addr);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (mr == &ram_memory) {
|
|
if (mr == &ram_memory) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -225,6 +233,22 @@ static XenPhysmap *get_physmapping(XenIOState *state,
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static target_phys_addr_t xen_phys_offset_to_gaddr(target_phys_addr_t start_addr,
|
|
|
|
+ ram_addr_t size, void *opaque)
|
|
|
|
+{
|
|
|
|
+ target_phys_addr_t addr = start_addr & TARGET_PAGE_MASK;
|
|
|
|
+ XenIOState *xen_io_state = opaque;
|
|
|
|
+ XenPhysmap *physmap = NULL;
|
|
|
|
+
|
|
|
|
+ QLIST_FOREACH(physmap, &xen_io_state->physmap, list) {
|
|
|
|
+ if (range_covers_byte(physmap->phys_offset, physmap->size, addr)) {
|
|
|
|
+ return physmap->start_addr;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return start_addr;
|
|
|
|
+}
|
|
|
|
+
|
|
#if CONFIG_XEN_CTRL_INTERFACE_VERSION >= 340
|
|
#if CONFIG_XEN_CTRL_INTERFACE_VERSION >= 340
|
|
static int xen_add_to_physmap(XenIOState *state,
|
|
static int xen_add_to_physmap(XenIOState *state,
|
|
target_phys_addr_t start_addr,
|
|
target_phys_addr_t start_addr,
|
|
@@ -237,6 +261,7 @@ static int xen_add_to_physmap(XenIOState *state,
|
|
XenPhysmap *physmap = NULL;
|
|
XenPhysmap *physmap = NULL;
|
|
target_phys_addr_t pfn, start_gpfn;
|
|
target_phys_addr_t pfn, start_gpfn;
|
|
target_phys_addr_t phys_offset = memory_region_get_ram_addr(mr);
|
|
target_phys_addr_t phys_offset = memory_region_get_ram_addr(mr);
|
|
|
|
+ char path[80], value[17];
|
|
|
|
|
|
if (get_physmapping(state, start_addr, size)) {
|
|
if (get_physmapping(state, start_addr, size)) {
|
|
return 0;
|
|
return 0;
|
|
@@ -275,6 +300,7 @@ go_physmap:
|
|
|
|
|
|
physmap->start_addr = start_addr;
|
|
physmap->start_addr = start_addr;
|
|
physmap->size = size;
|
|
physmap->size = size;
|
|
|
|
+ physmap->name = (char *)mr->name;
|
|
physmap->phys_offset = phys_offset;
|
|
physmap->phys_offset = phys_offset;
|
|
|
|
|
|
QLIST_INSERT_HEAD(&state->physmap, physmap, list);
|
|
QLIST_INSERT_HEAD(&state->physmap, physmap, list);
|
|
@@ -283,6 +309,30 @@ go_physmap:
|
|
start_addr >> TARGET_PAGE_BITS,
|
|
start_addr >> TARGET_PAGE_BITS,
|
|
(start_addr + size) >> TARGET_PAGE_BITS,
|
|
(start_addr + size) >> TARGET_PAGE_BITS,
|
|
XEN_DOMCTL_MEM_CACHEATTR_WB);
|
|
XEN_DOMCTL_MEM_CACHEATTR_WB);
|
|
|
|
+
|
|
|
|
+ snprintf(path, sizeof(path),
|
|
|
|
+ "/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
|
|
|
|
+ xen_domid, (uint64_t)phys_offset);
|
|
|
|
+ snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)start_addr);
|
|
|
|
+ if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ snprintf(path, sizeof(path),
|
|
|
|
+ "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
|
|
|
|
+ xen_domid, (uint64_t)phys_offset);
|
|
|
|
+ snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)size);
|
|
|
|
+ if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ if (mr->name) {
|
|
|
|
+ snprintf(path, sizeof(path),
|
|
|
|
+ "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
|
|
|
|
+ xen_domid, (uint64_t)phys_offset);
|
|
|
|
+ if (!xs_write(state->xenstore, 0, path, mr->name, strlen(mr->name))) {
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -942,6 +992,55 @@ int xen_init(void)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void xen_read_physmap(XenIOState *state)
|
|
|
|
+{
|
|
|
|
+ XenPhysmap *physmap = NULL;
|
|
|
|
+ unsigned int len, num, i;
|
|
|
|
+ char path[80], *value = NULL;
|
|
|
|
+ char **entries = NULL;
|
|
|
|
+
|
|
|
|
+ snprintf(path, sizeof(path),
|
|
|
|
+ "/local/domain/0/device-model/%d/physmap", xen_domid);
|
|
|
|
+ entries = xs_directory(state->xenstore, 0, path, &num);
|
|
|
|
+ if (entries == NULL)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < num; i++) {
|
|
|
|
+ physmap = g_malloc(sizeof (XenPhysmap));
|
|
|
|
+ physmap->phys_offset = strtoull(entries[i], NULL, 16);
|
|
|
|
+ snprintf(path, sizeof(path),
|
|
|
|
+ "/local/domain/0/device-model/%d/physmap/%s/start_addr",
|
|
|
|
+ xen_domid, entries[i]);
|
|
|
|
+ value = xs_read(state->xenstore, 0, path, &len);
|
|
|
|
+ if (value == NULL) {
|
|
|
|
+ free(physmap);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ physmap->start_addr = strtoull(value, NULL, 16);
|
|
|
|
+ free(value);
|
|
|
|
+
|
|
|
|
+ snprintf(path, sizeof(path),
|
|
|
|
+ "/local/domain/0/device-model/%d/physmap/%s/size",
|
|
|
|
+ xen_domid, entries[i]);
|
|
|
|
+ value = xs_read(state->xenstore, 0, path, &len);
|
|
|
|
+ if (value == NULL) {
|
|
|
|
+ free(physmap);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ physmap->size = strtoull(value, NULL, 16);
|
|
|
|
+ free(value);
|
|
|
|
+
|
|
|
|
+ snprintf(path, sizeof(path),
|
|
|
|
+ "/local/domain/0/device-model/%d/physmap/%s/name",
|
|
|
|
+ xen_domid, entries[i]);
|
|
|
|
+ physmap->name = xs_read(state->xenstore, 0, path, &len);
|
|
|
|
+
|
|
|
|
+ QLIST_INSERT_HEAD(&state->physmap, physmap, list);
|
|
|
|
+ }
|
|
|
|
+ free(entries);
|
|
|
|
+ return;
|
|
|
|
+}
|
|
|
|
+
|
|
int xen_hvm_init(void)
|
|
int xen_hvm_init(void)
|
|
{
|
|
{
|
|
int i, rc;
|
|
int i, rc;
|
|
@@ -999,7 +1098,7 @@ int xen_hvm_init(void)
|
|
}
|
|
}
|
|
|
|
|
|
/* Init RAM management */
|
|
/* Init RAM management */
|
|
- xen_map_cache_init();
|
|
|
|
|
|
+ xen_map_cache_init(xen_phys_offset_to_gaddr, state);
|
|
xen_ram_init(ram_size);
|
|
xen_ram_init(ram_size);
|
|
|
|
|
|
qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
|
|
qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
|
|
@@ -1017,6 +1116,7 @@ int xen_hvm_init(void)
|
|
xen_be_register("console", &xen_console_ops);
|
|
xen_be_register("console", &xen_console_ops);
|
|
xen_be_register("vkbd", &xen_kbdmouse_ops);
|
|
xen_be_register("vkbd", &xen_kbdmouse_ops);
|
|
xen_be_register("qdisk", &xen_blkdev_ops);
|
|
xen_be_register("qdisk", &xen_blkdev_ops);
|
|
|
|
+ xen_read_physmap(state);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|