@@ -28,6 +28,7 @@
#include "trace-root.h"
#endif
+#include "instrument/events.h"
#include "trace/mem.h"
#if DATA_SIZE == 8
@@ -89,6 +90,7 @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
#if !defined(SOFTMMU_CODE_ACCESS)
TraceMemInfo meminfo = trace_mem_build_info(SHIFT, false, MO_TE, false);
+ instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo);
trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
#endif
@@ -126,6 +128,7 @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
#if !defined(SOFTMMU_CODE_ACCESS)
TraceMemInfo meminfo = trace_mem_build_info(SHIFT, true, MO_TE, false);
+ instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo);
trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
#endif
@@ -167,6 +170,7 @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
#if !defined(SOFTMMU_CODE_ACCESS)
TraceMemInfo meminfo = trace_mem_build_info(SHIFT, false, MO_TE, true);
+ instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo);
trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
#endif
@@ -27,6 +27,7 @@
#include "trace-root.h"
#endif
+#include "instrument/events.h"
#include "trace/mem.h"
#if DATA_SIZE == 8
@@ -62,6 +63,7 @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
{
#if !defined(CODE_ACCESS)
TraceMemInfo meminfo = trace_mem_build_info(DATA_SIZE, false, MO_TE, false);
+ instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo);
trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
#endif
return glue(glue(ld, USUFFIX), _p)(g2h(ptr));
@@ -81,6 +83,7 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
{
#if !defined(CODE_ACCESS)
TraceMemInfo meminfo = trace_mem_build_info(DATA_SIZE, true, MO_TE, false);
+ instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo);
trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
#endif
return glue(glue(lds, SUFFIX), _p)(g2h(ptr));
@@ -102,6 +105,7 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
{
#if !defined(CODE_ACCESS)
TraceMemInfo meminfo = trace_mem_build_info(DATA_SIZE, false, MO_TE, true);
+ instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo);
trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
#endif
glue(glue(st, SUFFIX), _p)(g2h(ptr), v);
@@ -57,6 +57,7 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
}
#include "helper.h"
+#include "instrument/helpers.h"
#include "trace/generated-helpers.h"
#include "trace/generated-helpers-wrappers.h"
#include "tcg-runtime.h"
@@ -27,6 +27,7 @@ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
dh_ctype(t4), dh_ctype(t5));
#include "helper.h"
+#include "instrument/helpers.h"
#include "trace/generated-helpers.h"
#include "tcg-runtime.h"
@@ -40,6 +40,7 @@
| dh_sizemask(t5, 5) },
#include "helper.h"
+#include "instrument/helpers.h"
#include "trace/generated-helpers.h"
#include "tcg-runtime.h"
@@ -14,6 +14,8 @@
#include "instrument/qemu-instr/control.h"
#include "instrument/qemu-instr/visibility.h"
#include "qom/cpu.h"
+#include "exec/helper-proto.h"
+#include "exec/helper-gen.h"
__thread InstrInfo instr_cur_info;
@@ -86,3 +88,36 @@ QI_VPUBLIC void qi_event_set_guest_mem_before_trans(
ERROR_IF(!instr_get_state(), "called outside instrumentation");
instr_set_event(guest_mem_before_trans, fn);
}
+
+
+QI_VPUBLIC void qi_event_gen_guest_mem_before_exec(
+ QITCGv_cpu vcpu, QITCGv vaddr, QIMemInfo info)
+{
+ ERROR_IF(instr_get_state() != INSTR_STATE_ENABLE_TCG,
+ "called outside instrumentation");
+ InstrInfo *iinfo = &instr_cur_info;
+ TCGv_env vcpu_ = instr_tcg_get(iinfo, vcpu);
+ TCGv vaddr_ = instr_tcg_get(iinfo, vaddr);
+ TCGv_i32 info_ = tcg_const_i32(info.raw);
+ gen_helper_instr_guest_mem_before_exec(vcpu_, vaddr_, info_);
+ tcg_temp_free_i32(info_);
+}
+
+void helper_instr_guest_mem_before_exec(
+ CPUArchState * vcpu, target_ulong vaddr, uint32_t info)
+{
+ TraceMemInfo info_;
+ info_.raw = info;
+ instr_guest_mem_before_exec(ENV_GET_CPU(vcpu), vaddr, info_);
+}
+
+
+void (*instr_event__guest_mem_before_exec)(
+ QICPU vcpu, uint64_t vaddr, QIMemInfo info);
+
+QI_VPUBLIC void qi_event_set_guest_mem_before_exec(
+ void (*fn)(QICPU vcpu, uint64_t vaddr, QIMemInfo info))
+{
+ ERROR_IF(!instr_get_state(), "called outside instrumentation");
+ instr_set_event(guest_mem_before_exec, fn);
+}
@@ -54,6 +54,7 @@ static inline QICPU instr_cpu_set(CPUState *vcpu);
typedef enum {
INSTR_STATE_DISABLE,
INSTR_STATE_ENABLE,
+ INSTR_STATE_ENABLE_TCG,
} InstrState;
#define INSTR_MAX_TCG_REGS 16
@@ -102,6 +103,20 @@ static inline InstrState instr_get_state(void);
*/
static inline void instr_tcg_count(InstrInfo *info, unsigned int count);
+/**
+ * instr_tcg_get:
+ * @info: Pointer to #InstrInfo.
+ * @arg: QITCG register.
+ *
+ * Get a suitable TCGv* from a QITCGv* value.
+ */
+#define instr_tcg_get(info, arg) \
+ ({ \
+ unsigned int idx = (uintptr_t)arg; \
+ ERROR_IF(info->max <= idx, "invalid QITCGv register"); \
+ info->tcg_regs[idx]; \
+ })
+
#include "instrument/control.inc.h"
@@ -63,6 +63,11 @@ extern void (*instr_event__guest_mem_before_trans)(
static inline void instr_guest_mem_before_trans(
CPUState *vcpu_trans, TCGv_env vcpu_exec, TCGv vaddr, TraceMemInfo info);
+extern void (*instr_event__guest_mem_before_exec)(
+ QICPU vcpu, uint64_t vaddr, QIMemInfo info);
+static inline void instr_guest_mem_before_exec(
+ CPUState *vcpu, uint64_t vaddr, TraceMemInfo info);
+
#include "instrument/events.inc.h"
@@ -50,7 +50,7 @@ static inline void instr_guest_mem_before_trans(
void (*cb)(QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMemInfo info)
= instr_get_event(guest_mem_before_trans);
if (cb) {
- InstrInfo *iinfo = instr_set_state(INSTR_STATE_ENABLE);
+ InstrInfo *iinfo = instr_set_state(INSTR_STATE_ENABLE_TCG);
QICPU vcpu_trans_ = instr_cpu_set(vcpu_trans);
QITCGv_cpu vcpu_exec_ = instr_tcg_set(iinfo, 0, vcpu_exec);
QITCGv vaddr_ = instr_tcg_set(iinfo, 1, vaddr);
@@ -61,3 +61,19 @@ static inline void instr_guest_mem_before_trans(
instr_set_state(INSTR_STATE_DISABLE);
}
}
+
+static inline void instr_guest_mem_before_exec(
+ CPUState *vcpu, uint64_t vaddr, TraceMemInfo info)
+{
+ void (*cb)(QICPU vcpu, uint64_t vaddr, QIMemInfo info)
+ = instr_get_event(guest_mem_before_exec);
+ if (cb) {
+ InstrInfo *iinfo = instr_set_state(INSTR_STATE_ENABLE);
+ QICPU vcpu_ = instr_cpu_set(vcpu);
+ QIMemInfo info_;
+ info_.raw = info.raw;
+ instr_tcg_count(iinfo, 2);
+ (*cb)(vcpu_, vaddr, info_);
+ instr_set_state(INSTR_STATE_DISABLE);
+ }
+}
new file mode 100644
@@ -0,0 +1 @@
+DEF_HELPER_FLAGS_3(instr_guest_mem_before_exec, TCG_CALL_NO_RWG, void, env, tl, i32)
@@ -152,6 +152,7 @@ InstrUnloadError instr_unload(int64_t handle_id)
instr_set_event(guest_cpu_exit, NULL);
instr_set_event(guest_cpu_reset, NULL);
instr_set_event(guest_mem_before_trans, NULL);
+ instr_set_event(guest_mem_before_exec, NULL);
/* this should never fail */
if (dlclose(handle->dlhandle) < 0) {
@@ -113,6 +113,27 @@ void qi_event_set_guest_cpu_reset(void (*fn)(QICPU vcpu));
void qi_event_set_guest_mem_before_trans(
void (*fn)(QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMemInfo info));
+/*
+ * Generate code to trigger a 'guest_mem_before_exec' from
+ * 'guest_mem_before_trans'.
+ *
+ * Mode: user, softmmu
+ * Targets: TCG(all)
+ * Time: trans
+ */
+void qi_event_gen_guest_mem_before_exec(
+ QITCGv_cpu vcpu, QITCGv vaddr, QIMemInfo info);
+
+/*
+ * Execution-time equivalent of 'guest_mem_before_trans'.
+ *
+ * Mode: user, softmmu
+ * Targets: TCG(all)
+ * Time: exec
+ */
+void qi_event_set_guest_mem_before_exec(
+ void (*fn)(QICPU vcpu, uint64_t vaddr, QIMemInfo info));
+
#ifdef __cplusplus
}
#endif
@@ -16,3 +16,5 @@ void (*instr_event__guest_cpu_exit)(QICPU *vcpu);
void (*instr_event__guest_cpu_reset)(QICPU *vcpu);
void (*instr_event__guest_mem_before_trans)(
QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMemInfo info);
+void (*instr_event__guest_mem_before_exec)(
+ QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMemInfo info);
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu> --- include/exec/cpu_ldst_template.h | 4 +++ include/exec/cpu_ldst_useronly_template.h | 4 +++ include/exec/helper-gen.h | 1 + include/exec/helper-proto.h | 1 + include/exec/helper-tcg.h | 1 + instrument/control.c | 35 +++++++++++++++++++++++++++++ instrument/control.h | 15 ++++++++++++ instrument/events.h | 5 ++++ instrument/events.inc.h | 18 ++++++++++++++- instrument/helpers.h | 1 + instrument/load.c | 1 + instrument/qemu-instr/control.h | 21 +++++++++++++++++ stubs/instrument.c | 2 ++ 13 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 instrument/helpers.h