@@ -48,3 +48,12 @@ QI_VPUBLIC void qi_set_fini(qi_fini_fn fn, void *data)
instr_set_event(fini_fn, fn);
instr_set_event(fini_data, data);
}
+
+
+void (*instr_event__guest_cpu_enter)(QICPU vcpu);
+
+QI_VPUBLIC void qi_event_set_guest_cpu_enter(void (*fn)(QICPU vcpu))
+{
+ ERROR_IF(!instr_get_state(), "called outside instrumentation");
+ instr_set_event(guest_cpu_enter, fn);
+}
@@ -11,6 +11,7 @@
#define INSTRUMENT__EVENTS_H
#include "instrument/qemu-instr/control.h"
+#include "instrument/qemu-instr/types.h"
/**
* instr_get_event:
@@ -32,6 +33,10 @@
extern qi_fini_fn instr_event__fini_fn;
extern void *instr_event__fini_data;
+extern void (*instr_event__guest_cpu_enter)(QICPU vcpu);
+static inline void instr_guest_cpu_enter(CPUState *vcpu);
+
+
#include "instrument/events.inc.h"
#endif /* INSTRUMENT__EVENTS_H */
@@ -7,5 +7,16 @@
* See the COPYING file in the top-level directory.
*/
+#include "instrument/control.h"
+static inline void instr_guest_cpu_enter(CPUState *vcpu)
+{
+ void (*cb)(QICPU vcpu) = instr_get_event(guest_cpu_enter);
+ if (cb) {
+ QICPU vcpu_ = instr_cpu_set(vcpu);
+ instr_set_state(INSTR_STATE_ENABLE);
+ (*cb)(vcpu_);
+ instr_set_state(INSTR_STATE_DISABLE);
+ }
+}
@@ -148,6 +148,7 @@ InstrUnloadError instr_unload(int64_t handle_id)
}
instr_set_event(fini_fn, NULL);
+ instr_set_event(guest_cpu_enter, NULL);
/* this should never fail */
if (dlclose(handle->dlhandle) < 0) {
@@ -16,6 +16,7 @@ extern "C" {
#include <stdbool.h>
#include <stddef.h>
+#include <qemu-instr/types.h>
/**
@@ -36,6 +37,49 @@ typedef void (*qi_fini_fn)(void *arg);
*/
void qi_set_fini(qi_fini_fn fn, void *data);
+
+/*
+ * Set callbacks for available events. Each event has a short description and
+ * various indicators of when it can be triggered:
+ *
+ * - Mode :: user
+ * Triggered in QEMU user application emulation (e.g., linux-user).
+ *
+ * - Mode :: softmmy
+ * Triggered in QEMU full-system emulation.
+ *
+ *
+ * - Targets :: all
+ * Triggered on all targets, both using TCG or native hardware virtualization
+ * (e.g., KVM).
+ *
+ * - Targets :: TCG(<arch>)
+ * Triggered on the given guest target architectures when executing with TCG
+ * (no native hardware virtualization).
+ *
+ *
+ * - Time :: exec
+ * Triggered when the guest executes the described operation.
+ *
+ * - Time :: trans
+ * Triggered when QEMU translates a guest operation. This is only available
+ * when executing with TCG. Guest instructions are decompiled and translated
+ * into the intermediate TCG language (when "Time: trans" events are
+ * triggered). Then, the TCG compiler translates TCG code into the native host
+ * code that QEMU will execute to emulate the guest (when "Time: exec" events
+ * are triggered). As QEMU uses a cache of translated code, the same
+ * instruction might be translated more than once (when the cache overflows).
+ */
+
+/*
+ * Hot-plug a new virtual (guest) CPU.
+ *
+ * Mode: user, softmmu
+ * Targets: all
+ * Time: exec
+ */
+void qi_event_set_guest_cpu_enter(void (*fn)(QICPU vcpu));
+
#ifdef __cplusplus
}
#endif
@@ -11,3 +11,4 @@
__thread InstrState instr_cur_state;
+void (*instr_event__guest_cpu_enter)(QICPU *vcpu);
@@ -9,6 +9,7 @@
#include "qemu/osdep.h"
#include "cpu.h"
+#include "instrument/events.h"
#include "trace-root.h"
#include "trace/control.h"
#include "translate-all.h"
@@ -147,5 +148,6 @@ void trace_init_vcpu(CPUState *vcpu)
}
}
}
+ instr_guest_cpu_enter(vcpu);
trace_guest_cpu_enter(vcpu);
}
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu> --- instrument/control.c | 9 ++++++++ instrument/events.h | 5 ++++ instrument/events.inc.h | 11 ++++++++++ instrument/load.c | 1 + instrument/qemu-instr/control.h | 44 +++++++++++++++++++++++++++++++++++++++ stubs/instrument.c | 1 + trace/control-target.c | 2 ++ 7 files changed, 73 insertions(+)