plugin.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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 2
  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. QLIST_HEAD(, qemu_plugin_scoreboard) scoreboards;
  31. size_t scoreboard_alloc_size;
  32. DECLARE_BITMAP(mask, QEMU_PLUGIN_EV_MAX);
  33. /*
  34. * @lock protects the struct as well as ctx->uninstalling.
  35. * The lock must be acquired by all API ops.
  36. * The lock is recursive, which greatly simplifies things, e.g.
  37. * callback registration from qemu_plugin_vcpu_for_each().
  38. */
  39. QemuRecMutex lock;
  40. /*
  41. * HT of callbacks invoked from helpers. All entries are freed when
  42. * the code cache is flushed.
  43. */
  44. struct qht dyn_cb_arr_ht;
  45. /* How many vcpus were started */
  46. int num_vcpus;
  47. };
  48. struct qemu_plugin_ctx {
  49. GModule *handle;
  50. qemu_plugin_id_t id;
  51. struct qemu_plugin_cb *callbacks[QEMU_PLUGIN_EV_MAX];
  52. QTAILQ_ENTRY(qemu_plugin_ctx) entry;
  53. /*
  54. * keep a reference to @desc until uninstall, so that plugins do not have
  55. * to strdup plugin args.
  56. */
  57. struct qemu_plugin_desc *desc;
  58. bool installing;
  59. bool uninstalling;
  60. bool resetting;
  61. };
  62. struct qemu_plugin_ctx *plugin_id_to_ctx_locked(qemu_plugin_id_t id);
  63. void plugin_register_inline_op_on_entry(GArray **arr,
  64. enum qemu_plugin_mem_rw rw,
  65. enum qemu_plugin_op op,
  66. qemu_plugin_u64 entry,
  67. uint64_t imm);
  68. void plugin_reset_uninstall(qemu_plugin_id_t id,
  69. qemu_plugin_simple_cb_t cb,
  70. bool reset);
  71. void plugin_register_cb(qemu_plugin_id_t id, enum qemu_plugin_event ev,
  72. void *func);
  73. void plugin_unregister_cb__locked(struct qemu_plugin_ctx *ctx,
  74. enum qemu_plugin_event ev);
  75. void
  76. plugin_register_cb_udata(qemu_plugin_id_t id, enum qemu_plugin_event ev,
  77. void *func, void *udata);
  78. void
  79. plugin_register_dyn_cb__udata(GArray **arr,
  80. qemu_plugin_vcpu_udata_cb_t cb,
  81. enum qemu_plugin_cb_flags flags, void *udata);
  82. void
  83. plugin_register_dyn_cond_cb__udata(GArray **arr,
  84. qemu_plugin_vcpu_udata_cb_t cb,
  85. enum qemu_plugin_cb_flags flags,
  86. enum qemu_plugin_cond cond,
  87. qemu_plugin_u64 entry,
  88. uint64_t imm,
  89. void *udata);
  90. void plugin_register_vcpu_mem_cb(GArray **arr,
  91. void *cb,
  92. enum qemu_plugin_cb_flags flags,
  93. enum qemu_plugin_mem_rw rw,
  94. void *udata);
  95. void exec_inline_op(struct qemu_plugin_dyn_cb *cb, int cpu_index);
  96. int plugin_num_vcpus(void);
  97. struct qemu_plugin_scoreboard *plugin_scoreboard_new(size_t element_size);
  98. void plugin_scoreboard_free(struct qemu_plugin_scoreboard *score);
  99. #endif /* PLUGIN_H */