qemu/include/qemu/qemu-plugin.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2017, Emilio G. Cota <cota@braap.org>
   3 * Copyright (C) 2019, Linaro
   4 *
   5 * License: GNU GPL, version 2 or later.
   6 *   See the COPYING file in the top-level directory.
   7 *
   8 * SPDX-License-Identifier: GPL-2.0-or-later
   9 */
  10#ifndef QEMU_PLUGIN_API_H
  11#define QEMU_PLUGIN_API_H
  12
  13#include <inttypes.h>
  14#include <stdbool.h>
  15#include <stddef.h>
  16
  17/*
  18 * For best performance, build the plugin with -fvisibility=hidden so that
  19 * QEMU_PLUGIN_LOCAL is implicit. Then, just mark qemu_plugin_install with
  20 * QEMU_PLUGIN_EXPORT. For more info, see
  21 *   https://gcc.gnu.org/wiki/Visibility
  22 */
  23#if defined _WIN32 || defined __CYGWIN__
  24  #ifdef BUILDING_DLL
  25    #define QEMU_PLUGIN_EXPORT __declspec(dllexport)
  26  #else
  27    #define QEMU_PLUGIN_EXPORT __declspec(dllimport)
  28  #endif
  29  #define QEMU_PLUGIN_LOCAL
  30#else
  31  #define QEMU_PLUGIN_EXPORT __attribute__((visibility("default")))
  32  #define QEMU_PLUGIN_LOCAL  __attribute__((visibility("hidden")))
  33#endif
  34
  35/**
  36 * typedef qemu_plugin_id_t - Unique plugin ID
  37 */
  38typedef uint64_t qemu_plugin_id_t;
  39
  40/*
  41 * Versioning plugins:
  42 *
  43 * The plugin API will pass a minimum and current API version that
  44 * QEMU currently supports. The minimum API will be incremented if an
  45 * API needs to be deprecated.
  46 *
  47 * The plugins export the API they were built against by exposing the
  48 * symbol qemu_plugin_version which can be checked.
  49 */
  50
  51extern QEMU_PLUGIN_EXPORT int qemu_plugin_version;
  52
  53#define QEMU_PLUGIN_VERSION 1
  54
  55/**
  56 * struct qemu_info_t - system information for plugins
  57 *
  58 * This structure provides for some limited information about the
  59 * system to allow the plugin to make decisions on how to proceed. For
  60 * example it might only be suitable for running on some guest
  61 * architectures or when under full system emulation.
  62 */
  63typedef struct qemu_info_t {
  64    /** @target_name: string describing architecture */
  65    const char *target_name;
  66    /** @version: minimum and current plugin API level */
  67    struct {
  68        int min;
  69        int cur;
  70    } version;
  71    /** @system_emulation: is this a full system emulation? */
  72    bool system_emulation;
  73    union {
  74        /** @system: information relevant to system emulation */
  75        struct {
  76            /** @system.smp_vcpus: initial number of vCPUs */
  77            int smp_vcpus;
  78            /** @system.max_vcpus: maximum possible number of vCPUs */
  79            int max_vcpus;
  80        } system;
  81    };
  82} qemu_info_t;
  83
  84/**
  85 * qemu_plugin_install() - Install a plugin
  86 * @id: this plugin's opaque ID
  87 * @info: a block describing some details about the guest
  88 * @argc: number of arguments
  89 * @argv: array of arguments (@argc elements)
  90 *
  91 * All plugins must export this symbol which is called when the plugin
  92 * is first loaded. Calling qemu_plugin_uninstall() from this function
  93 * is a bug.
  94 *
  95 * Note: @info is only live during the call. Copy any information we
  96 * want to keep. @argv remains valid throughout the lifetime of the
  97 * loaded plugin.
  98 *
  99 * Return: 0 on successful loading, !0 for an error.
 100 */
 101QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
 102                                           const qemu_info_t *info,
 103                                           int argc, char **argv);
 104
 105/**
 106 * typedef qemu_plugin_simple_cb_t - simple callback
 107 * @id: the unique qemu_plugin_id_t
 108 *
 109 * This callback passes no information aside from the unique @id.
 110 */
 111typedef void (*qemu_plugin_simple_cb_t)(qemu_plugin_id_t id);
 112
 113/**
 114 * typedef qemu_plugin_udata_cb_t - callback with user data
 115 * @id: the unique qemu_plugin_id_t
 116 * @userdata: a pointer to some user data supplied when the callback
 117 * was registered.
 118 */
 119typedef void (*qemu_plugin_udata_cb_t)(qemu_plugin_id_t id, void *userdata);
 120
 121/**
 122 * typedef qemu_plugin_vcpu_simple_cb_t - vcpu callback
 123 * @id: the unique qemu_plugin_id_t
 124 * @vcpu_index: the current vcpu context
 125 */
 126typedef void (*qemu_plugin_vcpu_simple_cb_t)(qemu_plugin_id_t id,
 127                                             unsigned int vcpu_index);
 128
 129/**
 130 * typedef qemu_plugin_vcpu_udata_cb_t - vcpu callback
 131 * @vcpu_index: the current vcpu context
 132 * @userdata: a pointer to some user data supplied when the callback
 133 * was registered.
 134 */
 135typedef void (*qemu_plugin_vcpu_udata_cb_t)(unsigned int vcpu_index,
 136                                            void *userdata);
 137
 138/**
 139 * qemu_plugin_uninstall() - Uninstall a plugin
 140 * @id: this plugin's opaque ID
 141 * @cb: callback to be called once the plugin has been removed
 142 *
 143 * Do NOT assume that the plugin has been uninstalled once this function
 144 * returns. Plugins are uninstalled asynchronously, and therefore the given
 145 * plugin receives callbacks until @cb is called.
 146 *
 147 * Note: Calling this function from qemu_plugin_install() is a bug.
 148 */
 149void qemu_plugin_uninstall(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb);
 150
 151/**
 152 * qemu_plugin_reset() - Reset a plugin
 153 * @id: this plugin's opaque ID
 154 * @cb: callback to be called once the plugin has been reset
 155 *
 156 * Unregisters all callbacks for the plugin given by @id.
 157 *
 158 * Do NOT assume that the plugin has been reset once this function returns.
 159 * Plugins are reset asynchronously, and therefore the given plugin receives
 160 * callbacks until @cb is called.
 161 */
 162void qemu_plugin_reset(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb);
 163
 164/**
 165 * qemu_plugin_register_vcpu_init_cb() - register a vCPU initialization callback
 166 * @id: plugin ID
 167 * @cb: callback function
 168 *
 169 * The @cb function is called every time a vCPU is initialized.
 170 *
 171 * See also: qemu_plugin_register_vcpu_exit_cb()
 172 */
 173void qemu_plugin_register_vcpu_init_cb(qemu_plugin_id_t id,
 174                                       qemu_plugin_vcpu_simple_cb_t cb);
 175
 176/**
 177 * qemu_plugin_register_vcpu_exit_cb() - register a vCPU exit callback
 178 * @id: plugin ID
 179 * @cb: callback function
 180 *
 181 * The @cb function is called every time a vCPU exits.
 182 *
 183 * See also: qemu_plugin_register_vcpu_init_cb()
 184 */
 185void qemu_plugin_register_vcpu_exit_cb(qemu_plugin_id_t id,
 186                                       qemu_plugin_vcpu_simple_cb_t cb);
 187
 188/**
 189 * qemu_plugin_register_vcpu_idle_cb() - register a vCPU idle callback
 190 * @id: plugin ID
 191 * @cb: callback function
 192 *
 193 * The @cb function is called every time a vCPU idles.
 194 */
 195void qemu_plugin_register_vcpu_idle_cb(qemu_plugin_id_t id,
 196                                       qemu_plugin_vcpu_simple_cb_t cb);
 197
 198/**
 199 * qemu_plugin_register_vcpu_resume_cb() - register a vCPU resume callback
 200 * @id: plugin ID
 201 * @cb: callback function
 202 *
 203 * The @cb function is called every time a vCPU resumes execution.
 204 */
 205void qemu_plugin_register_vcpu_resume_cb(qemu_plugin_id_t id,
 206                                         qemu_plugin_vcpu_simple_cb_t cb);
 207
 208/** struct qemu_plugin_tb - Opaque handle for a translation block */
 209struct qemu_plugin_tb;
 210/** struct qemu_plugin_insn - Opaque handle for a translated instruction */
 211struct qemu_plugin_insn;
 212
 213/**
 214 * enum qemu_plugin_cb_flags - type of callback
 215 *
 216 * @QEMU_PLUGIN_CB_NO_REGS: callback does not access the CPU's regs
 217 * @QEMU_PLUGIN_CB_R_REGS: callback reads the CPU's regs
 218 * @QEMU_PLUGIN_CB_RW_REGS: callback reads and writes the CPU's regs
 219 *
 220 * Note: currently unused, plugins cannot read or change system
 221 * register state.
 222 */
 223enum qemu_plugin_cb_flags {
 224    QEMU_PLUGIN_CB_NO_REGS,
 225    QEMU_PLUGIN_CB_R_REGS,
 226    QEMU_PLUGIN_CB_RW_REGS,
 227};
 228
 229enum qemu_plugin_mem_rw {
 230    QEMU_PLUGIN_MEM_R = 1,
 231    QEMU_PLUGIN_MEM_W,
 232    QEMU_PLUGIN_MEM_RW,
 233};
 234
 235/**
 236 * typedef qemu_plugin_vcpu_tb_trans_cb_t - translation callback
 237 * @id: unique plugin id
 238 * @tb: opaque handle used for querying and instrumenting a block.
 239 */
 240typedef void (*qemu_plugin_vcpu_tb_trans_cb_t)(qemu_plugin_id_t id,
 241                                               struct qemu_plugin_tb *tb);
 242
 243/**
 244 * qemu_plugin_register_vcpu_tb_trans_cb() - register a translate cb
 245 * @id: plugin ID
 246 * @cb: callback function
 247 *
 248 * The @cb function is called every time a translation occurs. The @cb
 249 * function is passed an opaque qemu_plugin_type which it can query
 250 * for additional information including the list of translated
 251 * instructions. At this point the plugin can register further
 252 * callbacks to be triggered when the block or individual instruction
 253 * executes.
 254 */
 255void qemu_plugin_register_vcpu_tb_trans_cb(qemu_plugin_id_t id,
 256                                           qemu_plugin_vcpu_tb_trans_cb_t cb);
 257
 258/**
 259 * qemu_plugin_register_vcpu_tb_exec_cb() - register execution callback
 260 * @tb: the opaque qemu_plugin_tb handle for the translation
 261 * @cb: callback function
 262 * @flags: does the plugin read or write the CPU's registers?
 263 * @userdata: any plugin data to pass to the @cb?
 264 *
 265 * The @cb function is called every time a translated unit executes.
 266 */
 267void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb,
 268                                          qemu_plugin_vcpu_udata_cb_t cb,
 269                                          enum qemu_plugin_cb_flags flags,
 270                                          void *userdata);
 271
 272/**
 273 * enum qemu_plugin_op - describes an inline op
 274 *
 275 * @QEMU_PLUGIN_INLINE_ADD_U64: add an immediate value uint64_t
 276 *
 277 * Note: currently only a single inline op is supported.
 278 */
 279
 280enum qemu_plugin_op {
 281    QEMU_PLUGIN_INLINE_ADD_U64,
 282};
 283
 284/**
 285 * qemu_plugin_register_vcpu_tb_exec_inline() - execution inline op
 286 * @tb: the opaque qemu_plugin_tb handle for the translation
 287 * @op: the type of qemu_plugin_op (e.g. ADD_U64)
 288 * @ptr: the target memory location for the op
 289 * @imm: the op data (e.g. 1)
 290 *
 291 * Insert an inline op to every time a translated unit executes.
 292 * Useful if you just want to increment a single counter somewhere in
 293 * memory.
 294 *
 295 * Note: ops are not atomic so in multi-threaded/multi-smp situations
 296 * you will get inexact results.
 297 */
 298void qemu_plugin_register_vcpu_tb_exec_inline(struct qemu_plugin_tb *tb,
 299                                              enum qemu_plugin_op op,
 300                                              void *ptr, uint64_t imm);
 301
 302/**
 303 * qemu_plugin_register_vcpu_insn_exec_cb() - register insn execution cb
 304 * @insn: the opaque qemu_plugin_insn handle for an instruction
 305 * @cb: callback function
 306 * @flags: does the plugin read or write the CPU's registers?
 307 * @userdata: any plugin data to pass to the @cb?
 308 *
 309 * The @cb function is called every time an instruction is executed
 310 */
 311void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn,
 312                                            qemu_plugin_vcpu_udata_cb_t cb,
 313                                            enum qemu_plugin_cb_flags flags,
 314                                            void *userdata);
 315
 316/**
 317 * qemu_plugin_register_vcpu_insn_exec_inline() - insn execution inline op
 318 * @insn: the opaque qemu_plugin_insn handle for an instruction
 319 * @op: the type of qemu_plugin_op (e.g. ADD_U64)
 320 * @ptr: the target memory location for the op
 321 * @imm: the op data (e.g. 1)
 322 *
 323 * Insert an inline op to every time an instruction executes. Useful
 324 * if you just want to increment a single counter somewhere in memory.
 325 */
 326void qemu_plugin_register_vcpu_insn_exec_inline(struct qemu_plugin_insn *insn,
 327                                                enum qemu_plugin_op op,
 328                                                void *ptr, uint64_t imm);
 329
 330/**
 331 * qemu_plugin_tb_n_insns() - query helper for number of insns in TB
 332 * @tb: opaque handle to TB passed to callback
 333 *
 334 * Returns: number of instructions in this block
 335 */
 336size_t qemu_plugin_tb_n_insns(const struct qemu_plugin_tb *tb);
 337
 338/**
 339 * qemu_plugin_tb_vaddr() - query helper for vaddr of TB start
 340 * @tb: opaque handle to TB passed to callback
 341 *
 342 * Returns: virtual address of block start
 343 */
 344uint64_t qemu_plugin_tb_vaddr(const struct qemu_plugin_tb *tb);
 345
 346/**
 347 * qemu_plugin_tb_get_insn() - retrieve handle for instruction
 348 * @tb: opaque handle to TB passed to callback
 349 * @idx: instruction number, 0 indexed
 350 *
 351 * The returned handle can be used in follow up helper queries as well
 352 * as when instrumenting an instruction. It is only valid for the
 353 * lifetime of the callback.
 354 *
 355 * Returns: opaque handle to instruction
 356 */
 357struct qemu_plugin_insn *
 358qemu_plugin_tb_get_insn(const struct qemu_plugin_tb *tb, size_t idx);
 359
 360/**
 361 * qemu_plugin_insn_data() - return ptr to instruction data
 362 * @insn: opaque instruction handle from qemu_plugin_tb_get_insn()
 363 *
 364 * Note: data is only valid for duration of callback. See
 365 * qemu_plugin_insn_size() to calculate size of stream.
 366 *
 367 * Returns: pointer to a stream of bytes containing the value of this
 368 * instructions opcode.
 369 */
 370const void *qemu_plugin_insn_data(const struct qemu_plugin_insn *insn);
 371
 372/**
 373 * qemu_plugin_insn_size() - return size of instruction
 374 * @insn: opaque instruction handle from qemu_plugin_tb_get_insn()
 375 *
 376 * Returns: size of instruction in bytes
 377 */
 378size_t qemu_plugin_insn_size(const struct qemu_plugin_insn *insn);
 379
 380/**
 381 * qemu_plugin_insn_vaddr() - return vaddr of instruction
 382 * @insn: opaque instruction handle from qemu_plugin_tb_get_insn()
 383 *
 384 * Returns: virtual address of instruction
 385 */
 386uint64_t qemu_plugin_insn_vaddr(const struct qemu_plugin_insn *insn);
 387
 388/**
 389 * qemu_plugin_insn_haddr() - return hardware addr of instruction
 390 * @insn: opaque instruction handle from qemu_plugin_tb_get_insn()
 391 *
 392 * Returns: hardware (physical) target address of instruction
 393 */
 394void *qemu_plugin_insn_haddr(const struct qemu_plugin_insn *insn);
 395
 396/**
 397 * typedef qemu_plugin_meminfo_t - opaque memory transaction handle
 398 *
 399 * This can be further queried using the qemu_plugin_mem_* query
 400 * functions.
 401 */
 402typedef uint32_t qemu_plugin_meminfo_t;
 403/** struct qemu_plugin_hwaddr - opaque hw address handle */
 404struct qemu_plugin_hwaddr;
 405
 406/**
 407 * qemu_plugin_mem_size_shift() - get size of access
 408 * @info: opaque memory transaction handle
 409 *
 410 * Returns: size of access in ^2 (0=byte, 1=16bit, 2=32bit etc...)
 411 */
 412unsigned int qemu_plugin_mem_size_shift(qemu_plugin_meminfo_t info);
 413/**
 414 * qemu_plugin_mem_is_sign_extended() - was the access sign extended
 415 * @info: opaque memory transaction handle
 416 *
 417 * Returns: true if it was, otherwise false
 418 */
 419bool qemu_plugin_mem_is_sign_extended(qemu_plugin_meminfo_t info);
 420/**
 421 * qemu_plugin_mem_is_big_endian() - was the access big endian
 422 * @info: opaque memory transaction handle
 423 *
 424 * Returns: true if it was, otherwise false
 425 */
 426bool qemu_plugin_mem_is_big_endian(qemu_plugin_meminfo_t info);
 427/**
 428 * qemu_plugin_mem_is_store() - was the access a store
 429 * @info: opaque memory transaction handle
 430 *
 431 * Returns: true if it was, otherwise false
 432 */
 433bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info);
 434
 435/**
 436 * qemu_plugin_get_hwaddr() - return handle for memory operation
 437 * @info: opaque memory info structure
 438 * @vaddr: the virtual address of the memory operation
 439 *
 440 * For system emulation returns a qemu_plugin_hwaddr handle to query
 441 * details about the actual physical address backing the virtual
 442 * address. For linux-user guests it just returns NULL.
 443 *
 444 * This handle is *only* valid for the duration of the callback. Any
 445 * information about the handle should be recovered before the
 446 * callback returns.
 447 */
 448struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
 449                                                  uint64_t vaddr);
 450
 451/*
 452 * The following additional queries can be run on the hwaddr structure to
 453 * return information about it - namely whether it is for an IO access and the
 454 * physical address associated with the access.
 455 */
 456
 457/**
 458 * qemu_plugin_hwaddr_is_io() - query whether memory operation is IO
 459 * @haddr: address handle from qemu_plugin_get_hwaddr()
 460 *
 461 * Returns true if the handle's memory operation is to memory-mapped IO, or
 462 * false if it is to RAM
 463 */
 464bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr);
 465
 466/**
 467 * qemu_plugin_hwaddr_phys_addr() - query physical address for memory operation
 468 * @haddr: address handle from qemu_plugin_get_hwaddr()
 469 *
 470 * Returns the physical address associated with the memory operation
 471 *
 472 * Note that the returned physical address may not be unique if you are dealing
 473 * with multiple address spaces.
 474 */
 475uint64_t qemu_plugin_hwaddr_phys_addr(const struct qemu_plugin_hwaddr *haddr);
 476
 477/*
 478 * Returns a string representing the device. The string is valid for
 479 * the lifetime of the plugin.
 480 */
 481const char *qemu_plugin_hwaddr_device_name(const struct qemu_plugin_hwaddr *h);
 482
 483typedef void
 484(*qemu_plugin_vcpu_mem_cb_t)(unsigned int vcpu_index,
 485                             qemu_plugin_meminfo_t info, uint64_t vaddr,
 486                             void *userdata);
 487
 488void qemu_plugin_register_vcpu_mem_cb(struct qemu_plugin_insn *insn,
 489                                      qemu_plugin_vcpu_mem_cb_t cb,
 490                                      enum qemu_plugin_cb_flags flags,
 491                                      enum qemu_plugin_mem_rw rw,
 492                                      void *userdata);
 493
 494void qemu_plugin_register_vcpu_mem_inline(struct qemu_plugin_insn *insn,
 495                                          enum qemu_plugin_mem_rw rw,
 496                                          enum qemu_plugin_op op, void *ptr,
 497                                          uint64_t imm);
 498
 499
 500
 501typedef void
 502(*qemu_plugin_vcpu_syscall_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_index,
 503                                 int64_t num, uint64_t a1, uint64_t a2,
 504                                 uint64_t a3, uint64_t a4, uint64_t a5,
 505                                 uint64_t a6, uint64_t a7, uint64_t a8);
 506
 507void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
 508                                          qemu_plugin_vcpu_syscall_cb_t cb);
 509
 510typedef void
 511(*qemu_plugin_vcpu_syscall_ret_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_idx,
 512                                     int64_t num, int64_t ret);
 513
 514void
 515qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
 516                                         qemu_plugin_vcpu_syscall_ret_cb_t cb);
 517
 518
 519/**
 520 * qemu_plugin_insn_disas() - return disassembly string for instruction
 521 * @insn: instruction reference
 522 *
 523 * Returns an allocated string containing the disassembly
 524 */
 525
 526char *qemu_plugin_insn_disas(const struct qemu_plugin_insn *insn);
 527
 528/**
 529 * qemu_plugin_vcpu_for_each() - iterate over the existing vCPU
 530 * @id: plugin ID
 531 * @cb: callback function
 532 *
 533 * The @cb function is called once for each existing vCPU.
 534 *
 535 * See also: qemu_plugin_register_vcpu_init_cb()
 536 */
 537void qemu_plugin_vcpu_for_each(qemu_plugin_id_t id,
 538                               qemu_plugin_vcpu_simple_cb_t cb);
 539
 540void qemu_plugin_register_flush_cb(qemu_plugin_id_t id,
 541                                   qemu_plugin_simple_cb_t cb);
 542
 543void qemu_plugin_register_atexit_cb(qemu_plugin_id_t id,
 544                                    qemu_plugin_udata_cb_t cb, void *userdata);
 545
 546/* returns -1 in user-mode */
 547int qemu_plugin_n_vcpus(void);
 548
 549/* returns -1 in user-mode */
 550int qemu_plugin_n_max_vcpus(void);
 551
 552/**
 553 * qemu_plugin_outs() - output string via QEMU's logging system
 554 * @string: a string
 555 */
 556void qemu_plugin_outs(const char *string);
 557
 558#endif /* QEMU_PLUGIN_API_H */
 559