qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC][PATCH 05/16 v8] Add API to get memory mapping


From: Wen Congyang
Subject: [Qemu-devel] [RFC][PATCH 05/16 v8] Add API to get memory mapping
Date: Fri, 02 Mar 2012 18:18:23 +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

Add API to get all virtual address and physical address mapping.
If there is no virtual address for some physical address, the virtual
address is 0.

Signed-off-by: Wen Congyang <address@hidden>
---
 memory_mapping.c |   88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 memory_mapping.h |    8 +++++
 2 files changed, 96 insertions(+), 0 deletions(-)

diff --git a/memory_mapping.c b/memory_mapping.c
index 718f271..f74c5d0 100644
--- a/memory_mapping.c
+++ b/memory_mapping.c
@@ -164,3 +164,91 @@ void memory_mapping_list_init(MemoryMappingList *list)
     list->last_mapping = NULL;
     QTAILQ_INIT(&list->head);
 }
+
+int qemu_get_guest_memory_mapping(MemoryMappingList *list)
+{
+    CPUState *env;
+    MemoryMapping *memory_mapping;
+    RAMBlock *block;
+    ram_addr_t offset, length, m_length;
+    target_phys_addr_t m_phys_addr;
+    int ret;
+    bool paging_mode;
+
+#if defined(CONFIG_HAVE_GET_MEMORY_MAPPING)
+    paging_mode = cpu_paging_enabled(first_cpu);
+    if (paging_mode) {
+        for (env = first_cpu; env != NULL; env = env->next_cpu) {
+            ret = cpu_get_memory_mapping(list, env);
+            if (ret < 0) {
+                return -1;
+            }
+        }
+    }
+#else
+    return -2;
+#endif
+
+    /*
+     * some memory may be not in the memory mapping's list:
+     * 1. the guest doesn't use paging
+     * 2. the guest is in 2nd kernel, and the memory used by 1st kernel is not
+     *    in paging table
+     * add them into memory mapping's list
+     */
+    QLIST_FOREACH(block, &ram_list.blocks, next) {
+        offset = block->offset;
+        length = block->length;
+
+        if (!paging_mode) {
+            create_new_memory_mapping(list, offset, offset, length);
+            continue;
+        }
+
+        QTAILQ_FOREACH(memory_mapping, &list->head, next) {
+            m_phys_addr = memory_mapping->phys_addr;
+            m_length = memory_mapping->length;
+
+            if (offset + length <= m_phys_addr) {
+                /*
+                 * memory_mapping's list does not conatin the region
+                 * [offset, offset+length)
+                 */
+                create_new_memory_mapping(list, offset, 0, length);
+                length = 0;
+                break;
+            }
+
+            if (m_phys_addr + m_length <= offset) {
+                continue;
+            }
+
+            if (m_phys_addr > offset) {
+                /*
+                 * memory_mapping's list does not conatin the region
+                 * [offset, memory_mapping->phys_addr)
+                 */
+                create_new_memory_mapping(list, offset, 0,
+                                          m_phys_addr - offset);
+            }
+
+            if (offset + length <= m_phys_addr + m_length) {
+                length = 0;
+                break;
+            }
+
+            length -= m_phys_addr + m_length - offset;
+            offset = m_phys_addr + m_length;
+        }
+
+        if (length > 0) {
+            /*
+             * memory_mapping's list does not conatin the region
+             * [offset, memory_mapping->phys_addr)
+             */
+            create_new_memory_mapping(list, offset, 0, length);
+        }
+    }
+
+    return 0;
+}
diff --git a/memory_mapping.h b/memory_mapping.h
index 836b047..ebd7cf6 100644
--- a/memory_mapping.h
+++ b/memory_mapping.h
@@ -44,4 +44,12 @@ void memory_mapping_list_free(MemoryMappingList *list);
 
 void memory_mapping_list_init(MemoryMappingList *list);
 
+/*
+ * Return value:
+ *    0: success
+ *   -1: failed
+ *   -2: unsupported
+ */
+int qemu_get_guest_memory_mapping(MemoryMappingList *list);
+
 #endif
-- 
1.7.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]