[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v6 16/54] plugins: implement helpers for resolving hwaddr
From: |
Alex Bennée |
Subject: |
[PATCH v6 16/54] plugins: implement helpers for resolving hwaddr |
Date: |
Thu, 17 Oct 2019 14:15:37 +0100 |
We need to keep a local per-cpu copy of the data as other threads may
be running. Currently we can provide insight as to if the access was
IO or not and give the offset into a given device (usually the main
RAMBlock). We store enough information to get details such as the
MemoryRegion which might be useful in later expansions to the API.
Signed-off-by: Alex Bennée <address@hidden>
Reviewed-by: Richard Henderson <address@hidden>
---
v5
- use TLS instead of racy GArray
- add more commentary regarding success
- error_report if we fail
v6
- rename api to qemu_plugin_hwaddr_device_offset
- also save iotlb details for IO accesses.
- keep memory api header details in separate header
---
accel/tcg/cputlb.c | 42 +++++++++++++++++++++++++++++++
include/qemu/plugin-memory.h | 40 +++++++++++++++++++++++++++++
include/qemu/qemu-plugin.h | 8 ++++++
plugins/api.c | 49 ++++++++++++++++++++++++++++++++++++
4 files changed, 139 insertions(+)
create mode 100644 include/qemu/plugin-memory.h
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 82282d30d9..2c06b57272 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -34,6 +34,9 @@
#include "qemu/atomic.h"
#include "qemu/atomic128.h"
#include "translate-all.h"
+#ifdef CONFIG_PLUGIN
+#include "qemu/plugin-memory.h"
+#endif
/* DEBUG defines, enable DEBUG_TLB_LOG to log to the CPU_LOG_MMU target */
/* #define DEBUG_TLB */
@@ -1247,6 +1250,45 @@ void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
return (void *)((uintptr_t)addr + entry->addend);
}
+
+#ifdef CONFIG_PLUGIN
+/*
+ * Perform a TLB lookup and populate the qemu_plugin_hwaddr structure.
+ * This should be a hot path as we will have just looked this path up
+ * in the softmmu lookup code (or helper). We don't handle re-fills or
+ * checking the victim table. This is purely informational.
+ *
+ * This should never fail as the memory access being instrumented
+ * should have just filled the TLB.
+ */
+
+bool tlb_plugin_lookup(CPUState *cpu, target_ulong addr, int mmu_idx,
+ bool is_store, struct qemu_plugin_hwaddr *data)
+{
+ CPUArchState *env = cpu->env_ptr;
+ CPUTLBEntry *tlbe = tlb_entry(env, mmu_idx, addr);
+ uintptr_t index = tlb_index(env, mmu_idx, addr);
+ target_ulong tlb_addr = is_store ? tlb_addr_write(tlbe) : tlbe->addr_read;
+
+ if (likely(tlb_hit(tlb_addr, addr))) {
+ /* We must have an iotlb entry for MMIO */
+ if (tlb_addr & TLB_MMIO) {
+ CPUIOTLBEntry *iotlbentry;
+ iotlbentry = &env_tlb(env)->d[mmu_idx].iotlb[index];
+ data->is_io = true;
+ data->v.io.section = iotlb_to_section(cpu, iotlbentry->addr,
iotlbentry->attrs);
+ data->v.io.offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
+ } else {
+ data->is_io = false;
+ data->v.ram.hostaddr = addr + tlbe->addend;
+ }
+ return true;
+ }
+ return false;
+}
+
+#endif
+
/* Probe for a read-modify-write atomic operation. Do not allow unaligned
* operations, or io operations to proceed. Return the host address. */
static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
diff --git a/include/qemu/plugin-memory.h b/include/qemu/plugin-memory.h
new file mode 100644
index 0000000000..fbbe99474b
--- /dev/null
+++ b/include/qemu/plugin-memory.h
@@ -0,0 +1,40 @@
+/*
+ * Plugin Memory API
+ *
+ * Copyright (c) 2019 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef _PLUGIN_MEMORY_H_
+#define _PLUGIN_MEMORY_H_
+
+struct qemu_plugin_hwaddr {
+ bool is_io;
+ bool is_store;
+ union {
+ struct {
+ MemoryRegionSection *section;
+ hwaddr offset;
+ } io;
+ struct {
+ uint64_t hostaddr;
+ } ram;
+ } v;
+};
+
+/**
+ * tlb_plugin_lookup: query last TLB lookup
+ * @cpu: cpu environment
+ *
+ * This function can be used directly after a memory operation to
+ * query information about the access. It is used by the plugin
+ * infrastructure to expose more information about the address.
+ *
+ * It would only fail if not called from an instrumented memory access
+ * which would be an abuse of the API.
+ */
+bool tlb_plugin_lookup(CPUState *cpu, target_ulong addr, int mmu_idx,
+ bool is_store, struct qemu_plugin_hwaddr *data);
+
+#endif /* _PLUGIN_MEMORY_H_ */
diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h
index b9a4a4b684..c213d1dd19 100644
--- a/include/qemu/qemu-plugin.h
+++ b/include/qemu/qemu-plugin.h
@@ -285,6 +285,14 @@ bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info);
struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
uint64_t vaddr);
+/*
+ * The following additional queries can be run on the hwaddr structure
+ * to return information about it. For non-IO accesses the device
+ * offset will be into the appropriate block of RAM.
+ */
+bool qemu_plugin_hwaddr_is_io(struct qemu_plugin_hwaddr *hwaddr);
+uint64_t qemu_plugin_hwaddr_device_offset(const struct qemu_plugin_hwaddr
*haddr);
+
typedef void
(*qemu_plugin_vcpu_mem_cb_t)(unsigned int vcpu_index,
qemu_plugin_meminfo_t info, uint64_t vaddr,
diff --git a/plugins/api.c b/plugins/api.c
index facf2a132d..33dac8e790 100644
--- a/plugins/api.c
+++ b/plugins/api.c
@@ -42,6 +42,7 @@
#include "trace/mem-internal.h" /* mem_info macros */
#include "plugin.h"
#ifndef CONFIG_USER_ONLY
+#include "qemu/plugin-memory.h"
#include "hw/boards.h"
#endif
@@ -240,11 +241,59 @@ bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info)
* Virtual Memory queries
*/
+#ifdef CONFIG_SOFTMMU
+static __thread struct qemu_plugin_hwaddr hwaddr_info;
+
+struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
+ uint64_t vaddr)
+{
+ CPUState *cpu = current_cpu;
+ unsigned int mmu_idx = info >> TRACE_MEM_MMU_SHIFT;
+ hwaddr_info.is_store = info & TRACE_MEM_ST;
+
+ if (!tlb_plugin_lookup(cpu, vaddr, mmu_idx,
+ info & TRACE_MEM_ST, &hwaddr_info)) {
+ error_report("invalid use of qemu_plugin_get_hwaddr");
+ return NULL;
+ }
+
+ return &hwaddr_info;
+}
+#else
struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
uint64_t vaddr)
{
return NULL;
}
+#endif
+
+bool qemu_plugin_hwaddr_is_io(struct qemu_plugin_hwaddr *hwaddr)
+{
+#ifdef CONFIG_SOFTMMU
+ return hwaddr->is_io;
+#else
+ return false;
+#endif
+}
+
+uint64_t qemu_plugin_hwaddr_device_offset(const struct qemu_plugin_hwaddr
*haddr)
+{
+#ifdef CONFIG_SOFTMMU
+ if (haddr) {
+ if (!haddr->is_io) {
+ ram_addr_t ram_addr = qemu_ram_addr_from_host((void *)
haddr->v.ram.hostaddr);
+ if (ram_addr == RAM_ADDR_INVALID) {
+ error_report("Bad ram pointer %"PRIx64"",
haddr->v.ram.hostaddr);
+ abort();
+ }
+ return ram_addr;
+ } else {
+ return haddr->v.io.offset;
+ }
+ }
+#endif
+ return 0;
+}
/*
* Queries to the number and potential maximum number of vCPUs there
--
2.20.1
- [PATCH v6 22/54] translator: add translator_ld{ub,sw,uw,l,q}, (continued)
- [PATCH v6 22/54] translator: add translator_ld{ub,sw,uw,l,q}, Alex Bennée, 2019/10/17
- [PATCH v6 32/54] target/xtensa: fetch code with translator_ld, Alex Bennée, 2019/10/17
- [PATCH v6 30/54] target/riscv: fetch code with translator_ld, Alex Bennée, 2019/10/17
- [PATCH v6 40/54] vl: support -plugin option, Alex Bennée, 2019/10/17
- [PATCH v6 51/54] accel/stubs: reduce headers from tcg-stub, Alex Bennée, 2019/10/17
- [PATCH v6 52/54] include/exec: wrap cpu_ldst.h in CONFIG_TCG, Alex Bennée, 2019/10/17
- [PATCH v6 31/54] target/sparc: fetch code with translator_ld, Alex Bennée, 2019/10/17
- [PATCH v6 53/54] .travis.yml: add --enable-plugins tests, Alex Bennée, 2019/10/17
- [PATCH v6 41/54] linux-user: support -plugin option, Alex Bennée, 2019/10/17
- [PATCH v6 43/54] tests/tcg/Makefile.target: fix path to config-host.mak, Alex Bennée, 2019/10/17
- [PATCH v6 16/54] plugins: implement helpers for resolving hwaddr,
Alex Bennée <=
- [PATCH v6 17/54] translate-all: notify plugin code of tb_flush, Alex Bennée, 2019/10/17
- [PATCH v6 28/54] target/m68k: fetch code with translator_ld, Alex Bennée, 2019/10/17
- [PATCH v6 27/54] target/hppa: fetch code with translator_ld, Alex Bennée, 2019/10/17
- [PATCH v6 38/54] plugin: add qemu_plugin_insn_disas helper, Alex Bennée, 2019/10/17
- [PATCH v6 45/54] tests/tcg: move "virtual" tests to EXTRA_TESTS, Alex Bennée, 2019/10/17
- [PATCH v6 35/54] configure: add --enable-plugins, Alex Bennée, 2019/10/17
- [PATCH v6 49/54] tests/plugin: add instruction execution breakdown, Alex Bennée, 2019/10/17
- Re: [PATCH for 4.2 v6 00/54] Support for TCG plugins, no-reply, 2019/10/17
- Re: [PATCH for 4.2 v6 00/54] Support for TCG plugins, no-reply, 2019/10/18
- Re: [PATCH for 4.2 v6 00/54] Support for TCG plugins, no-reply, 2019/10/18