[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v6 22/22] instrument: Add API to manipulate guest me
From: |
Lluís Vilanova |
Subject: |
[Qemu-devel] [PATCH v6 22/22] instrument: Add API to manipulate guest memory |
Date: |
Wed, 13 Sep 2017 14:22:37 +0300 |
User-agent: |
StGit/0.18 |
It includes access to the guest's memory and vCPU registers.
Signed-off-by: Lluís Vilanova <address@hidden>
---
instrument/Makefile.objs | 1
instrument/qemu-instr/state.h | 104 +++++++++++++++++++++++++++++++++++++++++
instrument/state.c | 73 +++++++++++++++++++++++++++++
3 files changed, 178 insertions(+)
create mode 100644 instrument/qemu-instr/state.h
create mode 100644 instrument/state.c
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index d7e6c760c3..ee482bdb45 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -5,3 +5,4 @@ target-obj-$(CONFIG_INSTRUMENT) += load.o
target-obj-$(CONFIG_INSTRUMENT) += qmp.o
target-obj-$(CONFIG_INSTRUMENT) += control.o
target-obj-$(CONFIG_INSTRUMENT) += trace.o
+target-obj-$(CONFIG_INSTRUMENT) += state.o
diff --git a/instrument/qemu-instr/state.h b/instrument/qemu-instr/state.h
new file mode 100644
index 0000000000..0ae6255fe5
--- /dev/null
+++ b/instrument/qemu-instr/state.h
@@ -0,0 +1,104 @@
+/*
+ * Interface for accessing guest state.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef QI__STATE_H
+#define QI__STATE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <qemu-instr/types.h>
+
+
+/**
+ * qi_mem_read_virt:
+ * @vcpu: CPU to use for address translation.
+ * @vaddr: Starting virtual address to read from.
+ * @size: Number of bytes to read.
+ * @buf: Buffer to write into.
+ *
+ * Read contents from virtual memory.
+ *
+ * Returns: Whether the range of virtual addresses to read could be translated.
+ *
+ * Warning: Even on error, some of the destination buffer might have been
+ * modified.
+ *
+ * Precondition: The output buffer has at least "size" bytes.
+ */
+bool qi_mem_read_virt(QICPU vcpu, uint64_t vaddr, size_t size, void *buf);
+
+/**
+ * qi_mem_write_virt:
+ * @vcpu: CPU to use for address translation.
+ * @vaddr: Starting virtual address to write into.
+ * @size: Number of bytes to write.
+ * @buf: Buffer with the contents to write from.
+ *
+ * Write contents into virtual memory.
+ *
+ * Returns: Whether the range of virtual addresses to write could be
translated.
+ *
+ * Warning: Even on error, some of the destination memory might have been
+ * modified.
+ * Precondition: The input buffer has at least "size" bytes.
+ */
+bool qi_mem_write_virt(QICPU vcpu, uint64_t vaddr, size_t size, void *buf);
+
+/**
+ * qi_mem_virt_to_phys:
+ * @vcpu: CPU to use for address translation.
+ * @vaddr: Virtual address to translate.
+ * @paddr: Pointer to output physical address.
+ *
+ * Translate a virtual address into a physical address.
+ *
+ * Returns: Whether the address could be translated.
+ */
+bool qi_mem_virt_to_phys(QICPU vcpu, uint64_t vaddr, uint64_t *paddr);
+
+/**
+ * qi_mem_read_phys:
+ * @paddr: Starting physical address to read from.
+ * @size: Number of bytes to read.
+ * @buf: Buffer to write into.
+ *
+ * Read contents from physical memory.
+ *
+ * Returns: Whether the range of physical addresses is valid.
+ *
+ * Warning: Even on error, some of the destination buffer might have been
+ * modified.
+ * Precondition: The output buffer has at least "size" bytes.
+ */
+bool qi_mem_read_phys(uint64_t paddr, size_t size, void *buf);
+
+/**
+ * qi_mem_write_phys:
+ * @paddr: Starting physical address to write into.
+ * @size: Number of bytes to write.
+ * @buf: Buffer with the contents to write from.
+ *
+ * Write contents into virtual memory.
+ *
+ * Returns: Whether the range of physical addresses is valid.
+ *
+ * Warning: Even on error, some of the destination memory might have been
+ * modified.
+ *
+ * Precondition: The input buffer has at least "size" bytes.
+ */
+bool qi_mem_write_phys(uint64_t paddr, size_t size, void *buf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* QI__STATE_H */
diff --git a/instrument/state.c b/instrument/state.c
new file mode 100644
index 0000000000..e76fd5fbcd
--- /dev/null
+++ b/instrument/state.c
@@ -0,0 +1,73 @@
+/*
+ * Interface for accessing guest state.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include "qemu/compiler.h"
+#include "cpu.h"
+#include "exec/cpu-all.h"
+#include "instrument/control.h"
+#include "instrument/error.h"
+#include "instrument/qemu-instr/state.h"
+
+
+SYM_PUBLIC bool qi_mem_read_virt(QICPU vcpu, uint64_t vaddr,
+ size_t size, void *buf)
+{
+ CPUState *vcpu_ = instr_cpu_from_qicpu(vcpu);
+ ERROR_IF_RET(!instr_get_state(), false, "called outside instrumentation");
+ ERROR_IF_RET(!vcpu_, false, "invalid QICPU");
+ return cpu_memory_rw_debug(vcpu_, vaddr, buf, size, 0) == 0;
+}
+
+SYM_PUBLIC bool qi_mem_write_virt(QICPU vcpu, uint64_t vaddr,
+ size_t size, void *buf)
+{
+ CPUState *vcpu_ = instr_cpu_from_qicpu(vcpu);
+ ERROR_IF_RET(!instr_get_state(), false, "called outside instrumentation");
+ ERROR_IF_RET(!vcpu_, false, "invalid QICPU");
+ return cpu_memory_rw_debug(vcpu_, vaddr, buf, size, 1) == 0;
+}
+
+SYM_PUBLIC bool qi_mem_virt_to_phys(QICPU vcpu, uint64_t vaddr, uint64_t
*paddr)
+{
+ CPUState *vcpu_ = instr_cpu_from_qicpu(vcpu);
+ ERROR_IF_RET(!instr_get_state(), false, "called outside instrumentation");
+ ERROR_IF_RET(!vcpu_, false, "invalid QICPU");
+
+#if defined(CONFIG_USER_ONLY)
+ *paddr = vaddr;
+ return true;
+#else
+ *paddr = cpu_get_phys_page_debug(vcpu_, vaddr);
+ return *paddr != -1;
+#endif
+}
+
+SYM_PUBLIC bool qi_mem_read_phys(uint64_t paddr, size_t size, void *buf)
+{
+ ERROR_IF_RET(!instr_get_state(), false, "called outside instrumentation");
+#if defined(CONFIG_USER_ONLY)
+ return cpu_memory_rw_debug(NULL, paddr, buf, size, 0) == 0;
+#else
+ cpu_physical_memory_read(paddr, buf, size);
+ return true;
+#endif
+}
+
+SYM_PUBLIC bool qi_mem_write_phys(uint64_t paddr, size_t size, void *buf)
+{
+ ERROR_IF_RET(!instr_get_state(), false, "called outside instrumentation");
+#if defined(CONFIG_USER_ONLY)
+ return cpu_memory_rw_debug(NULL, paddr, buf, size, 1) == 0;
+#else
+ cpu_physical_memory_write(paddr, buf, size);
+ return true;
+#endif
+}
- [Qemu-devel] [PATCH v6 12/22] instrument: Add event 'guest_cpu_enter', (continued)
- [Qemu-devel] [PATCH v6 12/22] instrument: Add event 'guest_cpu_enter', Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 13/22] instrument: Support synchronous modification of vCPU state, Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 14/22] exec: Add function to synchronously flush TB on a stopped vCPU, Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 15/22] instrument: Add event 'guest_cpu_exit', Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 16/22] instrument: Add event 'guest_cpu_reset', Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 17/22] trace: Introduce a proper structure to describe memory accesses, Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 18/22] instrument: Add event 'guest_mem_before_trans', Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 19/22] instrument: Add event 'guest_mem_before_exec', Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 20/22] instrument: Add event 'guest_user_syscall', Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 21/22] instrument: Add event 'guest_user_syscall_ret', Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 22/22] instrument: Add API to manipulate guest memory,
Lluís Vilanova <=
- Re: [Qemu-devel] [PATCH v6 00/22] instrument: Add basic event instrumentation, no-reply, 2017/09/13
- Re: [Qemu-devel] [PATCH v6 00/22] instrument: Add basic event instrumentation, Emilio G. Cota, 2017/09/25