diff mbox

[RFC,6/8,v3] target-i386: Add API to add extra memory mapping

Message ID 4EF0519E.4060801@cn.fujitsu.com
State New
Headers show

Commit Message

Wen Congyang Dec. 20, 2011, 9:13 a.m. UTC
Crash needs extra memory mapping to determine phys_base.

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
---
 cpu-all.h               |    2 ++
 target-i386/arch-dump.c |   44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 0 deletions(-)
diff mbox

Patch

diff --git a/cpu-all.h b/cpu-all.h
index 038934d..4d87d51 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -591,10 +591,12 @@  int cpu_write_elf64_note(Monitor *mon, int fd, CPUState *env, int cpuid,
                          target_phys_addr_t *offset);
 int cpu_write_elf32_note(Monitor *mon, int fd, CPUState *env, int cpuid,
                          target_phys_addr_t *offset);
+int cpu_add_extra_memory_mapping(Monitor *mon, MemoryMappingList *list);
 #else
 #define cpu_get_memory_mapping(list, env)
 #define cpu_write_elf64_note(mon, fd, env, cpuid, offset) ({ -1; })
 #define cpu_write_elf32_note(mon, fd, env, cpuid, offset) ({ -1; })
+#define cpu_add_extra_memory_mapping(mon, list) ({ 0; })
 #endif
 
 #endif /* CPU_ALL_H */
diff --git a/target-i386/arch-dump.c b/target-i386/arch-dump.c
index 4ecb981..2410c6a 100644
--- a/target-i386/arch-dump.c
+++ b/target-i386/arch-dump.c
@@ -498,3 +498,47 @@  int cpu_write_elf32_note(Monitor *mon, int fd, CPUState *env, int cpuid,
 {
     return x86_write_elf32_note(mon, fd, env, cpuid, offset);
 }
+
+/* This function is copied from crash */
+static target_ulong get_phys_base_addr(CPUState *env, target_ulong *base_vaddr)
+{
+    int i;
+    target_ulong kernel_base = -1;
+    target_ulong last, mask;
+
+    for (i = 30, last = -1; (kernel_base == -1) && (i >= 20); i--) {
+        mask = ~((1LL << i) - 1);
+        *base_vaddr = env->idt.base & mask;
+        if (*base_vaddr == last) {
+            continue;
+        }
+
+        kernel_base = cpu_get_phys_page_debug(env, *base_vaddr);
+        last = *base_vaddr;
+    }
+
+    return kernel_base;
+}
+
+int cpu_add_extra_memory_mapping(Monitor *mon, MemoryMappingList *list)
+{
+#ifdef TARGET_X86_64
+    target_phys_addr_t kernel_base = -1;
+    target_ulong base_vaddr;
+    bool lma = !!(first_cpu->hflags & HF_LMA_MASK);
+
+    if (!lma) {
+        return 0;
+    }
+
+    kernel_base = get_phys_base_addr(first_cpu, &base_vaddr);
+    if (kernel_base == -1) {
+        monitor_printf(mon, "dump: can not get phys_base\n");
+        return -1;
+    }
+
+    create_new_memory_mapping_head(list, kernel_base, base_vaddr,
+                                   TARGET_PAGE_SIZE);
+#endif
+    return 0;
+}