[PATCH] add support to "virsh dump-guest-memory"(qemu memory dump)

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

 



Hello Dave,

I made this patch to make crash can analyze core dump file created by
"virsh dump-guest-memory"(I will call it "qemu memory dump" below). In
my test(guest OS: RHEL6.2 x86 & x86_64), the patch works well with dump
files created by "qemu memory dump".

However, after some investigation, I think I need to discuss further
works with you.

The core dump created by qemu memory dump is similar to kdump. The
distinctness only focuses on note sections. The former one gets
note sections with a name called "QEMU".

1. Some registers' information stored in "CORE" note sections, needed
by crash, also stores in "QEMU" note sections. I think it's not
reasonable to replace them. What do you think?

2. Other registers which are only stored in "QEMU" note sections are
not directly used in crash. I will continue investigating the use of
these registers. And if you give some suggestion, it will be helpful.

--
--
Regards
Qiao Nuohan


>From ebb598aa224f5dca7837b23f2536b83701ab070d Mon Sep 17 00:00:00 2001
From: qiaonuohan <qiaonuohan@xxxxxxxxxxxxxx>
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

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux