qemu-devel
[Top][All Lists]
Advanced

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

[PATCH v2] TCG plugin API extension to read guest memory content by an a


From: Mikhail Tyutin
Subject: [PATCH v2] TCG plugin API extension to read guest memory content by an address
Date: Mon, 20 Feb 2023 11:13:33 +0000

TCG plugin API extension to read guest memory content. qemu_plugin_vcpu_read_phys_mem()

function can be used by TCG plugin inside of qemu_plugin_vcpu_mem_cb_t callback to adjust

received address according to internal memory mappings and read content of guest memory.

Works for both user-level and system-level emulation modes.

 

What's new in v2:

* Increment QEMU_PLUGIN_VERSION instead of custom define

* Example of qemu_plugin_vcpu_read_phys_mem() usage in memtrace.c

* Use cpu_memory_rw_debug() to get memory content in both user-level and

  system-level emulation modes

 

Signed-off-by: Mikhail Tyutin <m.tyutin@yadro.com>

Signed-off-by: Aleksey Titov <a.titov@yadro.com>

---

contrib/plugins/Makefile     |  1 +

contrib/plugins/memtrace.c   | 76 ++++++++++++++++++++++++++++++++++++

include/qemu/qemu-plugin.h   | 18 ++++++++-

plugins/api.c                | 16 ++++++++

plugins/qemu-plugins.symbols |  1 +

5 files changed, 111 insertions(+), 1 deletion(-)

create mode 100644 contrib/plugins/memtrace.c

 

diff --git a/contrib/plugins/Makefile b/contrib/plugins/Makefile

index 23e0396687..cf27554616 100644

--- a/contrib/plugins/Makefile

+++ b/contrib/plugins/Makefile

@@ -21,6 +21,7 @@ NAMES += lockstep

NAMES += hwprofile

NAMES += cache

NAMES += drcov

+NAMES += memtrace

 SONAMES := $(addsuffix .so,$(addprefix lib,$(NAMES)))

diff --git a/contrib/plugins/memtrace.c b/contrib/plugins/memtrace.c

new file mode 100644

index 0000000000..16c1553f47

--- /dev/null

+++ b/contrib/plugins/memtrace.c

@@ -0,0 +1,76 @@

+/*

+ * Copyright (C) 2023, Mikhail Tyutin <m.tyutin@yadro.com>

+ *

+ * Log all memory accesses including content of the access.

+ *

+ * License: GNU GPL, version 2 or later.

+ *   See the COPYING file in the top-level directory.

+ */

+

+#include <glib.h>

+

+#include <qemu-plugin.h>

+

+

+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;

+

+

+static void vcpu_mem_access(uint32_t vcpuIndex, qemu_plugin_meminfo_t memInfo,

+                            uint64_t vaddr, void *userdata)

+{

+    unsigned size = 1 << qemu_plugin_mem_size_shift(memInfo);

+    char* memContent = g_malloc(size);

+    unsigned i;

+    GString* logLine = g_string_new(NULL);

+

+    qemu_plugin_vcpu_read_phys_mem(vcpuIndex, vaddr, memContent, size);

+

+    if(qemu_plugin_mem_is_store(memInfo)) {

+        g_string_append(logLine, "mem store");

+    }

+    else {

+        g_string_append(logLine, "mem load");

+    }

+

+    g_string_append_printf(logLine, " at 0x%08"PRIx64, vaddr);

+

+    g_string_append_printf(logLine, " size=%u content={",size);

+    for (i = 0; i < size; i++) {

+        if (i != 0) {

+            g_string_append(logLine, " ");

+        }

+        g_string_append_printf(logLine, "%02hhx", memContent[i]);

+    }

+    g_string_append(logLine, "}\n");

+

+    qemu_plugin_outs(logLine->str);

+

+    g_string_free(logLine, TRUE);

+    g_free(memContent);

+}

+

+static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)

+{

+    size_t n_insns;

+    size_t i;

+

+    n_insns = qemu_plugin_tb_n_insns(tb);

+    for (i = 0; i < n_insns; i++) {

+        struct qemu_plugin_insn *insn = qemu_plugin_tb_get_insn(tb, i);

+

+        qemu_plugin_register_vcpu_mem_cb(insn,

+                                     vcpu_mem_access,

+                                     QEMU_PLUGIN_CB_NO_REGS,

+                                     QEMU_PLUGIN_MEM_RW,

+                                     0);

+    }

+}

+

+QEMU_PLUGIN_EXPORT

+int qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info,

+                        int argc, char **argv)

+{

+    qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans);

+

+    return 0;

+}

diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h

index d0e9d03adf..866282cf7d 100644

--- a/include/qemu/qemu-plugin.h

+++ b/include/qemu/qemu-plugin.h

@@ -51,7 +51,7 @@ typedef uint64_t qemu_plugin_id_t;

 extern QEMU_PLUGIN_EXPORT int qemu_plugin_version;

-#define QEMU_PLUGIN_VERSION 1

+#define QEMU_PLUGIN_VERSION 2

 /**

  * struct qemu_info_t - system information for plugins

@@ -625,4 +625,20 @@ uint64_t qemu_plugin_end_code(void);

  */

uint64_t qemu_plugin_entry_code(void);

+/**

+ * qemu_plugin_vcpu_read_phys_mem() - reads guest's memory content

+ *

+ * @vcpu_index: vcpu index

+ * @addr: guest's virtual address

+ * @buf: destination buffer to read data to

+ * @len: number of bytes to read

+ *

+ * Adjusts address according to internal memory mapping and reads

+ * content of guest memory.

+ */

+void qemu_plugin_vcpu_read_phys_mem(unsigned int vcpu_index,

+                                    uint64_t addr,

+                                    void *buf,

+                                    uint64_t len);

+

#endif /* QEMU_QEMU_PLUGIN_H */

diff --git a/plugins/api.c b/plugins/api.c

index 2078b16edb..af4f177229 100644

--- a/plugins/api.c

+++ b/plugins/api.c

@@ -442,3 +442,19 @@ uint64_t qemu_plugin_entry_code(void)

#endif

     return entry;

}

+

+void qemu_plugin_vcpu_read_phys_mem(unsigned int vcpu_index,

+                                    uint64_t addr,

+                                    void *buf,

+                                    uint64_t len) {

+    CPUClass *cc;

+    CPUState *cpu;

+

+    cpu = qemu_get_cpu(vcpu_index);

+    cc = CPU_GET_CLASS(cpu);

+    if (cc->memory_rw_debug) {

+        cc->memory_rw_debug(cpu, addr, buf, len, false);

+    } else {

+        cpu_memory_rw_debug(cpu, addr, buf, len, false);

+    }

+}

\ No newline at end of file

diff --git a/plugins/qemu-plugins.symbols b/plugins/qemu-plugins.symbols

index 71f6c90549..f0ce8c730f 100644

--- a/plugins/qemu-plugins.symbols

+++ b/plugins/qemu-plugins.symbols

@@ -42,4 +42,5 @@

   qemu_plugin_tb_vaddr;

   qemu_plugin_uninstall;

   qemu_plugin_vcpu_for_each;

+  qemu_plugin_vcpu_read_phys_mem;

};

--

2.34.1

 


reply via email to

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