xref: /openbmc/qemu/plugins/plugin.h (revision 85ef20f1673feaa083f4acab8cf054df77b0dbed)
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  
12  #ifndef PLUGIN_H
13  #define PLUGIN_H
14  
15  #include <gmodule.h>
16  #include "qemu/qht.h"
17  
18  #define QEMU_PLUGIN_MIN_VERSION 2
19  
20  /* global state */
21  struct qemu_plugin_state {
22      QTAILQ_HEAD(, qemu_plugin_ctx) ctxs;
23      QLIST_HEAD(, qemu_plugin_cb) cb_lists[QEMU_PLUGIN_EV_MAX];
24      /*
25       * Use the HT as a hash map by inserting k == v, which saves memory as
26       * documented by GLib. The parent struct is obtained with container_of().
27       */
28      GHashTable *id_ht;
29      /*
30       * Use the HT as a hash map. Note that we could use a list here,
31       * but with the HT we avoid adding a field to CPUState.
32       */
33      GHashTable *cpu_ht;
34      QLIST_HEAD(, qemu_plugin_scoreboard) scoreboards;
35      size_t scoreboard_alloc_size;
36      DECLARE_BITMAP(mask, QEMU_PLUGIN_EV_MAX);
37      /*
38       * @lock protects the struct as well as ctx->uninstalling.
39       * The lock must be acquired by all API ops.
40       * The lock is recursive, which greatly simplifies things, e.g.
41       * callback registration from qemu_plugin_vcpu_for_each().
42       */
43      QemuRecMutex lock;
44      /*
45       * HT of callbacks invoked from helpers. All entries are freed when
46       * the code cache is flushed.
47       */
48      struct qht dyn_cb_arr_ht;
49      /* How many vcpus were started */
50      int num_vcpus;
51  };
52  
53  
54  struct qemu_plugin_ctx {
55      GModule *handle;
56      qemu_plugin_id_t id;
57      struct qemu_plugin_cb *callbacks[QEMU_PLUGIN_EV_MAX];
58      QTAILQ_ENTRY(qemu_plugin_ctx) entry;
59      /*
60       * keep a reference to @desc until uninstall, so that plugins do not have
61       * to strdup plugin args.
62       */
63      struct qemu_plugin_desc *desc;
64      bool installing;
65      bool uninstalling;
66      bool resetting;
67  };
68  
69  struct qemu_plugin_ctx *plugin_id_to_ctx_locked(qemu_plugin_id_t id);
70  
71  void plugin_register_inline_op_on_entry(GArray **arr,
72                                          enum qemu_plugin_mem_rw rw,
73                                          enum qemu_plugin_op op,
74                                          qemu_plugin_u64 entry,
75                                          uint64_t imm);
76  
77  void plugin_reset_uninstall(qemu_plugin_id_t id,
78                              qemu_plugin_simple_cb_t cb,
79                              bool reset);
80  
81  void plugin_register_cb(qemu_plugin_id_t id, enum qemu_plugin_event ev,
82                          void *func);
83  
84  void plugin_unregister_cb__locked(struct qemu_plugin_ctx *ctx,
85                                    enum qemu_plugin_event ev);
86  
87  void
88  plugin_register_cb_udata(qemu_plugin_id_t id, enum qemu_plugin_event ev,
89                           void *func, void *udata);
90  
91  void
92  plugin_register_dyn_cb__udata(GArray **arr,
93                                qemu_plugin_vcpu_udata_cb_t cb,
94                                enum qemu_plugin_cb_flags flags, void *udata);
95  
96  void
97  plugin_register_dyn_cond_cb__udata(GArray **arr,
98                                     qemu_plugin_vcpu_udata_cb_t cb,
99                                     enum qemu_plugin_cb_flags flags,
100                                     enum qemu_plugin_cond cond,
101                                     qemu_plugin_u64 entry,
102                                     uint64_t imm,
103                                     void *udata);
104  
105  void plugin_register_vcpu_mem_cb(GArray **arr,
106                                   void *cb,
107                                   enum qemu_plugin_cb_flags flags,
108                                   enum qemu_plugin_mem_rw rw,
109                                   void *udata);
110  
111  void exec_inline_op(enum plugin_dyn_cb_type type,
112                      struct qemu_plugin_inline_cb *cb,
113                      int cpu_index);
114  
115  int plugin_num_vcpus(void);
116  
117  struct qemu_plugin_scoreboard *plugin_scoreboard_new(size_t element_size);
118  
119  void plugin_scoreboard_free(struct qemu_plugin_scoreboard *score);
120  
121  #endif /* PLUGIN_H */
122