>From ebb598aa224f5dca7837b23f2536b83701ab070d Mon Sep 17 00:00:00 2001
From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
Date: Tue, 17 Jul 2012 13:05:47 +0800
Subject: [PATCH] add support to qemu memory dump

---
 defs.h    |   18 +++++-
 filesys.c |   12 +++-
 kernel.c  |    2 +
 main.c    |   14 ++++
 memory.c  |   30 +++++++---
 netdump.c |  204 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 netdump.h |   23 +++++++
 task.c    |   12 +++-
 tools.c   |    4 +-
 x86_64.c  |    2 +-
 10 files changed, 295 insertions(+), 26 deletions(-)

diff --git a/defs.h b/defs.h
index caa87c0..390f852 100755
--- a/defs.h
+++ b/defs.h
@@ -250,6 +250,7 @@ struct number_option {
 #define NETDUMP_DUMPFILE()  (pc->flags & (NETDUMP|REM_NETDUMP))
 #define DISKDUMP_DUMPFILE() (pc->flags & DISKDUMP)
 #define KDUMP_DUMPFILE()    (pc->flags & KDUMP)
+#define QEMU_MEM_DUMP_DUMPFILE() ((pc->flags & NETDUMP) && (pc->flags2 & QEMU_MEM_DUMP))
 #define XENDUMP_DUMPFILE()  (pc->flags & XENDUMP)
 #define XEN_HYPER_MODE()    (pc->flags & XEN_HYPER)
 #define SYSRQ_TASK(X)       ((pc->flags & SYSRQ) && is_task_active(X))
@@ -260,7 +261,7 @@ struct number_option {
 
 #define NETDUMP_LOCAL    (0x1)  /* netdump_data flags */
 #define NETDUMP_REMOTE   (0x2)  
-#define VMCORE_VALID()   (nd->flags & (NETDUMP_LOCAL|NETDUMP_REMOTE|KDUMP_LOCAL))
+#define VMCORE_VALID()   (nd->flags & (NETDUMP_LOCAL|NETDUMP_REMOTE|KDUMP_LOCAL|QEMU_MEM_DUMP_LOCAL))
 #define NETDUMP_ELF32    (0x4)
 #define NETDUMP_ELF64    (0x8)
 #define PARTIAL_DUMP    (0x10)  /* netdump or diskdump */
@@ -270,11 +271,14 @@ struct number_option {
 #define KCORE_LOCAL    (0x100)     
 #define KCORE_ELF32    (0x200)
 #define KCORE_ELF64    (0x400)
+#define QEMU_MEM_DUMP_LOCAL (0x800)
+#define QEMU_MEM_DUMP_ELF32 (0x1000)
+#define QEMU_MEM_DUMP_ELF64 (0x2000)
 #define KVMDUMP_LOCAL    (0x1)
 #define KVMDUMP_VALID()  (kvm->flags & (KVMDUMP_LOCAL))
 
 #define DUMPFILE_FORMAT(flags) ((flags) & \
-		        (NETDUMP_ELF32|NETDUMP_ELF64|KDUMP_ELF32|KDUMP_ELF64))
+		        (NETDUMP_ELF32|NETDUMP_ELF64|KDUMP_ELF32|KDUMP_ELF64|QEMU_MEM_DUMP_ELF32|QEMU_MEM_DUMP_ELF64))
 
 #define DISKDUMP_LOCAL      (0x1)
 #define KDUMP_CMPRS_LOCAL   (0x2)
@@ -484,6 +488,7 @@ struct program_context {
 #define ERASEINFO_DATA (0x10ULL)
 #define GDB_CMD_MODE   (0x20ULL)
 #define LIVE_DUMP      (0x40ULL)
+#define QEMU_MEM_DUMP  (0x80ULL)
 #define FLAT_FORMAT() (pc->flags2 & FLAT)
 #define ELF_NOTES_VALID() (pc->flags2 & ELF_NOTES)
 	char *cleanup;
@@ -4982,6 +4987,15 @@ int proc_kcore_init(FILE *);
 int read_proc_kcore(int, void *, int, ulong, physaddr_t);
 int write_proc_kcore(int, void *, int, ulong, physaddr_t);
 int kcore_memory_dump(FILE *);
+struct vmcore_data *get_qemu_mem_dump_vmcore_data(void);
+int is_qemu_mem_dump(char *, ulong);
+int qemu_mem_dump_init(char *, FILE *);
+ulong get_qemu_mem_dump_panic_task(void);
+uint qemu_mem_dump_page_size(void);
+int qemu_mem_dump_free_memory(void);
+int qemu_mem_dump_memory_used(void);
+int qemu_mem_dump_memory_dump(FILE *);
+void get_qemu_mem_dump_regs(struct bt_info *, ulong *, ulong *);
 
 /*
  *  diskdump.c
diff --git a/filesys.c b/filesys.c
index 6fc7d42..765f97e 100755
--- a/filesys.c
+++ b/filesys.c
@@ -212,9 +212,15 @@ memory_source_init(void)
 				pc->dumpfile);
 	
                 if (pc->flags & NETDUMP) {
-                        if (!netdump_init(pc->dumpfile, fp))
-                                error(FATAL, "%s: initialization failed\n",
-                                        pc->dumpfile);
+			if (pc->flags2 & QEMU_MEM_DUMP) {
+				if (!qemu_mem_dump_init(pc->dumpfile, fp))
+                                	error(FATAL, "%s: initialization failed\n",
+                                        	pc->dumpfile);
+			} else {
+				if (!netdump_init(pc->dumpfile, fp))
+                                	error(FATAL, "%s: initialization failed\n",
+                                        	pc->dumpfile);
+			}
 		} else if (pc->flags & KDUMP) {
                         if (!kdump_init(pc->dumpfile, fp))
                                 error(FATAL, "%s: initialization failed\n",
diff --git a/kernel.c b/kernel.c
index e2707d3..a5c49a7 100755
--- a/kernel.c
+++ b/kernel.c
@@ -2382,6 +2382,8 @@ back_trace(struct bt_info *bt)
                 get_netdump_regs(bt, &eip, &esp);
 	else if (KDUMP_DUMPFILE())
                 get_kdump_regs(bt, &eip, &esp);
+	else if (QEMU_MEM_DUMP_DUMPFILE())
+		get_qemu_mem_dump_regs(bt, &eip, &esp);
 	else if (DISKDUMP_DUMPFILE())
                 get_diskdump_regs(bt, &eip, &esp);
 	else if (KVMDUMP_DUMPFILE())
diff --git a/main.c b/main.c
index 7b06cc9..bf483f9 100755
--- a/main.c
+++ b/main.c
@@ -476,6 +476,18 @@ main(int argc, char **argv)
                                 pc->readmem = read_kdump;
                                 pc->writemem = write_kdump;
 
+                        } else if (is_qemu_mem_dump(argv[optind], QEMU_MEM_DUMP_LOCAL)) {
+                                if (pc->flags & MEMORY_SOURCES) {
+                                        error(INFO,
+                                            "too many dumpfile arguments\n");
+                                        program_usage(SHORT_FORM);
+                                }
+                                pc->flags |= NETDUMP;
+				pc->flags2 |= QEMU_MEM_DUMP;
+                                pc->dumpfile = argv[optind];
+                                pc->readmem = read_netdump;
+                                pc->writemem = write_netdump;
+
                         } else if (is_kvmdump(argv[optind])) {
                                 if (pc->flags & MEMORY_SOURCES) {
                                         error(INFO,
@@ -1315,6 +1327,8 @@ dump_program_context(void)
 		fprintf(fp, "%sREMOTE_DAEMON", others++ ? "|" : "");
 	if (pc->flags2 & LIVE_DUMP)
 		fprintf(fp, "%sLIVE_DUMP", others++ ? "|" : "");
+	if (pc->flags2 & QEMU_MEM_DUMP)
+		fprintf(fp, "%sQEMU_MEM_DUMP", others++ ? "|" : "");
 	fprintf(fp, ")\n");
 
 	fprintf(fp, "         namelist: %s\n", pc->namelist);
diff --git a/memory.c b/memory.c
index 703e623..e8b801d 100755
--- a/memory.c
+++ b/memory.c
@@ -2029,7 +2029,6 @@ readmem(ulonglong addr, int memtype, void *buffer, long size,
 
 			break;
 		}
-
 		/* 
 		 *  Compute bytes till end of page.
 		 */
@@ -14289,7 +14288,10 @@ memory_page_size(void)
 		break;
 
 	case NETDUMP:
-		psz = netdump_page_size();
+		if (pc->flags2 & QEMU_MEM_DUMP)
+			psz = qemu_mem_dump_page_size();
+		else
+			psz = netdump_page_size();
 		break;
 
 	case MCLXCD:
@@ -14520,8 +14522,12 @@ dumpfile_memory(int cmd)
 	case DUMPFILE_MEM_USED:
                 if (REMOTE_DUMPFILE()) 
                         retval = remote_memory_used();
-		else if (pc->flags & NETDUMP)
-        		retval = netdump_memory_used();
+		else if (pc->flags & NETDUMP) {
+			if (pc->flags2 & QEMU_MEM_DUMP)
+				retval = qemu_mem_dump_memory_used();
+			else
+        			retval = netdump_memory_used();
+		}
 		else if (pc->flags & KDUMP)
         		retval = kdump_memory_used();
 		else if (pc->flags & XENDUMP)
@@ -14543,8 +14549,12 @@ dumpfile_memory(int cmd)
 	case DUMPFILE_FREE_MEM:
                 if (REMOTE_DUMPFILE())
                         retval = remote_free_memory();
-                else if (pc->flags & NETDUMP)
-			retval = netdump_free_memory();
+                else if (pc->flags & NETDUMP) {
+			if (pc->flags2 & QEMU_MEM_DUMP)
+				retval = qemu_mem_dump_free_memory();
+			else
+				retval = netdump_free_memory();
+		}
                 else if (pc->flags & KDUMP)
 			retval = kdump_free_memory();
                 else if (pc->flags & XENDUMP)
@@ -14566,8 +14576,12 @@ dumpfile_memory(int cmd)
 	case DUMPFILE_MEM_DUMP:
 		if (REMOTE_DUMPFILE())
                         retval = remote_memory_dump(0);
-                else if (pc->flags & NETDUMP) 
-                        retval = netdump_memory_dump(fp);
+                else if (pc->flags & NETDUMP) {
+			if (pc->flags2 & QEMU_MEM_DUMP)
+				retval = qemu_mem_dump_memory_dump(fp);
+			else
+                        	retval = netdump_memory_dump(fp);
+		}
                 else if (pc->flags & KDUMP) 
                         retval = kdump_memory_dump(fp);
                 else if (pc->flags & XENDUMP) 
diff --git a/netdump.c b/netdump.c
index 9fecbf3..c6c616c 100644
--- a/netdump.c
+++ b/netdump.c
@@ -42,6 +42,8 @@ static int proc_kcore_init_32(FILE *fp);
 static int proc_kcore_init_64(FILE *fp);
 static char *get_regs_from_note(char *, ulong *, ulong *);
 static void kdump_get_osrelease(void);
+static int check_elf_note(char *, int , char *, int);
+
 
 #define ELFSTORE 1
 #define ELFREAD  0
@@ -205,8 +207,12 @@ is_netdump(char *file, ulong source_query)
                 size = (size_t)load32->p_offset;
 
 		if ((load32->p_offset & (MIN_PAGE_SIZE-1)) &&
-		    (load32->p_align == 0))
-                	tmp_flags |= KDUMP_ELF32;
+		    (load32->p_align == 0)) {
+			if (check_elf_note(eheader, fd, file, 0))
+				tmp_flags |= QEMU_MEM_DUMP_ELF32;
+                	else
+				tmp_flags |= KDUMP_ELF32;
+		}
 		else
                 	tmp_flags |= NETDUMP_ELF32;
 	} else if ((elf64->e_ident[EI_CLASS] == ELFCLASS64) &&
@@ -259,7 +265,10 @@ is_netdump(char *file, ulong source_query)
                 size = (size_t)load64->p_offset;
 		if ((load64->p_offset & (MIN_PAGE_SIZE-1)) &&
 		    (load64->p_align == 0))
-                	tmp_flags |= KDUMP_ELF64;
+			if (check_elf_note(eheader, fd, file, 0))
+				tmp_flags |= QEMU_MEM_DUMP_ELF64;
+                	else
+				tmp_flags |= KDUMP_ELF64;
 		else
                 	tmp_flags |= NETDUMP_ELF64;
 	} else {
@@ -292,6 +301,13 @@ is_netdump(char *file, ulong source_query)
 			break;
 		else
 			goto bailout;
+
+	case QEMU_MEM_DUMP_ELF32:
+	case QEMU_MEM_DUMP_ELF64:
+		if (source_query & QEMU_MEM_DUMP_LOCAL)
+			break;
+		else
+			goto bailout;
 	}
 
 	if ((tmp_elf_header = (char *)malloc(size)) == NULL) {
@@ -327,6 +343,7 @@ is_netdump(char *file, ulong source_query)
 	{
 	case NETDUMP_ELF32:
 	case KDUMP_ELF32:
+	case QEMU_MEM_DUMP_ELF32:
 		nd->header_size = load32->p_offset;
         	nd->elf32 = (Elf32_Ehdr *)&nd->elf_header[0];
 		nd->num_pt_load_segments = nd->elf32->e_phnum - 1;
@@ -356,6 +373,7 @@ is_netdump(char *file, ulong source_query)
 
 	case NETDUMP_ELF64:
 	case KDUMP_ELF64:
+	case QEMU_MEM_DUMP_ELF64:
                 nd->header_size = load64->p_offset;
                 nd->elf64 = (Elf64_Ehdr *)&nd->elf_header[0];
 		nd->num_pt_load_segments = nd->elf64->e_phnum - 1;
@@ -521,6 +539,8 @@ read_netdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
 	case NETDUMP_ELF64:
 	case KDUMP_ELF32:
 	case KDUMP_ELF64:
+	case QEMU_MEM_DUMP_ELF32:
+	case QEMU_MEM_DUMP_ELF64:
 		if (nd->num_pt_load_segments == 1) {
 			offset = (off_t)paddr + (off_t)nd->header_size -
 				(off_t)nd->pt_load_segments[0].phys_start;
@@ -611,6 +631,8 @@ write_netdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
 	case NETDUMP_ELF64:
 	case KDUMP_ELF32:
 	case KDUMP_ELF64:
+	case QEMU_MEM_DUMP_ELF32:
+	case QEMU_MEM_DUMP_ELF64:
 		if (nd->num_pt_load_segments == 1) {
 			offset = (off_t)paddr + (off_t)nd->header_size;
 			break;
@@ -744,6 +766,8 @@ get_netdump_panic_task(void)
 
         case KDUMP_ELF32:
         case KDUMP_ELF64:
+	case QEMU_MEM_DUMP_ELF32:
+	case QEMU_MEM_DUMP_ELF64:
 		crashing_cpu = -1;
 		if (kernel_symbol_exists("crashing_cpu")) {
 			get_symbol_data("crashing_cpu", sizeof(int), &i);
@@ -932,6 +956,12 @@ netdump_memory_dump(FILE *fp)
 		netdump_print("%sKDUMP_ELF64", others++ ? "|" : "");
 	if (nd->flags & PARTIAL_DUMP)
 		netdump_print("%sPARTIAL_DUMP", others++ ? "|" : "");
+	if (nd->flags & QEMU_MEM_DUMP_LOCAL)
+		netdump_print("%sQEMU_MEM_DUMP_LOCAL", others++ ? "|" : "");
+	if (nd->flags & QEMU_MEM_DUMP_ELF32)
+		netdump_print("%sQEMU_MEM_DUMP_ELF32", others++ ? "|" : "");
+	if (nd->flags & QEMU_MEM_DUMP_ELF64)
+		netdump_print("%sQEMU_MEM_DUMP_ELF64", others++ ? "|" : "");
 	netdump_print(") %s\n", FLAT_FORMAT() ? "[FLAT]" : "");
 	if ((pc->flags & RUNTIME) && symbol_exists("dump_level")) {
 		int dump_level;
@@ -1064,6 +1094,7 @@ netdump_memory_dump(FILE *fp)
 	{
 	case NETDUMP_ELF32:
 	case KDUMP_ELF32:
+	case QEMU_MEM_DUMP_ELF32:
 		dump_Elf32_Ehdr(nd->elf32);
 		dump_Elf32_Phdr(nd->notes32, ELFREAD);
                 for (i = 0; i < nd->num_pt_load_segments; i++) 
@@ -1078,6 +1109,7 @@ netdump_memory_dump(FILE *fp)
 
 	case NETDUMP_ELF64:
 	case KDUMP_ELF64:
+	case QEMU_MEM_DUMP_ELF64:
 		dump_Elf64_Ehdr(nd->elf64);
 		dump_Elf64_Phdr(nd->notes64, ELFREAD);
                 for (i = 0; i < nd->num_pt_load_segments; i++)
@@ -2290,7 +2322,7 @@ get_netdump_regs_x86_64(struct bt_info *bt, ulong *ripp, ulong *rspp)
         if (is_task_active(bt->task)) 
                 bt->flags |= BT_DUMPFILE_SEARCH;
 
-	if (((NETDUMP_DUMPFILE() || KDUMP_DUMPFILE()) &&
+	if (((NETDUMP_DUMPFILE() || KDUMP_DUMPFILE() || QEMU_MEM_DUMP_DUMPFILE()) &&
    	      VALID_STRUCT(user_regs_struct) && (bt->task == tt->panic_task)) ||
 	      (KDUMP_DUMPFILE() && (kt->flags & DWARF_UNWIND) && 
 	      (bt->flags & BT_DUMPFILE_SEARCH))) {
@@ -2321,7 +2353,7 @@ get_netdump_regs_x86_64(struct bt_info *bt, ulong *ripp, ulong *rspp)
                 		ULONG(user_regs + rsp_offset),
                 		ULONG(user_regs + rip_offset));
 
-		if (KDUMP_DUMPFILE()) {
+		if (KDUMP_DUMPFILE() || QEMU_MEM_DUMP_DUMPFILE()) {
 			*rspp = ULONG(user_regs + rsp_offset);
 			*ripp = ULONG(user_regs + rip_offset);
 
@@ -2757,8 +2789,9 @@ kdump_page_size(void)
         if (!VMCORE_VALID())
                 return 0;
 
-	if (!(pagesz = nd->page_size))
+	if (!(pagesz = nd->page_size)) {
                 pagesz = (uint)getpagesize();
+	}
 
         return pagesz;
 }
@@ -3475,3 +3508,162 @@ kdump_get_osrelease(void)
 	} else 
 		pc->flags2 &= ~GET_OSRELEASE;
 }
+
+int
+is_qemu_mem_dump(char *file, ulong source_query)
+{
+	return is_netdump(file, source_query);
+}
+
+int
+qemu_mem_dump_init(char *unused, FILE *fptr)
+{
+	return netdump_init(unused, fptr);
+}
+
+ulong 
+get_qemu_mem_dump_panic_task(void)
+{
+	return get_netdump_panic_task();
+}
+
+uint
+qemu_mem_dump_page_size()
+{
+	uint pagesz;
+
+	if (!VMCORE_VALID())
+		return 0;
+
+	if (!(pagesz = nd->page_size))
+		pagesz = (uint)getpagesize();
+
+	return pagesz;
+}
+
+int
+qemu_mem_dump_free_memory()
+{
+	return netdump_free_memory();
+}
+
+int
+qemu_mem_dump_memory_used()
+{
+	return netdump_memory_used();
+}
+
+int
+qemu_mem_dump_memory_dump(FILE *fp)
+{
+	return netdump_memory_dump(fp);
+}
+
+void
+get_qemu_mem_dump_regs(struct bt_info *bt, ulong *eip, ulong *esp)
+{
+	get_netdump_regs(bt, eip, esp);
+}
+
+struct vmcore_data *
+get_qemu_mem_dump_vmcore_data(void)
+{
+	if (!VMCORE_VALID() || !QEMU_MEM_DUMP_DUMPFILE())
+		return NULL;
+
+	return &vmcore_data;
+}
+
+static int
+check_elf_note(char *eheader, int fd, char *file, int machine_type)
+{
+	int qemu_memory_dump;
+	Elf32_Phdr *load32;
+	Elf64_Phdr *load64;
+	ulong offset;
+	ulong filesz;
+	char *pnotes;
+	char buf[BUFSIZE];
+	char *tmp_note;
+	Elf32_Nhdr *tmp_note32;
+	Elf64_Nhdr *tmp_note64;
+	uint32_t namesz, descsz, type;
+	char *name, *desc;
+	int num;
+
+	qemu_memory_dump  = FALSE;
+
+	load32 = (Elf32_Phdr *)&eheader[sizeof(Elf32_Ehdr)];
+	load64 = (Elf64_Phdr *)&eheader[sizeof(Elf64_Phdr)];
+
+	if (machine_type == 0) {
+		if (!(load32->p_type == PT_NOTE))
+			return qemu_memory_dump;
+
+		offset = load32->p_offset;
+		filesz = load32->p_filesz;
+	} else {
+		if (!(load64->p_type == PT_NOTE))
+			return qemu_memory_dump;
+
+		offset = load64->p_offset;
+		filesz = load64->p_filesz;
+	}
+
+	if ((pnotes = (char *)malloc(filesz)) == NULL) {
+		fprintf(stderr, "cannot malloc elf note buffer\n");
+		clean_exit(1);
+	}
+
+	if (FLAT_FORMAT()) {
+		if (!read_flattened_format(fd, offset, pnotes, filesz)) {
+			free(pnotes);
+			return qemu_memory_dump;
+		}
+	} else {
+		if (lseek(fd, offset, SEEK_SET) != offset) {
+			sprintf(buf, "%s: lseek", file);
+			perror(buf);
+			return qemu_memory_dump;
+		}
+		if (read(fd, pnotes, filesz) != filesz) {
+			sprintf(buf, "%s: read", file);
+			perror(buf);
+			free(pnotes);
+			return qemu_memory_dump;
+		}
+	}
+
+	tmp_note = pnotes;
+	num = 0;
+
+	while (tmp_note < pnotes + filesz)
+	{
+		if (machine_type == 0) {
+			tmp_note32 = (Elf32_Nhdr *)tmp_note;
+			namesz = tmp_note32->n_namesz;
+			descsz = tmp_note32->n_descsz;
+			type = tmp_note32->n_type;
+
+			name = (char *)tmp_note + ((sizeof(Elf32_Nhdr) + 3) / 4) * 4;
+		} else {
+			tmp_note64 = (Elf64_Nhdr *)tmp_note;
+			namesz = tmp_note64->n_namesz;
+			descsz = tmp_note64->n_descsz;
+			type = tmp_note64->n_type;
+
+			name = (char *)tmp_note + ((sizeof(Elf64_Nhdr) + 3) / 4) * 4;
+		}
+		desc = name + ((namesz + 3) / 4) * 4;
+
+		if (STREQ(name, "QEMU")) {
+			qemu_memory_dump = TRUE;
+			nd->nt_qemu_percpu[num] = desc;
+			num++;
+		}
+		
+		tmp_note = desc + (descsz + 3) / 4 * 4;
+	}
+
+	return qemu_memory_dump;
+}
diff --git a/netdump.h b/netdump.h
index 2e296ad..ced0451 100644
--- a/netdump.h
+++ b/netdump.h
@@ -68,6 +68,7 @@ struct vmcore_data {
 	ulong switch_stack;
 	uint num_prstatus_notes;
 	void *nt_prstatus_percpu[NR_CPUS];
+	void *nt_qemu_percpu[NR_CPUS];
 	struct xen_kdump_data *xen_kdump_data;
 	void *vmcoreinfo;
 	uint size_vmcoreinfo;
@@ -172,3 +173,25 @@ struct proc_kcore_data {
 	Elf32_Phdr *load32;
 };
 
+struct QEMUCPUSegment {
+    uint32_t selector;
+    uint32_t limit;
+    uint32_t flags;
+    uint32_t pad;
+    uint64_t base;
+};
+
+typedef struct QEMUCPUSegment QEMUCPUSegment;
+
+struct QEMUCPUState {
+    uint32_t version;
+    uint32_t size;
+    uint64_t rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp;
+    uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
+    uint64_t rip, rflags;
+    QEMUCPUSegment cs, ds, es, fs, gs, ss;
+    QEMUCPUSegment ldt, tr, gdt, idt;
+    uint64_t cr[5];
+};
+
+typedef struct QEMUCPUState QEMUCPUState;
diff --git a/task.c b/task.c
index 30de29a..62ea4c0 100755
--- a/task.c
+++ b/task.c
@@ -463,7 +463,7 @@ task_init(void)
 		tt->this_task = pid_to_task(active_pid);
 	}
 	else {
-		if (KDUMP_DUMPFILE())
+		if (KDUMP_DUMPFILE() || QEMU_MEM_DUMP_DUMPFILE())
 			map_cpus_to_prstatus();
 		else if (ELF_NOTES_VALID() && DISKDUMP_DUMPFILE())
 			map_cpus_to_prstatus_kdump_cmprs();
@@ -6027,8 +6027,12 @@ get_dumpfile_panic_task(void)
 	ulong task;
 
 	if (NETDUMP_DUMPFILE()) {
-		task = pc->flags & REM_NETDUMP ?
-			tt->panic_task : get_netdump_panic_task();
+		if (QEMU_MEM_DUMP_DUMPFILE()) {
+			task = get_qemu_mem_dump_panic_task();
+		} else {
+			task = pc->flags & REM_NETDUMP ?
+				tt->panic_task : get_netdump_panic_task();
+		}
 		if (task) 
 			return task;
 	} else if (KDUMP_DUMPFILE()) {
@@ -6100,7 +6104,7 @@ populate_panic_threads(void)
 	}
 
 	if (!found && !(kt->flags & SMP) &&
-	    (LKCD_DUMPFILE() || NETDUMP_DUMPFILE() || 
+	    (LKCD_DUMPFILE() || NETDUMP_DUMPFILE() || QEMU_MEM_DUMP_DUMPFILE() ||
 	     KDUMP_DUMPFILE() || DISKDUMP_DUMPFILE() || KVMDUMP_DUMPFILE())) 
 		tt->panic_threads[0] = get_dumpfile_panic_task();
 }
diff --git a/tools.c b/tools.c
index 77f145e..48a14d3 100755
--- a/tools.c
+++ b/tools.c
@@ -5313,7 +5313,7 @@ machine_type_mismatch(char *file, char *e_machine, char *alt, ulong query)
 	if (machine_type(e_machine) || machine_type(alt))
 		return FALSE;
 
-	if (query == KDUMP_LOCAL)  /* already printed by NETDUMP_LOCAL */
+	if (query == KDUMP_LOCAL || query == QEMU_MEM_DUMP_LOCAL)  /* already printed by NETDUMP_LOCAL */
 		return TRUE;
 
 	error(WARNING, "machine type mismatch:\n");
@@ -5425,7 +5425,7 @@ endian_mismatch(char *file, char dumpfile_endian, ulong query)
 		break;
 	}
 
-	if (query == KDUMP_LOCAL)  /* already printed by NETDUMP_LOCAL */
+	if (query == KDUMP_LOCAL || query == QEMU_MEM_DUMP_LOCAL)  /* already printed by NETDUMP_LOCAL */
 		return TRUE;
 
         error(WARNING, "endian mismatch:\n");
diff --git a/x86_64.c b/x86_64.c
index 3ceae3e..64a3160 100755
--- a/x86_64.c
+++ b/x86_64.c
@@ -5865,7 +5865,7 @@ x86_64_calc_phys_base(void)
 		return;
 	}
 
-	if ((vd = get_kdump_vmcore_data())) {
+	if ((vd = get_kdump_vmcore_data()) || (vd = get_qemu_mem_dump_vmcore_data())) {
                 for (i = 0; i < vd->num_pt_load_segments; i++) {
 			phdr = vd->load64 + i;
 			if ((phdr->p_vaddr >= __START_KERNEL_map) &&
-- 
1.7.1

