|
|
9ae3a8 |
From c67daf48e19c0a73c933d09a4c748cfda8d6d3f2 Mon Sep 17 00:00:00 2001
|
|
|
9ae3a8 |
From: Laszlo Ersek <lersek@redhat.com>
|
|
|
9ae3a8 |
Date: Mon, 12 Aug 2013 15:59:40 +0200
|
|
|
9ae3a8 |
Subject: dump: rebase from host-private RAMBlock offsets to guest-physical addresses
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
RH-Author: Laszlo Ersek <lersek@redhat.com>
|
|
|
9ae3a8 |
Message-id: <1376323180-12863-11-git-send-email-lersek@redhat.com>
|
|
|
9ae3a8 |
Patchwork-id: 53168
|
|
|
9ae3a8 |
O-Subject: [RHEL-7 qemu-kvm PATCH 10/10] dump: rebase from host-private RAMBlock offsets to guest-physical addresses
|
|
|
9ae3a8 |
Bugzilla: 981582
|
|
|
9ae3a8 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Radim Krcmar <rkrcmar@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
RAMBlock.offset --> GuestPhysBlock.target_start
|
|
|
9ae3a8 |
RAMBlock.offset + RAMBlock.length --> GuestPhysBlock.target_end
|
|
|
9ae3a8 |
RAMBlock.length --> GuestPhysBlock.target_end -
|
|
|
9ae3a8 |
GuestPhysBlock.target_start
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
"GuestPhysBlock.host_addr" is only used when writing the dump contents.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
This patch enables "crash" to work with the vmcore by rebasing the vmcore
|
|
|
9ae3a8 |
from the left side of the following diagram to the right side:
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
host-private
|
|
|
9ae3a8 |
offset
|
|
|
9ae3a8 |
relative
|
|
|
9ae3a8 |
to ram_addr RAMBlock guest-visible paddrs
|
|
|
9ae3a8 |
0 +-------------------+.....+-------------------+ 0
|
|
|
9ae3a8 |
| ^ | | ^ |
|
|
|
9ae3a8 |
| 640 KB | | 640 KB |
|
|
|
9ae3a8 |
| v | | v |
|
|
|
9ae3a8 |
0x0000a0000 +-------------------+.....+-------------------+ 0x0000a0000
|
|
|
9ae3a8 |
| ^ | |XXXXXXXXXXXXXXXXXXX|
|
|
|
9ae3a8 |
| 384 KB | |XXXXXXXXXXXXXXXXXXX|
|
|
|
9ae3a8 |
| v | |XXXXXXXXXXXXXXXXXXX|
|
|
|
9ae3a8 |
0x000100000 +-------------------+.....+-------------------+ 0x000100000
|
|
|
9ae3a8 |
| ^ | | ^ |
|
|
|
9ae3a8 |
| 3583 MB | | 3583 MB |
|
|
|
9ae3a8 |
| v | | v |
|
|
|
9ae3a8 |
0x0e0000000 +-------------------+.....+-------------------+ 0x0e0000000
|
|
|
9ae3a8 |
| ^ |. |XXXXXXXXXXXXXXXXXXX|
|
|
|
9ae3a8 |
| above_4g_mem_size | . |XXXX PCI hole XXXXX|
|
|
|
9ae3a8 |
| v | . |XXXX XXXXX|
|
|
|
9ae3a8 |
ram_size +-------------------+ . |XXXX 512 MB XXXXX|
|
|
|
9ae3a8 |
. .|XXXXXXXXXXXXXXXXXXX|
|
|
|
9ae3a8 |
. +-------------------+ 0x100000000
|
|
|
9ae3a8 |
. | ^ |
|
|
|
9ae3a8 |
. | above_4g_mem_size |
|
|
|
9ae3a8 |
.| v |
|
|
|
9ae3a8 |
+-------------------+ ram_size
|
|
|
9ae3a8 |
+ 512 MB
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Related RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=981582
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
9ae3a8 |
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
|
|
|
9ae3a8 |
(cherry picked from commit 56c4bfb3f07f3107894c00281276aea4f5e8834d)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Conflicts:
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
memory_mapping.c
|
|
|
9ae3a8 |
stubs/dump.c
|
|
|
9ae3a8 |
target-s390x/arch_dump.c
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
The conflicts are due to RHEL-7 not having
|
|
|
9ae3a8 |
- upstream commit 182735ef ("cpu: Make first_cpu and next_cpu CPUState"),
|
|
|
9ae3a8 |
whose backport I rejected due to its many dependencies,
|
|
|
9ae3a8 |
- upstream commit 9b4f38e1 ("s390: Implement dump-guest-memory support for
|
|
|
9ae3a8 |
target s390x") -- we don't support the s390x target.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/dump.c b/dump.c
|
|
|
9ae3a8 |
index e6b7a00..0523ad4 100644
|
|
|
9ae3a8 |
--- a/dump.c
|
|
|
9ae3a8 |
+++ b/dump.c
|
|
|
9ae3a8 |
@@ -70,7 +70,7 @@ typedef struct DumpState {
|
|
|
9ae3a8 |
hwaddr memory_offset;
|
|
|
9ae3a8 |
int fd;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- RAMBlock *block;
|
|
|
9ae3a8 |
+ GuestPhysBlock *next_block;
|
|
|
9ae3a8 |
ram_addr_t start;
|
|
|
9ae3a8 |
bool has_filter;
|
|
|
9ae3a8 |
int64_t begin;
|
|
|
9ae3a8 |
@@ -395,14 +395,14 @@ static int write_data(DumpState *s, void *buf, int length)
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* write the memroy to vmcore. 1 page per I/O. */
|
|
|
9ae3a8 |
-static int write_memory(DumpState *s, RAMBlock *block, ram_addr_t start,
|
|
|
9ae3a8 |
+static int write_memory(DumpState *s, GuestPhysBlock *block, ram_addr_t start,
|
|
|
9ae3a8 |
int64_t size)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
int64_t i;
|
|
|
9ae3a8 |
int ret;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
for (i = 0; i < size / TARGET_PAGE_SIZE; i++) {
|
|
|
9ae3a8 |
- ret = write_data(s, block->host + start + i * TARGET_PAGE_SIZE,
|
|
|
9ae3a8 |
+ ret = write_data(s, block->host_addr + start + i * TARGET_PAGE_SIZE,
|
|
|
9ae3a8 |
TARGET_PAGE_SIZE);
|
|
|
9ae3a8 |
if (ret < 0) {
|
|
|
9ae3a8 |
return ret;
|
|
|
9ae3a8 |
@@ -410,7 +410,7 @@ static int write_memory(DumpState *s, RAMBlock *block, ram_addr_t start,
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
if ((size % TARGET_PAGE_SIZE) != 0) {
|
|
|
9ae3a8 |
- ret = write_data(s, block->host + start + i * TARGET_PAGE_SIZE,
|
|
|
9ae3a8 |
+ ret = write_data(s, block->host_addr + start + i * TARGET_PAGE_SIZE,
|
|
|
9ae3a8 |
size % TARGET_PAGE_SIZE);
|
|
|
9ae3a8 |
if (ret < 0) {
|
|
|
9ae3a8 |
return ret;
|
|
|
9ae3a8 |
@@ -427,7 +427,7 @@ static void get_offset_range(hwaddr phys_addr,
|
|
|
9ae3a8 |
hwaddr *p_offset,
|
|
|
9ae3a8 |
hwaddr *p_filesz)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
- RAMBlock *block;
|
|
|
9ae3a8 |
+ GuestPhysBlock *block;
|
|
|
9ae3a8 |
hwaddr offset = s->memory_offset;
|
|
|
9ae3a8 |
int64_t size_in_block, start;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
@@ -441,35 +441,34 @@ static void get_offset_range(hwaddr phys_addr,
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- QTAILQ_FOREACH(block, &ram_list.blocks, next) {
|
|
|
9ae3a8 |
+ QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
|
|
|
9ae3a8 |
if (s->has_filter) {
|
|
|
9ae3a8 |
- if (block->offset >= s->begin + s->length ||
|
|
|
9ae3a8 |
- block->offset + block->length <= s->begin) {
|
|
|
9ae3a8 |
+ if (block->target_start >= s->begin + s->length ||
|
|
|
9ae3a8 |
+ block->target_end <= s->begin) {
|
|
|
9ae3a8 |
/* This block is out of the range */
|
|
|
9ae3a8 |
continue;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- if (s->begin <= block->offset) {
|
|
|
9ae3a8 |
- start = block->offset;
|
|
|
9ae3a8 |
+ if (s->begin <= block->target_start) {
|
|
|
9ae3a8 |
+ start = block->target_start;
|
|
|
9ae3a8 |
} else {
|
|
|
9ae3a8 |
start = s->begin;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- size_in_block = block->length - (start - block->offset);
|
|
|
9ae3a8 |
- if (s->begin + s->length < block->offset + block->length) {
|
|
|
9ae3a8 |
- size_in_block -= block->offset + block->length -
|
|
|
9ae3a8 |
- (s->begin + s->length);
|
|
|
9ae3a8 |
+ size_in_block = block->target_end - start;
|
|
|
9ae3a8 |
+ if (s->begin + s->length < block->target_end) {
|
|
|
9ae3a8 |
+ size_in_block -= block->target_end - (s->begin + s->length);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
} else {
|
|
|
9ae3a8 |
- start = block->offset;
|
|
|
9ae3a8 |
- size_in_block = block->length;
|
|
|
9ae3a8 |
+ start = block->target_start;
|
|
|
9ae3a8 |
+ size_in_block = block->target_end - block->target_start;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
if (phys_addr >= start && phys_addr < start + size_in_block) {
|
|
|
9ae3a8 |
*p_offset = phys_addr - start + offset;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* The offset range mapped from the vmcore file must not spill over
|
|
|
9ae3a8 |
- * the RAMBlock, clamp it. The rest of the mapping will be
|
|
|
9ae3a8 |
+ * the GuestPhysBlock, clamp it. The rest of the mapping will be
|
|
|
9ae3a8 |
* zero-filled in memory at load time; see
|
|
|
9ae3a8 |
* <http://refspecs.linuxbase.org/elf/gabi4+/ch5.pheader.html>.
|
|
|
9ae3a8 |
*/
|
|
|
9ae3a8 |
@@ -617,7 +616,7 @@ static int dump_completed(DumpState *s)
|
|
|
9ae3a8 |
return 0;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
-static int get_next_block(DumpState *s, RAMBlock *block)
|
|
|
9ae3a8 |
+static int get_next_block(DumpState *s, GuestPhysBlock *block)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
while (1) {
|
|
|
9ae3a8 |
block = QTAILQ_NEXT(block, next);
|
|
|
9ae3a8 |
@@ -627,16 +626,16 @@ static int get_next_block(DumpState *s, RAMBlock *block)
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
s->start = 0;
|
|
|
9ae3a8 |
- s->block = block;
|
|
|
9ae3a8 |
+ s->next_block = block;
|
|
|
9ae3a8 |
if (s->has_filter) {
|
|
|
9ae3a8 |
- if (block->offset >= s->begin + s->length ||
|
|
|
9ae3a8 |
- block->offset + block->length <= s->begin) {
|
|
|
9ae3a8 |
+ if (block->target_start >= s->begin + s->length ||
|
|
|
9ae3a8 |
+ block->target_end <= s->begin) {
|
|
|
9ae3a8 |
/* This block is out of the range */
|
|
|
9ae3a8 |
continue;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- if (s->begin > block->offset) {
|
|
|
9ae3a8 |
- s->start = s->begin - block->offset;
|
|
|
9ae3a8 |
+ if (s->begin > block->target_start) {
|
|
|
9ae3a8 |
+ s->start = s->begin - block->target_start;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
@@ -647,18 +646,18 @@ static int get_next_block(DumpState *s, RAMBlock *block)
|
|
|
9ae3a8 |
/* write all memory to vmcore */
|
|
|
9ae3a8 |
static int dump_iterate(DumpState *s)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
- RAMBlock *block;
|
|
|
9ae3a8 |
+ GuestPhysBlock *block;
|
|
|
9ae3a8 |
int64_t size;
|
|
|
9ae3a8 |
int ret;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
while (1) {
|
|
|
9ae3a8 |
- block = s->block;
|
|
|
9ae3a8 |
+ block = s->next_block;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- size = block->length;
|
|
|
9ae3a8 |
+ size = block->target_end - block->target_start;
|
|
|
9ae3a8 |
if (s->has_filter) {
|
|
|
9ae3a8 |
size -= s->start;
|
|
|
9ae3a8 |
- if (s->begin + s->length < block->offset + block->length) {
|
|
|
9ae3a8 |
- size -= block->offset + block->length - (s->begin + s->length);
|
|
|
9ae3a8 |
+ if (s->begin + s->length < block->target_end) {
|
|
|
9ae3a8 |
+ size -= block->target_end - (s->begin + s->length);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
ret = write_memory(s, block, s->start, size);
|
|
|
9ae3a8 |
@@ -693,23 +692,23 @@ static int create_vmcore(DumpState *s)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
static ram_addr_t get_start_block(DumpState *s)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
- RAMBlock *block;
|
|
|
9ae3a8 |
+ GuestPhysBlock *block;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
if (!s->has_filter) {
|
|
|
9ae3a8 |
- s->block = QTAILQ_FIRST(&ram_list.blocks);
|
|
|
9ae3a8 |
+ s->next_block = QTAILQ_FIRST(&s->guest_phys_blocks.head);
|
|
|
9ae3a8 |
return 0;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- QTAILQ_FOREACH(block, &ram_list.blocks, next) {
|
|
|
9ae3a8 |
- if (block->offset >= s->begin + s->length ||
|
|
|
9ae3a8 |
- block->offset + block->length <= s->begin) {
|
|
|
9ae3a8 |
+ QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
|
|
|
9ae3a8 |
+ if (block->target_start >= s->begin + s->length ||
|
|
|
9ae3a8 |
+ block->target_end <= s->begin) {
|
|
|
9ae3a8 |
/* This block is out of the range */
|
|
|
9ae3a8 |
continue;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- s->block = block;
|
|
|
9ae3a8 |
- if (s->begin > block->offset) {
|
|
|
9ae3a8 |
- s->start = s->begin - block->offset;
|
|
|
9ae3a8 |
+ s->next_block = block;
|
|
|
9ae3a8 |
+ if (s->begin > block->target_start) {
|
|
|
9ae3a8 |
+ s->start = s->begin - block->target_start;
|
|
|
9ae3a8 |
} else {
|
|
|
9ae3a8 |
s->start = 0;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
@@ -762,7 +761,7 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
|
|
|
9ae3a8 |
* If the target architecture is not supported, cpu_get_dump_info() will
|
|
|
9ae3a8 |
* return -1.
|
|
|
9ae3a8 |
*/
|
|
|
9ae3a8 |
- ret = cpu_get_dump_info(&s->dump_info);
|
|
|
9ae3a8 |
+ ret = cpu_get_dump_info(&s->dump_info, &s->guest_phys_blocks);
|
|
|
9ae3a8 |
if (ret < 0) {
|
|
|
9ae3a8 |
error_set(errp, QERR_UNSUPPORTED);
|
|
|
9ae3a8 |
goto cleanup;
|
|
|
9ae3a8 |
@@ -778,13 +777,13 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
|
|
|
9ae3a8 |
/* get memory mapping */
|
|
|
9ae3a8 |
memory_mapping_list_init(&s->list);
|
|
|
9ae3a8 |
if (paging) {
|
|
|
9ae3a8 |
- qemu_get_guest_memory_mapping(&s->list, &err;;
|
|
|
9ae3a8 |
+ qemu_get_guest_memory_mapping(&s->list, &s->guest_phys_blocks, &err;;
|
|
|
9ae3a8 |
if (err != NULL) {
|
|
|
9ae3a8 |
error_propagate(errp, err);
|
|
|
9ae3a8 |
goto cleanup;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
} else {
|
|
|
9ae3a8 |
- qemu_get_guest_simple_memory_mapping(&s->list);
|
|
|
9ae3a8 |
+ qemu_get_guest_simple_memory_mapping(&s->list, &s->guest_phys_blocks);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
if (s->has_filter) {
|
|
|
9ae3a8 |
diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
|
|
|
9ae3a8 |
index b8c770f..19fafb2 100644
|
|
|
9ae3a8 |
--- a/include/sysemu/dump.h
|
|
|
9ae3a8 |
+++ b/include/sysemu/dump.h
|
|
|
9ae3a8 |
@@ -20,7 +20,9 @@ typedef struct ArchDumpInfo {
|
|
|
9ae3a8 |
int d_class; /* ELFCLASS32 or ELFCLASS64 */
|
|
|
9ae3a8 |
} ArchDumpInfo;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
-int cpu_get_dump_info(ArchDumpInfo *info);
|
|
|
9ae3a8 |
+struct GuestPhysBlockList; /* memory_mapping.h */
|
|
|
9ae3a8 |
+int cpu_get_dump_info(ArchDumpInfo *info,
|
|
|
9ae3a8 |
+ const struct GuestPhysBlockList *guest_phys_blocks);
|
|
|
9ae3a8 |
ssize_t cpu_get_note_size(int class, int machine, int nr_cpus);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
#endif
|
|
|
9ae3a8 |
diff --git a/include/sysemu/memory_mapping.h b/include/sysemu/memory_mapping.h
|
|
|
9ae3a8 |
index b2d7d85..a75d59a 100644
|
|
|
9ae3a8 |
--- a/include/sysemu/memory_mapping.h
|
|
|
9ae3a8 |
+++ b/include/sysemu/memory_mapping.h
|
|
|
9ae3a8 |
@@ -68,10 +68,13 @@ void guest_phys_blocks_free(GuestPhysBlockList *list);
|
|
|
9ae3a8 |
void guest_phys_blocks_init(GuestPhysBlockList *list);
|
|
|
9ae3a8 |
void guest_phys_blocks_append(GuestPhysBlockList *list);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
-void qemu_get_guest_memory_mapping(MemoryMappingList *list, Error **errp);
|
|
|
9ae3a8 |
+void qemu_get_guest_memory_mapping(MemoryMappingList *list,
|
|
|
9ae3a8 |
+ const GuestPhysBlockList *guest_phys_blocks,
|
|
|
9ae3a8 |
+ Error **errp);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* get guest's memory mapping without do paging(virtual address is 0). */
|
|
|
9ae3a8 |
-void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list);
|
|
|
9ae3a8 |
+void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list,
|
|
|
9ae3a8 |
+ const GuestPhysBlockList *guest_phys_blocks);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
void memory_mapping_filter(MemoryMappingList *list, int64_t begin,
|
|
|
9ae3a8 |
int64_t length);
|
|
|
9ae3a8 |
diff --git a/memory_mapping.c b/memory_mapping.c
|
|
|
9ae3a8 |
index 411aba6..65082d8 100644
|
|
|
9ae3a8 |
--- a/memory_mapping.c
|
|
|
9ae3a8 |
+++ b/memory_mapping.c
|
|
|
9ae3a8 |
@@ -279,10 +279,12 @@ static CPUArchState *find_paging_enabled_cpu(CPUArchState *start_cpu)
|
|
|
9ae3a8 |
return NULL;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
-void qemu_get_guest_memory_mapping(MemoryMappingList *list, Error **errp)
|
|
|
9ae3a8 |
+void qemu_get_guest_memory_mapping(MemoryMappingList *list,
|
|
|
9ae3a8 |
+ const GuestPhysBlockList *guest_phys_blocks,
|
|
|
9ae3a8 |
+ Error **errp)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
CPUArchState *env, *first_paging_enabled_cpu;
|
|
|
9ae3a8 |
- RAMBlock *block;
|
|
|
9ae3a8 |
+ GuestPhysBlock *block;
|
|
|
9ae3a8 |
ram_addr_t offset, length;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
first_paging_enabled_cpu = find_paging_enabled_cpu(first_cpu);
|
|
|
9ae3a8 |
@@ -302,19 +304,21 @@ void qemu_get_guest_memory_mapping(MemoryMappingList *list, Error **errp)
|
|
|
9ae3a8 |
* If the guest doesn't use paging, the virtual address is equal to physical
|
|
|
9ae3a8 |
* address.
|
|
|
9ae3a8 |
*/
|
|
|
9ae3a8 |
- QTAILQ_FOREACH(block, &ram_list.blocks, next) {
|
|
|
9ae3a8 |
- offset = block->offset;
|
|
|
9ae3a8 |
- length = block->length;
|
|
|
9ae3a8 |
+ QTAILQ_FOREACH(block, &guest_phys_blocks->head, next) {
|
|
|
9ae3a8 |
+ offset = block->target_start;
|
|
|
9ae3a8 |
+ length = block->target_end - block->target_start;
|
|
|
9ae3a8 |
create_new_memory_mapping(list, offset, offset, length);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
-void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list)
|
|
|
9ae3a8 |
+void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list,
|
|
|
9ae3a8 |
+ const GuestPhysBlockList *guest_phys_blocks)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
- RAMBlock *block;
|
|
|
9ae3a8 |
+ GuestPhysBlock *block;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- QTAILQ_FOREACH(block, &ram_list.blocks, next) {
|
|
|
9ae3a8 |
- create_new_memory_mapping(list, block->offset, 0, block->length);
|
|
|
9ae3a8 |
+ QTAILQ_FOREACH(block, &guest_phys_blocks->head, next) {
|
|
|
9ae3a8 |
+ create_new_memory_mapping(list, block->target_start, 0,
|
|
|
9ae3a8 |
+ block->target_end - block->target_start);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/stubs/dump.c b/stubs/dump.c
|
|
|
9ae3a8 |
index b3f42cb..5749e2c 100644
|
|
|
9ae3a8 |
--- a/stubs/dump.c
|
|
|
9ae3a8 |
+++ b/stubs/dump.c
|
|
|
9ae3a8 |
@@ -24,7 +24,8 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
|
|
|
9ae3a8 |
error_set(errp, QERR_UNSUPPORTED);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
-int cpu_get_dump_info(ArchDumpInfo *info)
|
|
|
9ae3a8 |
+int cpu_get_dump_info(ArchDumpInfo *info,
|
|
|
9ae3a8 |
+ const struct GuestPhysBlockList *guest_phys_blocks)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
return -1;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c
|
|
|
9ae3a8 |
index 83898cd..a99ef8c 100644
|
|
|
9ae3a8 |
--- a/target-i386/arch_dump.c
|
|
|
9ae3a8 |
+++ b/target-i386/arch_dump.c
|
|
|
9ae3a8 |
@@ -15,6 +15,7 @@
|
|
|
9ae3a8 |
#include "exec/cpu-all.h"
|
|
|
9ae3a8 |
#include "sysemu/dump.h"
|
|
|
9ae3a8 |
#include "elf.h"
|
|
|
9ae3a8 |
+#include "sysemu/memory_mapping.h"
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
#ifdef TARGET_X86_64
|
|
|
9ae3a8 |
typedef struct {
|
|
|
9ae3a8 |
@@ -388,10 +389,11 @@ int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cs,
|
|
|
9ae3a8 |
return cpu_write_qemu_note(f, &cpu->env, opaque, 0);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
-int cpu_get_dump_info(ArchDumpInfo *info)
|
|
|
9ae3a8 |
+int cpu_get_dump_info(ArchDumpInfo *info,
|
|
|
9ae3a8 |
+ const GuestPhysBlockList *guest_phys_blocks)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
bool lma = false;
|
|
|
9ae3a8 |
- RAMBlock *block;
|
|
|
9ae3a8 |
+ GuestPhysBlock *block;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
#ifdef TARGET_X86_64
|
|
|
9ae3a8 |
lma = !!(first_cpu->hflags & HF_LMA_MASK);
|
|
|
9ae3a8 |
@@ -409,8 +411,8 @@ int cpu_get_dump_info(ArchDumpInfo *info)
|
|
|
9ae3a8 |
} else {
|
|
|
9ae3a8 |
info->d_class = ELFCLASS32;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- QTAILQ_FOREACH(block, &ram_list.blocks, next) {
|
|
|
9ae3a8 |
- if (block->offset + block->length > UINT_MAX) {
|
|
|
9ae3a8 |
+ QTAILQ_FOREACH(block, &guest_phys_blocks->head, next) {
|
|
|
9ae3a8 |
+ if (block->target_end > UINT_MAX) {
|
|
|
9ae3a8 |
/* The memory size is greater than 4G */
|
|
|
9ae3a8 |
info->d_class = ELFCLASS64;
|
|
|
9ae3a8 |
break;
|