@@ -87,7 +87,7 @@ int qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info,
qemu_plugin_register_vcpu_init_cb(id, vcpu_init);
qemu_plugin_vcpu_for_each(id, vcpu_init);
- qemu_plugin_register_vcpu_discon_cb(id, QEMU_PLUGIN_DISCON_TRAPS,
+ qemu_plugin_register_vcpu_discon_cb(id, QEMU_PLUGIN_DISCON_ALL,
vcpu_discon);
qemu_plugin_register_atexit_cb(id, plugin_exit, NULL);
@@ -31,6 +31,7 @@
#endif
#include "cpregs.h"
#include "target/arm/gtimer.h"
+#include "qemu/plugin.h"
#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */
@@ -11166,6 +11167,25 @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
}
}
+static void arm_do_plugin_vcpu_interrupt_cb(CPUState *cs, uint64_t from,
+ uint64_t to)
+{
+ switch (cs->exception_index) {
+ case EXCP_IRQ:
+ case EXCP_VIRQ:
+ case EXCP_NMI:
+ case EXCP_VINMI:
+ case EXCP_FIQ:
+ case EXCP_VFIQ:
+ case EXCP_VFNMI:
+ case EXCP_VSERR:
+ qemu_plugin_vcpu_interrupt_cb(cs, from, to);
+ break;
+ default:
+ qemu_plugin_vcpu_exception_cb(cs, from, to);
+ }
+}
+
static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
{
/*
@@ -11822,6 +11842,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;
unsigned int new_el = env->exception.target_el;
+ uint64_t last_pc = env->pc;
assert(!arm_feature(env, ARM_FEATURE_M));
@@ -11838,6 +11859,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
if (tcg_enabled() && arm_is_psci_call(cpu, cs->exception_index)) {
arm_handle_psci_call(cpu);
qemu_log_mask(CPU_LOG_INT, "...handled as PSCI call\n");
+ qemu_plugin_vcpu_hostcall_cb(cs, last_pc, env->pc);
return;
}
@@ -11849,6 +11871,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
#ifdef CONFIG_TCG
if (cs->exception_index == EXCP_SEMIHOST) {
tcg_handle_semihosting(cs);
+ qemu_plugin_vcpu_hostcall_cb(cs, last_pc, env->pc);
return;
}
#endif
@@ -11874,6 +11897,8 @@ void arm_cpu_do_interrupt(CPUState *cs)
if (!kvm_enabled()) {
cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
}
+
+ arm_do_plugin_vcpu_interrupt_cb(cs, last_pc, env->pc);
}
#endif /* !CONFIG_USER_ONLY */
@@ -24,6 +24,7 @@
#if !defined(CONFIG_USER_ONLY)
#include "hw/intc/armv7m_nvic.h"
#endif
+#include "qemu/plugin.h"
static void v7m_msr_xpsr(CPUARMState *env, uint32_t mask,
uint32_t reg, uint32_t val)
@@ -2186,6 +2187,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
CPUARMState *env = &cpu->env;
uint32_t lr;
bool ignore_stackfaults;
+ uint64_t last_pc = env->pc;
arm_log_exception(cs);
@@ -2353,6 +2355,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
g_assert_not_reached();
#endif
env->regs[15] += env->thumb ? 2 : 4;
+ qemu_plugin_vcpu_hostcall_cb(cs, last_pc, env->pc);
return;
case EXCP_BKPT:
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG, false);
@@ -2419,6 +2422,21 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
ignore_stackfaults = v7m_push_stack(cpu);
v7m_exception_taken(cpu, lr, false, ignore_stackfaults);
+
+ switch (cs->exception_index) {
+ case EXCP_IRQ:
+ case EXCP_VIRQ:
+ case EXCP_NMI:
+ case EXCP_VINMI:
+ case EXCP_FIQ:
+ case EXCP_VFIQ:
+ case EXCP_VFNMI:
+ case EXCP_VSERR:
+ qemu_plugin_vcpu_interrupt_cb(cs, last_pc, env->pc);
+ break;
+ default:
+ qemu_plugin_vcpu_exception_cb(cs, last_pc, env->pc);
+ }
}
uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)