3 * Copyright (C) 2019, Linaro
5 * License: GNU GPL, version 2 or later.
6 * See the COPYING file in the top-level directory.
8 * SPDX-License-Identifier: GPL-2.0-or-later
10 #ifndef QEMU_PLUGIN_API_H
11 #define QEMU_PLUGIN_API_H
17 * For best performance, build the plugin with -fvisibility=hidden so that
18 * QEMU_PLUGIN_LOCAL is implicit. Then, just mark qemu_plugin_install with
19 * QEMU_PLUGIN_EXPORT. For more info, see
20 * https://gcc.gnu.org/wiki/Visibility
22 #if defined _WIN32 || defined __CYGWIN__
24 #define QEMU_PLUGIN_EXPORT __declspec(dllexport)
26 #define QEMU_PLUGIN_EXPORT __declspec(dllimport)
28 #define QEMU_PLUGIN_LOCAL
31 #define QEMU_PLUGIN_EXPORT __attribute__((visibility("default")))
32 #define QEMU_PLUGIN_LOCAL __attribute__((visibility("hidden")))
34 #define QEMU_PLUGIN_EXPORT
35 #define QEMU_PLUGIN_LOCAL
39 typedef uint64_t qemu_plugin_id_t;
42 * qemu_plugin_install() - Install a plugin
43 * @id: this plugin's opaque ID
44 * @argc: number of arguments
45 * @argv: array of arguments (@argc elements)
47 * All plugins must export this symbol.
49 * Note: Calling qemu_plugin_uninstall() from this function is a bug. To raise
50 * an error during install, return !0.
52 * Note: @argv remains valid throughout the lifetime of the loaded plugin.
54 QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, int argc,
58 * Prototypes for the various callback styles we will be registering
59 * in the following functions.
61 typedef void (*qemu_plugin_simple_cb_t)(qemu_plugin_id_t id);
63 typedef void (*qemu_plugin_udata_cb_t)(qemu_plugin_id_t id, void *userdata);
65 typedef void (*qemu_plugin_vcpu_simple_cb_t)(qemu_plugin_id_t id,
66 unsigned int vcpu_index);
68 typedef void (*qemu_plugin_vcpu_udata_cb_t)(unsigned int vcpu_index,
72 * qemu_plugin_uninstall() - Uninstall a plugin
73 * @id: this plugin's opaque ID
74 * @cb: callback to be called once the plugin has been removed
76 * Do NOT assume that the plugin has been uninstalled once this function
77 * returns. Plugins are uninstalled asynchronously, and therefore the given
78 * plugin receives callbacks until @cb is called.
80 * Note: Calling this function from qemu_plugin_install() is a bug.
82 void qemu_plugin_uninstall(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb);
85 * qemu_plugin_reset() - Reset a plugin
86 * @id: this plugin's opaque ID
87 * @cb: callback to be called once the plugin has been reset
89 * Unregisters all callbacks for the plugin given by @id.
91 * Do NOT assume that the plugin has been reset once this function returns.
92 * Plugins are reset asynchronously, and therefore the given plugin receives
93 * callbacks until @cb is called.
95 void qemu_plugin_reset(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb);
98 * qemu_plugin_register_vcpu_init_cb() - register a vCPU initialization callback
100 * @cb: callback function
102 * The @cb function is called every time a vCPU is initialized.
104 * See also: qemu_plugin_register_vcpu_exit_cb()
106 void qemu_plugin_register_vcpu_init_cb(qemu_plugin_id_t id,
107 qemu_plugin_vcpu_simple_cb_t cb);
110 * qemu_plugin_register_vcpu_exit_cb() - register a vCPU exit callback
112 * @cb: callback function
114 * The @cb function is called every time a vCPU exits.
116 * See also: qemu_plugin_register_vcpu_init_cb()
118 void qemu_plugin_register_vcpu_exit_cb(qemu_plugin_id_t id,
119 qemu_plugin_vcpu_simple_cb_t cb);
122 * qemu_plugin_register_vcpu_idle_cb() - register a vCPU idle callback
124 * @cb: callback function
126 * The @cb function is called every time a vCPU idles.
128 void qemu_plugin_register_vcpu_idle_cb(qemu_plugin_id_t id,
129 qemu_plugin_vcpu_simple_cb_t cb);
132 * qemu_plugin_register_vcpu_resume_cb() - register a vCPU resume callback
134 * @cb: callback function
136 * The @cb function is called every time a vCPU resumes execution.
138 void qemu_plugin_register_vcpu_resume_cb(qemu_plugin_id_t id,
139 qemu_plugin_vcpu_simple_cb_t cb);
142 * Opaque types that the plugin is given during the translation and
143 * instrumentation phase.
145 struct qemu_plugin_tb;
146 struct qemu_plugin_insn;
148 enum qemu_plugin_cb_flags {
149 QEMU_PLUGIN_CB_NO_REGS, /* callback does not access the CPU's regs */
150 QEMU_PLUGIN_CB_R_REGS, /* callback reads the CPU's regs */
151 QEMU_PLUGIN_CB_RW_REGS, /* callback reads and writes the CPU's regs */
154 enum qemu_plugin_mem_rw {
155 QEMU_PLUGIN_MEM_R = 1,
161 * qemu_plugin_register_vcpu_tb_trans_cb() - register a translate cb
163 * @cb: callback function
165 * The @cb function is called every time a translation occurs. The @cb
166 * function is passed an opaque qemu_plugin_type which it can query
167 * for additional information including the list of translated
168 * instructions. At this point the plugin can register further
169 * callbacks to be triggered when the block or individual instruction
172 typedef void (*qemu_plugin_vcpu_tb_trans_cb_t)(qemu_plugin_id_t id,
173 struct qemu_plugin_tb *tb);
175 void qemu_plugin_register_vcpu_tb_trans_cb(qemu_plugin_id_t id,
176 qemu_plugin_vcpu_tb_trans_cb_t cb);
179 * qemu_plugin_register_vcpu_tb_trans_exec_cb() - register execution callback
180 * @tb: the opaque qemu_plugin_tb handle for the translation
181 * @cb: callback function
182 * @flags: does the plugin read or write the CPU's registers?
183 * @userdata: any plugin data to pass to the @cb?
185 * The @cb function is called every time a translated unit executes.
187 void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb,
188 qemu_plugin_vcpu_udata_cb_t cb,
189 enum qemu_plugin_cb_flags flags,
192 enum qemu_plugin_op {
193 QEMU_PLUGIN_INLINE_ADD_U64,
197 * qemu_plugin_register_vcpu_tb_trans_exec_inline() - execution inline op
198 * @tb: the opaque qemu_plugin_tb handle for the translation
199 * @op: the type of qemu_plugin_op (e.g. ADD_U64)
200 * @ptr: the target memory location for the op
201 * @imm: the op data (e.g. 1)
203 * Insert an inline op to every time a translated unit executes.
204 * Useful if you just want to increment a single counter somewhere in
207 void qemu_plugin_register_vcpu_tb_exec_inline(struct qemu_plugin_tb *tb,
208 enum qemu_plugin_op op,
209 void *ptr, uint64_t imm);
212 * qemu_plugin_register_vcpu_insn_exec_cb() - register insn execution cb
213 * @insn: the opaque qemu_plugin_insn handle for an instruction
214 * @cb: callback function
215 * @flags: does the plugin read or write the CPU's registers?
216 * @userdata: any plugin data to pass to the @cb?
218 * The @cb function is called every time an instruction is executed
220 void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn,
221 qemu_plugin_vcpu_udata_cb_t cb,
222 enum qemu_plugin_cb_flags flags,
226 * qemu_plugin_register_vcpu_insn_exec_inline() - insn execution inline op
227 * @insn: the opaque qemu_plugin_insn handle for an instruction
228 * @cb: callback function
229 * @op: the type of qemu_plugin_op (e.g. ADD_U64)
230 * @ptr: the target memory location for the op
231 * @imm: the op data (e.g. 1)
233 * Insert an inline op to every time an instruction executes. Useful
234 * if you just want to increment a single counter somewhere in memory.
236 void qemu_plugin_register_vcpu_insn_exec_inline(struct qemu_plugin_insn *insn,
237 enum qemu_plugin_op op,
238 void *ptr, uint64_t imm);
241 * Helpers to query information about the instructions in a block
243 size_t qemu_plugin_tb_n_insns(const struct qemu_plugin_tb *tb);
245 uint64_t qemu_plugin_tb_vaddr(const struct qemu_plugin_tb *tb);
247 struct qemu_plugin_insn *
248 qemu_plugin_tb_get_insn(const struct qemu_plugin_tb *tb, size_t idx);
250 const void *qemu_plugin_insn_data(const struct qemu_plugin_insn *insn);
252 size_t qemu_plugin_insn_size(const struct qemu_plugin_insn *insn);
254 uint64_t qemu_plugin_insn_vaddr(const struct qemu_plugin_insn *insn);
255 void *qemu_plugin_insn_haddr(const struct qemu_plugin_insn *insn);
258 * Memory Instrumentation
260 * The anonymous qemu_plugin_meminfo_t and qemu_plugin_hwaddr types
261 * can be used in queries to QEMU to get more information about a
262 * given memory access.
264 typedef uint32_t qemu_plugin_meminfo_t;
265 struct qemu_plugin_hwaddr;
267 /* meminfo queries */
268 unsigned int qemu_plugin_mem_size_shift(qemu_plugin_meminfo_t info);
269 bool qemu_plugin_mem_is_sign_extended(qemu_plugin_meminfo_t info);
270 bool qemu_plugin_mem_is_big_endian(qemu_plugin_meminfo_t info);
271 bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info);
274 * qemu_plugin_get_hwaddr():
275 * @vaddr: the virtual address of the memory operation
277 * For system emulation returns a qemu_plugin_hwaddr handle to query
278 * details about the actual physical address backing the virtual
279 * address. For linux-user guests it just returns NULL.
281 * This handle is *only* valid for the duration of the callback. Any
282 * information about the handle should be recovered before the
285 struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
289 (*qemu_plugin_vcpu_mem_cb_t)(unsigned int vcpu_index,
290 qemu_plugin_meminfo_t info, uint64_t vaddr,
293 void qemu_plugin_register_vcpu_mem_cb(struct qemu_plugin_insn *insn,
294 qemu_plugin_vcpu_mem_cb_t cb,
295 enum qemu_plugin_cb_flags flags,
296 enum qemu_plugin_mem_rw rw,
299 void qemu_plugin_register_vcpu_mem_inline(struct qemu_plugin_insn *insn,
300 enum qemu_plugin_mem_rw rw,
301 enum qemu_plugin_op op, void *ptr,
307 (*qemu_plugin_vcpu_syscall_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_index,
308 int64_t num, uint64_t a1, uint64_t a2,
309 uint64_t a3, uint64_t a4, uint64_t a5,
310 uint64_t a6, uint64_t a7, uint64_t a8);
312 void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
313 qemu_plugin_vcpu_syscall_cb_t cb);
316 (*qemu_plugin_vcpu_syscall_ret_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_idx,
317 int64_t num, int64_t ret);
320 qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
321 qemu_plugin_vcpu_syscall_ret_cb_t cb);
325 * qemu_plugin_vcpu_for_each() - iterate over the existing vCPU
327 * @cb: callback function
329 * The @cb function is called once for each existing vCPU.
331 * See also: qemu_plugin_register_vcpu_init_cb()
333 void qemu_plugin_vcpu_for_each(qemu_plugin_id_t id,
334 qemu_plugin_vcpu_simple_cb_t cb);
336 void qemu_plugin_register_flush_cb(qemu_plugin_id_t id,
337 qemu_plugin_simple_cb_t cb);
339 void qemu_plugin_register_atexit_cb(qemu_plugin_id_t id,
340 qemu_plugin_udata_cb_t cb, void *userdata);
342 /* returns -1 in user-mode */
343 int qemu_plugin_n_vcpus(void);
345 /* returns -1 in user-mode */
346 int qemu_plugin_n_max_vcpus(void);
348 #endif /* QEMU_PLUGIN_API_H */