|
|
9bac43 |
From a1b9c54811a4fc6797259dae98548229dba53d76 Mon Sep 17 00:00:00 2001
|
|
|
9bac43 |
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
|
|
|
9bac43 |
Date: Mon, 27 Nov 2017 22:51:07 +0100
|
|
|
9bac43 |
Subject: [PATCH 09/21] dump: update phys_base header field based on VMCOREINFO
|
|
|
9bac43 |
content
|
|
|
9bac43 |
MIME-Version: 1.0
|
|
|
9bac43 |
Content-Type: text/plain; charset=UTF-8
|
|
|
9bac43 |
Content-Transfer-Encoding: 8bit
|
|
|
9bac43 |
|
|
|
9bac43 |
RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
|
|
|
9bac43 |
Message-id: <20171127225111.24518-6-marcandre.lureau@redhat.com>
|
|
|
9bac43 |
Patchwork-id: 77928
|
|
|
9bac43 |
O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 5/9] dump: update phys_base header field based on VMCOREINFO content
|
|
|
9bac43 |
Bugzilla: 1398633
|
|
|
9bac43 |
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
9bac43 |
RH-Acked-by: Andrew Jones <drjones@redhat.com>
|
|
|
9bac43 |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9bac43 |
|
|
|
9bac43 |
If the guest note is VMCOREINFO, try to get phys_base from it.
|
|
|
9bac43 |
|
|
|
9bac43 |
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
|
|
9bac43 |
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
|
|
9bac43 |
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
|
9bac43 |
|
|
|
9bac43 |
(cherry picked from commit d9feb51772b4ade9700c7fa54529327a6c8183a7)
|
|
|
9bac43 |
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
|
|
9bac43 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9bac43 |
---
|
|
|
9bac43 |
docs/specs/vmcoreinfo.txt | 8 +++++++
|
|
|
9bac43 |
dump.c | 56 +++++++++++++++++++++++++++++++++++++++++++++--
|
|
|
9bac43 |
2 files changed, 62 insertions(+), 2 deletions(-)
|
|
|
9bac43 |
|
|
|
9bac43 |
diff --git a/docs/specs/vmcoreinfo.txt b/docs/specs/vmcoreinfo.txt
|
|
|
9bac43 |
index 2868a77..8212610 100644
|
|
|
9bac43 |
--- a/docs/specs/vmcoreinfo.txt
|
|
|
9bac43 |
+++ b/docs/specs/vmcoreinfo.txt
|
|
|
9bac43 |
@@ -39,3 +39,11 @@ qemu dumps.
|
|
|
9bac43 |
|
|
|
9bac43 |
The note format/class must be of the target bitness and the size must
|
|
|
9bac43 |
be less than 1Mb.
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+If the ELF note name is "VMCOREINFO", it is expected to be the Linux
|
|
|
9bac43 |
+vmcoreinfo note (see Documentation/ABI/testing/sysfs-kernel-vmcoreinfo
|
|
|
9bac43 |
+in Linux source). In this case, qemu dump code will read the content
|
|
|
9bac43 |
+as a key=value text file, looking for "NUMBER(phys_base)" key
|
|
|
9bac43 |
+value. The value is expected to be more accurate than architecture
|
|
|
9bac43 |
+guess of the value. This is useful for KASLR-enabled guest with
|
|
|
9bac43 |
+ancient tools not handling the VMCOREINFO note.
|
|
|
9bac43 |
diff --git a/dump.c b/dump.c
|
|
|
9bac43 |
index a4f175d..e3175d7 100644
|
|
|
9bac43 |
--- a/dump.c
|
|
|
9bac43 |
+++ b/dump.c
|
|
|
9bac43 |
@@ -780,6 +780,23 @@ static void get_note_sizes(DumpState *s, const void *note,
|
|
|
9bac43 |
}
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
+static bool note_name_equal(DumpState *s,
|
|
|
9bac43 |
+ const uint8_t *note, const char *name)
|
|
|
9bac43 |
+{
|
|
|
9bac43 |
+ int len = strlen(name) + 1;
|
|
|
9bac43 |
+ uint64_t head_size, name_size;
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ get_note_sizes(s, note, &head_size, &name_size, NULL);
|
|
|
9bac43 |
+ head_size = ROUND_UP(head_size, 4);
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ if (name_size != len ||
|
|
|
9bac43 |
+ memcmp(note + head_size, "VMCOREINFO", len)) {
|
|
|
9bac43 |
+ return false;
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ return true;
|
|
|
9bac43 |
+}
|
|
|
9bac43 |
+
|
|
|
9bac43 |
/* write common header, sub header and elf note to vmcore */
|
|
|
9bac43 |
static void create_header32(DumpState *s, Error **errp)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
@@ -1554,6 +1571,39 @@ static int64_t dump_calculate_size(DumpState *s)
|
|
|
9bac43 |
return total;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
+static void vmcoreinfo_update_phys_base(DumpState *s)
|
|
|
9bac43 |
+{
|
|
|
9bac43 |
+ uint64_t size, note_head_size, name_size, phys_base;
|
|
|
9bac43 |
+ char **lines;
|
|
|
9bac43 |
+ uint8_t *vmci;
|
|
|
9bac43 |
+ size_t i;
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ if (!note_name_equal(s, s->guest_note, "VMCOREINFO")) {
|
|
|
9bac43 |
+ return;
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ get_note_sizes(s, s->guest_note, ¬e_head_size, &name_size, &size);
|
|
|
9bac43 |
+ note_head_size = ROUND_UP(note_head_size, 4);
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ vmci = s->guest_note + note_head_size + ROUND_UP(name_size, 4);
|
|
|
9bac43 |
+ *(vmci + size) = '\0';
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ lines = g_strsplit((char *)vmci, "\n", -1);
|
|
|
9bac43 |
+ for (i = 0; lines[i]; i++) {
|
|
|
9bac43 |
+ if (g_str_has_prefix(lines[i], "NUMBER(phys_base)=")) {
|
|
|
9bac43 |
+ if (qemu_strtou64(lines[i] + 18, NULL, 16,
|
|
|
9bac43 |
+ &phys_base) < 0) {
|
|
|
9bac43 |
+ warn_report("Failed to read NUMBER(phys_base)=");
|
|
|
9bac43 |
+ } else {
|
|
|
9bac43 |
+ s->dump_info.phys_base = phys_base;
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+ break;
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ g_strfreev(lines);
|
|
|
9bac43 |
+}
|
|
|
9bac43 |
+
|
|
|
9bac43 |
static void dump_init(DumpState *s, int fd, bool has_format,
|
|
|
9bac43 |
DumpGuestMemoryFormat format, bool paging, bool has_filter,
|
|
|
9bac43 |
int64_t begin, int64_t length, Error **errp)
|
|
|
9bac43 |
@@ -1637,8 +1687,9 @@ static void dump_init(DumpState *s, int fd, bool has_format,
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
/*
|
|
|
9bac43 |
- * The goal of this block is to copy the guest note out of
|
|
|
9bac43 |
- * the guest. Failure to do so is not fatal for dumping.
|
|
|
9bac43 |
+ * The goal of this block is to (a) update the previously guessed
|
|
|
9bac43 |
+ * phys_base, (b) copy the guest note out of the guest.
|
|
|
9bac43 |
+ * Failure to do so is not fatal for dumping.
|
|
|
9bac43 |
*/
|
|
|
9bac43 |
if (vmci) {
|
|
|
9bac43 |
uint64_t addr, note_head_size, name_size, desc_size;
|
|
|
9bac43 |
@@ -1671,6 +1722,7 @@ static void dump_init(DumpState *s, int fd, bool has_format,
|
|
|
9bac43 |
g_free(s->guest_note);
|
|
|
9bac43 |
s->guest_note = NULL;
|
|
|
9bac43 |
} else {
|
|
|
9bac43 |
+ vmcoreinfo_update_phys_base(s);
|
|
|
9bac43 |
s->note_size += s->guest_note_size;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
}
|
|
|
9bac43 |
--
|
|
|
9bac43 |
1.8.3.1
|
|
|
9bac43 |
|