plugin.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * Plugin Shared Internal Functions
  3. *
  4. * Copyright (C) 2019, Linaro
  5. *
  6. * License: GNU GPL, version 2 or later.
  7. * See the COPYING file in the top-level directory.
  8. *
  9. * SPDX-License-Identifier: GPL-2.0-or-later
  10. */
  11. #ifndef PLUGIN_H
  12. #define PLUGIN_H
  13. #include <gmodule.h>
  14. #include "qemu/qht.h"
  15. #define QEMU_PLUGIN_MIN_VERSION 0
  16. /* global state */
  17. struct qemu_plugin_state {
  18. QTAILQ_HEAD(, qemu_plugin_ctx) ctxs;
  19. QLIST_HEAD(, qemu_plugin_cb) cb_lists[QEMU_PLUGIN_EV_MAX];
  20. /*
  21. * Use the HT as a hash map by inserting k == v, which saves memory as
  22. * documented by GLib. The parent struct is obtained with container_of().
  23. */
  24. GHashTable *id_ht;
  25. /*
  26. * Use the HT as a hash map. Note that we could use a list here,
  27. * but with the HT we avoid adding a field to CPUState.
  28. */
  29. GHashTable *cpu_ht;
  30. DECLARE_BITMAP(mask, QEMU_PLUGIN_EV_MAX);
  31. /*
  32. * @lock protects the struct as well as ctx->uninstalling.
  33. * The lock must be acquired by all API ops.
  34. * The lock is recursive, which greatly simplifies things, e.g.
  35. * callback registration from qemu_plugin_vcpu_for_each().
  36. */
  37. QemuRecMutex lock;
  38. /*
  39. * HT of callbacks invoked from helpers. All entries are freed when
  40. * the code cache is flushed.
  41. */
  42. struct qht dyn_cb_arr_ht;
  43. };
  44. struct qemu_plugin_ctx {
  45. GModule *handle;
  46. qemu_plugin_id_t id;
  47. struct qemu_plugin_cb *callbacks[QEMU_PLUGIN_EV_MAX];
  48. QTAILQ_ENTRY(qemu_plugin_ctx) entry;
  49. /*
  50. * keep a reference to @desc until uninstall, so that plugins do not have
  51. * to strdup plugin args.
  52. */
  53. struct qemu_plugin_desc *desc;
  54. bool installing;
  55. bool uninstalling;
  56. bool resetting;
  57. };
  58. struct qemu_plugin_ctx *plugin_id_to_ctx_locked(qemu_plugin_id_t id);
  59. void plugin_register_inline_op(GArray **arr,
  60. enum qemu_plugin_mem_rw rw,
  61. enum qemu_plugin_op op, void *ptr,
  62. uint64_t imm);
  63. void plugin_reset_uninstall(qemu_plugin_id_t id,
  64. qemu_plugin_simple_cb_t cb,
  65. bool reset);
  66. void plugin_register_cb(qemu_plugin_id_t id, enum qemu_plugin_event ev,
  67. void *func);
  68. void plugin_unregister_cb__locked(struct qemu_plugin_ctx *ctx,
  69. enum qemu_plugin_event ev);
  70. void
  71. plugin_register_cb_udata(qemu_plugin_id_t id, enum qemu_plugin_event ev,
  72. void *func, void *udata);
  73. void
  74. plugin_register_dyn_cb__udata(GArray **arr,
  75. qemu_plugin_vcpu_udata_cb_t cb,
  76. enum qemu_plugin_cb_flags flags, void *udata);
  77. void plugin_register_vcpu_mem_cb(GArray **arr,
  78. void *cb,
  79. enum qemu_plugin_cb_flags flags,
  80. enum qemu_plugin_mem_rw rw,
  81. void *udata);
  82. void exec_inline_op(struct qemu_plugin_dyn_cb *cb);
  83. #endif /* PLUGIN_H */