[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC][PATCH 1/8 v3] Add API to create memory mapping list
From: |
Wen Congyang |
Subject: |
[Qemu-devel] [RFC][PATCH 1/8 v3] Add API to create memory mapping list |
Date: |
Tue, 20 Dec 2011 17:07:31 +0800 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.9) Gecko/20100413 Fedora/3.0.4-2.fc13 Thunderbird/3.0.4 |
The memory mapping list stores virtual address and physical address mapping.
The folloing patch will use this information to create PT_LOAD in the vmcore.
Signed-off-by: Wen Congyang <address@hidden>
---
Makefile.target | 1 +
memory_mapping.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
memory_mapping.h | 38 ++++++++++++++++
3 files changed, 169 insertions(+), 0 deletions(-)
create mode 100644 memory_mapping.c
create mode 100644 memory_mapping.h
diff --git a/Makefile.target b/Makefile.target
index 3261383..0d5286e 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -197,6 +197,7 @@ 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_mapping.o
LIBS+=-lz
QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
diff --git a/memory_mapping.c b/memory_mapping.c
new file mode 100644
index 0000000..d83b7d7
--- /dev/null
+++ b/memory_mapping.c
@@ -0,0 +1,130 @@
+/*
+ * QEMU memory mapping
+ *
+ * Copyright Fujitsu, Corp. 2011
+ *
+ * Authors:
+ * Wen Congyang <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "cpu.h"
+#include "cpu-all.h"
+#include "memory_mapping.h"
+
+static MemoryMapping *last_mapping;
+
+static void create_new_memory_mapping(MemoryMappingList *list,
+ target_phys_addr_t phys_addr,
+ target_phys_addr_t virt_addr,
+ ram_addr_t length)
+{
+ MemoryMapping *memory_mapping, *p;
+
+ memory_mapping = g_malloc(sizeof(MemoryMapping));
+ memory_mapping->phys_addr = phys_addr;
+ memory_mapping->virt_addr = virt_addr;
+ memory_mapping->length = length;
+ last_mapping = memory_mapping;
+ list->num++;
+ QTAILQ_FOREACH(p, &list->head, next) {
+ if (p->phys_addr >= memory_mapping->phys_addr) {
+ QTAILQ_INSERT_BEFORE(p, memory_mapping, next);
+ return;
+ }
+ }
+ QTAILQ_INSERT_TAIL(&list->head, memory_mapping, next);
+ return;
+}
+
+void create_new_memory_mapping_head(MemoryMappingList *list,
+ target_phys_addr_t phys_addr,
+ target_phys_addr_t virt_addr,
+ ram_addr_t length)
+{
+ MemoryMapping *memory_mapping;
+
+ memory_mapping = g_malloc(sizeof(MemoryMapping));
+ memory_mapping->phys_addr = phys_addr;
+ memory_mapping->virt_addr = virt_addr;
+ memory_mapping->length = length;
+ last_mapping = memory_mapping;
+ list->num++;
+ QTAILQ_INSERT_HEAD(&list->head, memory_mapping, next);
+ return;
+}
+
+void add_to_memory_mapping(MemoryMappingList *list,
+ target_phys_addr_t phys_addr,
+ target_phys_addr_t virt_addr,
+ ram_addr_t length)
+{
+ MemoryMapping *memory_mapping;
+
+ if (QTAILQ_EMPTY(&list->head)) {
+ create_new_memory_mapping(list, phys_addr, virt_addr, length);
+ return;
+ }
+
+ if (last_mapping) {
+ if ((phys_addr == (last_mapping->phys_addr + last_mapping->length)) &&
+ (virt_addr == (last_mapping->virt_addr + last_mapping->length))) {
+ last_mapping->length += length;
+ return;
+ }
+ }
+
+ QTAILQ_FOREACH(memory_mapping, &list->head, next) {
+ last_mapping = memory_mapping;
+ if ((phys_addr == (last_mapping->phys_addr + last_mapping->length)) &&
+ (virt_addr == (last_mapping->virt_addr + last_mapping->length))) {
+ last_mapping->length += length;
+ return;
+ }
+
+ if (!(phys_addr >= (last_mapping->phys_addr)) ||
+ !(phys_addr < (last_mapping->phys_addr + last_mapping->length))) {
+ /* last_mapping does not contain this region */
+ continue;
+ }
+ if (!(virt_addr >= (last_mapping->virt_addr)) ||
+ !(virt_addr < (last_mapping->virt_addr + last_mapping->length))) {
+ /* last_mapping does not contain this region */
+ continue;
+ }
+ if ((virt_addr - last_mapping->virt_addr) !=
+ (phys_addr - last_mapping->phys_addr)) {
+ /*
+ * last_mapping contains this region, but we should create another
+ * mapping region.
+ */
+ break;
+ }
+
+ /* merge this region into last_mapping */
+ if ((virt_addr + length) >
+ (last_mapping->virt_addr + last_mapping->length)) {
+ last_mapping->length = virt_addr + length -
last_mapping->virt_addr;
+ }
+ return;
+ }
+
+ /* this region can not be merged into any existed memory mapping. */
+ create_new_memory_mapping(list, phys_addr, virt_addr, length);
+ return;
+}
+
+void free_memory_mapping_list(MemoryMappingList *list)
+{
+ MemoryMapping *p, *q;
+
+ QTAILQ_FOREACH_SAFE(p, &list->head, next, q) {
+ QTAILQ_REMOVE(&list->head, p, next);
+ g_free(p);
+ }
+
+ list->num = 0;
+}
diff --git a/memory_mapping.h b/memory_mapping.h
new file mode 100644
index 0000000..a4b1532
--- /dev/null
+++ b/memory_mapping.h
@@ -0,0 +1,38 @@
+#ifndef MEMORY_MAPPING_H
+#define MEMORY_MAPPING_H
+
+#include "qemu-queue.h"
+
+typedef struct MemoryMapping {
+ target_phys_addr_t phys_addr;
+ target_ulong virt_addr;
+ ram_addr_t length;
+ QTAILQ_ENTRY(MemoryMapping) next;
+} MemoryMapping;
+
+typedef struct MemoryMappingList {
+ unsigned int num;
+ QTAILQ_HEAD(, MemoryMapping) head;
+} MemoryMappingList;
+
+/*
+ * crash needs some memory mapping should be at the head of the list. It will
+ * cause the list is not sorted. So the caller must add the special memory
+ * mapping after adding all the normal memory mapping into list.
+ */
+void create_new_memory_mapping_head(MemoryMappingList *list,
+ target_phys_addr_t phys_addr,
+ target_phys_addr_t virt_addr,
+ ram_addr_t length);
+/*
+ * add or merge the memory region into the memory mapping's list. The list is
+ * sorted by phys_addr.
+ */
+void add_to_memory_mapping(MemoryMappingList *list,
+ target_phys_addr_t phys_addr,
+ target_phys_addr_t virt_addr,
+ ram_addr_t length);
+
+void free_memory_mapping_list(MemoryMappingList *list);
+
+#endif
--
1.7.1
- [Qemu-devel] [RFC][PATCT 0/8 v3] dump memory when host pci device is used by guest, Wen Congyang, 2011/12/20
- [Qemu-devel] [RFC][PATCH 1/8 v3] Add API to create memory mapping list,
Wen Congyang <=
- [Qemu-devel] [RFC][PATCH 2/8 v3] Add API to check whether a physical address is I/O address, Wen Congyang, 2011/12/20
- [Qemu-devel] [RFC][PATCH 3/8 v3] target-i386: implement cpu_get_memory_mapping(), Wen Congyang, 2011/12/20
- [Qemu-devel] [RFC][PATCH 4/8 v3] Add API to get memory mapping, Wen Congyang, 2011/12/20
- [Qemu-devel] [RFC][PATCH 5/8 v3] target-i386: Add API to write elf notes to core file, Wen Congyang, 2011/12/20
- [Qemu-devel] [RFC][PATCH 6/8 v3] target-i386: Add API to add extra memory mapping, Wen Congyang, 2011/12/20
- [Qemu-devel] [RFC][PATCH 7/8 v3] target-i386: add API to get dump info, Wen Congyang, 2011/12/20
- [Qemu-devel] [RFC][PATCH 8/8 v3] introduce a new monitor command 'dump' to dump guest's memory, Wen Congyang, 2011/12/20