@@ -161,6 +161,9 @@ void qemu_plugin_vcpu_exit_hook(CPUState *cpu);
void qemu_plugin_tb_trans_cb(CPUState *cpu, struct qemu_plugin_tb *tb);
void qemu_plugin_vcpu_idle_cb(CPUState *cpu);
void qemu_plugin_vcpu_resume_cb(CPUState *cpu);
+void qemu_plugin_vcpu_interrupt_cb(CPUState *cpu, uint64_t from, uint64_t to);
+void qemu_plugin_vcpu_exception_cb(CPUState *cpu, uint64_t from, uint64_t to);
+void qemu_plugin_vcpu_hostcall_cb(CPUState *cpu, uint64_t from, uint64_t to);
void
qemu_plugin_vcpu_syscall(CPUState *cpu, int64_t num, uint64_t a1,
uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5,
@@ -243,6 +246,15 @@ static inline void qemu_plugin_vcpu_idle_cb(CPUState *cpu)
static inline void qemu_plugin_vcpu_resume_cb(CPUState *cpu)
{ }
+void qemu_plugin_vcpu_interrupt_cb(CPUState *cpu, uint64_t from, uint64_t to)
+{ }
+
+void qemu_plugin_vcpu_exception_cb(CPUState *cpu, uint64_t from, uint64_t to)
+{ }
+
+void qemu_plugin_vcpu_hostcall_cb(CPUState *cpu, uint64_t from, uint64_t to)
+{ }
+
static inline void
qemu_plugin_vcpu_syscall(CPUState *cpu, int64_t num, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5, uint64_t a6,
@@ -112,6 +112,43 @@ static void plugin_vcpu_cb__simple(CPUState *cpu, enum qemu_plugin_event ev)
}
}
+/*
+ * Disable CFI checks.
+ * The callback function has been loaded from an external library so we do not
+ * have type information
+ */
+QEMU_DISABLE_CFI
+static void plugin_vcpu_cb__discon(CPUState *cpu,
+ enum qemu_plugin_discon_type type,
+ uint64_t from, uint64_t to)
+{
+ struct qemu_plugin_cb *cb, *next;
+ enum qemu_plugin_event ev;
+
+ if (cpu->cpu_index < plugin.num_vcpus) {
+ switch (type) {
+ case QEMU_PLUGIN_DISCON_INTERRUPT:
+ ev = QEMU_PLUGIN_EV_VCPU_INTERRUPT;
+ break;
+ case QEMU_PLUGIN_DISCON_EXCEPTION:
+ ev = QEMU_PLUGIN_EV_VCPU_EXCEPTION;
+ break;
+ case QEMU_PLUGIN_DISCON_HOSTCALL:
+ ev = QEMU_PLUGIN_EV_VCPU_HOSTCALL;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ /* iterate safely; plugins might uninstall themselves at any time */
+ QLIST_FOREACH_SAFE_RCU(cb, &plugin.cb_lists[ev], entry, next) {
+ qemu_plugin_vcpu_discon_cb_t func = cb->f.vcpu_discon;
+
+ func(cb->ctx->id, cpu->cpu_index, type, from, to);
+ }
+ }
+}
+
/*
* Disable CFI checks.
* The callback function has been loaded from an external library so we do not
@@ -547,6 +584,21 @@ void qemu_plugin_vcpu_resume_cb(CPUState *cpu)
}
}
+void qemu_plugin_vcpu_interrupt_cb(CPUState *cpu, uint64_t from, uint64_t to)
+{
+ plugin_vcpu_cb__discon(cpu, QEMU_PLUGIN_DISCON_INTERRUPT, from, to);
+}
+
+void qemu_plugin_vcpu_exception_cb(CPUState *cpu, uint64_t from, uint64_t to)
+{
+ plugin_vcpu_cb__discon(cpu, QEMU_PLUGIN_DISCON_EXCEPTION, from, to);
+}
+
+void qemu_plugin_vcpu_hostcall_cb(CPUState *cpu, uint64_t from, uint64_t to)
+{
+ plugin_vcpu_cb__discon(cpu, QEMU_PLUGIN_DISCON_HOSTCALL, from, to);
+}
+
void qemu_plugin_register_vcpu_idle_cb(qemu_plugin_id_t id,
qemu_plugin_vcpu_simple_cb_t cb)
{