* CPU's index into a TCG temp, since the first callback did it already.
*/
#include "qemu/osdep.h"
+#include "qemu/plugin.h"
#include "cpu.h"
#include "tcg/tcg.h"
#include "tcg/tcg-temp-internal.h"
{
bool ret = false;
- if (test_bit(QEMU_PLUGIN_EV_VCPU_TB_TRANS, cpu->plugin_mask)) {
+ if (test_bit(QEMU_PLUGIN_EV_VCPU_TB_TRANS, cpu->plugin_state->event_mask)) {
struct qemu_plugin_tb *ptb = tcg_ctx->plugin_tb;
int i;
}
}
+#ifdef CONFIG_PLUGIN
static void qemu_plugin_vcpu_init__async(CPUState *cpu, run_on_cpu_data unused)
{
qemu_plugin_vcpu_init_hook(cpu);
}
+#endif
static void cpu_common_realizefn(DeviceState *dev, Error **errp)
{
}
/* Plugin initialization must wait until the cpu start executing code */
+#ifdef CONFIG_PLUGIN
if (tcg_enabled()) {
+ cpu->plugin_state = qemu_plugin_create_vcpu_state();
async_run_on_cpu(cpu, qemu_plugin_vcpu_init__async, RUN_ON_CPU_NULL);
}
+#endif
/* NOTE: latest generic point where the cpu is fully realized */
}
#include "qemu/rcu_queue.h"
#include "qemu/queue.h"
#include "qemu/thread.h"
-#include "qemu/plugin-event.h"
#include "qom/object.h"
typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size,
* @kvm_fd: vCPU file descriptor for KVM.
* @work_mutex: Lock to prevent multiple access to @work_list.
* @work_list: List of pending asynchronous work.
- * @plugin_mask: Plugin event bitmap. Modified only via async work.
+ * @plugin_mem_cbs: active plugin memory callbacks
+ * @plugin_state: per-CPU plugin state
* @ignore_memory_transaction_failures: Cached copy of the MachineState
* flag of the same name: allows the board to suppress calling of the
* CPU do_transaction_failed hook function.
/* Use by accel-block: CPU is executing an ioctl() */
QemuLockCnt in_ioctl_lock;
- DECLARE_BITMAP(plugin_mask, QEMU_PLUGIN_EV_MAX);
-
#ifdef CONFIG_PLUGIN
+ /*
+ * The callback pointer stays in the main CPUState as it is
+ * accessed via TCG (see gen_empty_mem_helper).
+ */
GArray *plugin_mem_cbs;
+ CPUPluginState *plugin_state;
#endif
/* TODO Move common fields from CPUArchState here. */
return insn;
}
+/**
+ * struct CPUPluginState - per-CPU state for plugins
+ * @event_mask: plugin event bitmap. Modified only via async work.
+ */
+struct CPUPluginState {
+ DECLARE_BITMAP(event_mask, QEMU_PLUGIN_EV_MAX);
+};
+
+/**
+ * qemu_plugin_create_vcpu_state: allocate plugin state
+ */
+CPUPluginState *qemu_plugin_create_vcpu_state(void);
+
void qemu_plugin_vcpu_init_hook(CPUState *cpu);
void qemu_plugin_vcpu_exit_hook(CPUState *cpu);
void qemu_plugin_tb_trans_cb(CPUState *cpu, struct qemu_plugin_tb *tb);
typedef struct ConfidentialGuestSupport ConfidentialGuestSupport;
typedef struct CPUAddressSpace CPUAddressSpace;
typedef struct CPUArchState CPUArchState;
+typedef struct CPUPluginState CPUPluginState;
typedef struct CpuInfoFast CpuInfoFast;
typedef struct CPUJumpCache CPUJumpCache;
typedef struct CPUState CPUState;
#include "qapi/error.h"
#include "qemu/lockable.h"
#include "qemu/option.h"
+#include "qemu/plugin.h"
#include "qemu/rcu_queue.h"
#include "qemu/xxhash.h"
#include "qemu/rcu.h"
static void plugin_cpu_update__async(CPUState *cpu, run_on_cpu_data data)
{
- bitmap_copy(cpu->plugin_mask, &data.host_ulong, QEMU_PLUGIN_EV_MAX);
+ bitmap_copy(cpu->plugin_state->event_mask,
+ &data.host_ulong, QEMU_PLUGIN_EV_MAX);
tcg_flush_jmp_cache(cpu);
}
do_plugin_register_cb(id, ev, func, udata);
}
+CPUPluginState *qemu_plugin_create_vcpu_state(void)
+{
+ return g_new0(CPUPluginState, 1);
+}
+
void qemu_plugin_vcpu_init_hook(CPUState *cpu)
{
bool success;
struct qemu_plugin_cb *cb, *next;
enum qemu_plugin_event ev = QEMU_PLUGIN_EV_VCPU_SYSCALL;
- if (!test_bit(ev, cpu->plugin_mask)) {
+ if (!test_bit(ev, cpu->plugin_state->event_mask)) {
return;
}
struct qemu_plugin_cb *cb, *next;
enum qemu_plugin_event ev = QEMU_PLUGIN_EV_VCPU_SYSCALL_RET;
- if (!test_bit(ev, cpu->plugin_mask)) {
+ if (!test_bit(ev, cpu->plugin_state->event_mask)) {
return;
}