All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Emilio G. Cota" <cota@braap.org>
To: qemu-devel@nongnu.org
Cc: "Alex Bennée" <alex.bennee@linaro.org>,
	"Richard Henderson" <richard.henderson@linaro.org>,
	"Pavel Dovgalyuk" <Pavel.Dovgaluk@ispras.ru>
Subject: [Qemu-devel] [RFC v2 05/38] plugin: add user-facing API
Date: Sun,  9 Dec 2018 14:37:16 -0500	[thread overview]
Message-ID: <20181209193749.12277-6-cota@braap.org> (raw)
In-Reply-To: <20181209193749.12277-1-cota@braap.org>

Add the API first to ease review.

Signed-off-by: Emilio G. Cota <cota@braap.org>
---
 include/qemu/qemu-plugin.h | 241 +++++++++++++++++++++++++++++++++++++
 1 file changed, 241 insertions(+)
 create mode 100644 include/qemu/qemu-plugin.h

diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h
new file mode 100644
index 0000000000..6c67211900
--- /dev/null
+++ b/include/qemu/qemu-plugin.h
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2017, Emilio G. Cota <cota@braap.org>
+ *
+ * License: GNU GPL, version 2 or later.
+ *   See the COPYING file in the top-level directory.
+ */
+#ifndef QEMU_PLUGIN_API_H
+#define QEMU_PLUGIN_API_H
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+/*
+ * For best performance, build the plugin with -fvisibility=hidden so that
+ * QEMU_PLUGIN_LOCAL is implicit. Then, just mark qemu_plugin_install with
+ * QEMU_PLUGIN_EXPORT. For more info, see
+ *   https://gcc.gnu.org/wiki/Visibility
+ */
+#if defined _WIN32 || defined __CYGWIN__
+  #ifdef BUILDING_DLL
+    #define QEMU_PLUGIN_EXPORT __declspec(dllexport)
+  #else
+    #define QEMU_PLUGIN_EXPORT __declspec(dllimport)
+  #endif
+  #define QEMU_PLUGIN_LOCAL
+#else
+  #if __GNUC__ >= 4
+    #define QEMU_PLUGIN_EXPORT __attribute__((visibility("default")))
+    #define QEMU_PLUGIN_LOCAL  __attribute__((visibility("hidden")))
+  #else
+    #define QEMU_PLUGIN_EXPORT
+    #define QEMU_PLUGIN_LOCAL
+  #endif
+#endif
+
+typedef uint64_t qemu_plugin_id_t;
+
+/**
+ * qemu_plugin_install - Install a plugin
+ * @id: this plugin's opaque ID
+ * @argc: number of arguments
+ * @argv: array of arguments (@argc elements)
+ *
+ * All plugins must export this symbol.
+ *
+ * Note: @argv is freed after this function returns.
+ */
+QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, int argc,
+                                           char **argv);
+
+typedef void (*qemu_plugin_uninstall_cb_t)(qemu_plugin_id_t id);
+
+/**
+ * qemu_plugin_uninstall - Uninstall a plugin
+ * @id: this plugin's opaque ID
+ * @cb: callback to be called once the plugin has been removed
+ *
+ * Do NOT assume that the plugin has been uninstalled once this
+ * function returns. Plugins are uninstalled asynchronously,
+ * and therefore the given plugin might still receive callbacks
+ * from prior subscriptions _until_ @cb is called.
+ */
+void qemu_plugin_uninstall(qemu_plugin_id_t id, qemu_plugin_uninstall_cb_t cb);
+
+typedef void (*qemu_plugin_simple_cb_t)(qemu_plugin_id_t id);
+
+typedef void (*qemu_plugin_udata_cb_t)(qemu_plugin_id_t id, void *userdata);
+
+typedef void (*qemu_plugin_vcpu_simple_cb_t)(qemu_plugin_id_t id,
+                                             unsigned int vcpu_index);
+
+typedef void (*qemu_plugin_vcpu_udata_cb_t)(unsigned int vcpu_index,
+                                            void *userdata);
+
+/**
+ * qemu_plugin_register_vcpu_init_cb - register a vCPU initialization callback
+ * @id: plugin ID
+ * @cb: callback function
+ *
+ * The @cb function is called every time a vCPU is initialized.
+ *
+ * See also: qemu_plugin_register_vcpu_exit_cb()
+ */
+void qemu_plugin_register_vcpu_init_cb(qemu_plugin_id_t id,
+                                       qemu_plugin_vcpu_simple_cb_t cb);
+
+/**
+ * qemu_plugin_register_vcpu_exit_cb - register a vCPU exit callback
+ * @id: plugin ID
+ * @cb: callback function
+ *
+ * The @cb function is called every time a vCPU exits.
+ *
+ * See also: qemu_plugin_register_vcpu_init_cb()
+ */
+void qemu_plugin_register_vcpu_exit_cb(qemu_plugin_id_t id,
+                                       qemu_plugin_vcpu_simple_cb_t cb);
+
+void qemu_plugin_register_vcpu_idle_cb(qemu_plugin_id_t id,
+                                       qemu_plugin_vcpu_simple_cb_t cb);
+
+void qemu_plugin_register_vcpu_resume_cb(qemu_plugin_id_t id,
+                                         qemu_plugin_vcpu_simple_cb_t cb);
+
+struct qemu_plugin_tb;
+struct qemu_plugin_insn;
+
+enum qemu_plugin_cb_flags {
+    QEMU_PLUGIN_CB_NO_REGS, /* callback does not access the CPU's regs */
+    QEMU_PLUGIN_CB_R_REGS,  /* callback reads the CPU's regs */
+    QEMU_PLUGIN_CB_RW_REGS, /* callback reads and writes the CPU's regs */
+};
+
+enum qemu_plugin_mem_rw {
+    QEMU_PLUGIN_MEM_R = 1,
+    QEMU_PLUGIN_MEM_W,
+    QEMU_PLUGIN_MEM_RW,
+};
+
+typedef void (*qemu_plugin_vcpu_tb_trans_cb_t)(qemu_plugin_id_t id,
+                                               unsigned int vcpu_index,
+                                               struct qemu_plugin_tb *tb);
+
+void qemu_plugin_register_vcpu_tb_trans_cb(qemu_plugin_id_t id,
+                                           qemu_plugin_vcpu_tb_trans_cb_t cb);
+
+/* can only call from tb_trans_cb callback */
+void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb,
+                                          qemu_plugin_vcpu_udata_cb_t cb,
+                                          enum qemu_plugin_cb_flags flags,
+                                          void *userdata);
+
+enum qemu_plugin_op {
+    QEMU_PLUGIN_INLINE_ADD_U64,
+};
+
+void qemu_plugin_register_vcpu_tb_exec_inline(struct qemu_plugin_tb *tb,
+                                              enum qemu_plugin_op op,
+                                              void *ptr, uint64_t imm);
+
+void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn,
+                                            qemu_plugin_vcpu_udata_cb_t cb,
+                                            enum qemu_plugin_cb_flags flags,
+                                            void *userdata);
+
+void qemu_plugin_register_vcpu_insn_exec_inline(struct qemu_plugin_insn *insn,
+                                                enum qemu_plugin_op op,
+                                                void *ptr, uint64_t imm);
+
+typedef uint32_t qemu_plugin_meminfo_t;
+
+unsigned qemu_plugin_mem_size_shift(qemu_plugin_meminfo_t info);
+bool qemu_plugin_mem_is_sign_extended(qemu_plugin_meminfo_t info);
+bool qemu_plugin_mem_is_big_endian(qemu_plugin_meminfo_t info);
+bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info);
+
+typedef void
+(*qemu_plugin_vcpu_mem_cb_t)(unsigned int vcpu_index,
+                             qemu_plugin_meminfo_t info, uint64_t vaddr,
+                             void *userdata);
+
+typedef void
+(*qemu_plugin_vcpu_mem_haddr_cb_t)(unsigned int vcpu_index,
+                                   qemu_plugin_meminfo_t info, uint64_t vaddr,
+                                   void *haddr, void *userdata);
+
+void qemu_plugin_register_vcpu_mem_cb(struct qemu_plugin_insn *insn,
+                                      qemu_plugin_vcpu_mem_cb_t cb,
+                                      enum qemu_plugin_cb_flags flags,
+                                      enum qemu_plugin_mem_rw rw,
+                                      void *userdata);
+
+void qemu_plugin_register_vcpu_mem_haddr_cb(struct qemu_plugin_insn *insn,
+                                            qemu_plugin_vcpu_mem_haddr_cb_t cb,
+                                            enum qemu_plugin_cb_flags flags,
+                                            enum qemu_plugin_mem_rw rw,
+                                            void *userdata);
+
+void qemu_plugin_register_vcpu_mem_inline(struct qemu_plugin_insn *insn,
+                                          enum qemu_plugin_mem_rw rw,
+                                          enum qemu_plugin_op op, void *ptr,
+                                          uint64_t imm);
+
+uint64_t qemu_plugin_ram_addr_from_host(void *haddr);
+
+typedef void
+(*qemu_plugin_vcpu_syscall_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_index,
+                                 int64_t num, uint64_t a1, uint64_t a2,
+                                 uint64_t a3, uint64_t a4, uint64_t a5,
+                                 uint64_t a6, uint64_t a7, uint64_t a8);
+
+void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
+                                          qemu_plugin_vcpu_syscall_cb_t cb);
+
+typedef void
+(*qemu_plugin_vcpu_syscall_ret_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_idx,
+                                     int64_t num, int64_t ret);
+
+void
+qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
+                                         qemu_plugin_vcpu_syscall_ret_cb_t cb);
+
+size_t qemu_plugin_tb_n_insns(const struct qemu_plugin_tb *tb);
+
+uint64_t qemu_plugin_tb_vaddr(const struct qemu_plugin_tb *tb);
+
+struct qemu_plugin_insn *
+qemu_plugin_tb_get_insn(const struct qemu_plugin_tb *tb, size_t idx);
+
+const void *qemu_plugin_insn_data(const struct qemu_plugin_insn *insn);
+
+size_t qemu_plugin_insn_size(const struct qemu_plugin_insn *insn);
+
+uint64_t qemu_plugin_insn_vaddr(const struct qemu_plugin_insn *insn);
+void *qemu_plugin_insn_haddr(const struct qemu_plugin_insn *insn);
+
+/**
+ * qemu_plugin_vcpu_for_each - iterate over the existing vCPU
+ * @id: plugin ID
+ * @cb: callback function
+ *
+ * The @cb function is called once for each existing vCPU.
+ *
+ * See also: qemu_plugin_register_vcpu_init_cb()
+ */
+void qemu_plugin_vcpu_for_each(qemu_plugin_id_t id,
+                               qemu_plugin_vcpu_simple_cb_t cb);
+
+void qemu_plugin_register_flush_cb(qemu_plugin_id_t id,
+                                   qemu_plugin_simple_cb_t cb);
+
+void qemu_plugin_register_atexit_cb(qemu_plugin_id_t id,
+                                    qemu_plugin_udata_cb_t cb, void *userdata);
+
+/* returns -1 in user-mode */
+int qemu_plugin_n_vcpus(void);
+
+/* returns -1 in user-mode */
+int qemu_plugin_n_max_vcpus(void);
+
+#endif /* QEMU_PLUGIN_API_H */
-- 
2.17.1

  parent reply	other threads:[~2018-12-09 19:38 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-09 19:37 [Qemu-devel] [RFC v2 00/38] Plugin support Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 01/38] trace: expand mem_info:size_shift to 3 bits Emilio G. Cota
2019-01-24 14:42   ` Alex Bennée
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 02/38] tcg/README: fix typo s/afterwise/afterwards/ Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 03/38] cpu: introduce cpu_in_exclusive_work_context() Emilio G. Cota
2019-01-24 14:44   ` Alex Bennée
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 04/38] translate-all: use cpu_in_exclusive_work_context() in tb_flush Emilio G. Cota
2019-01-24 14:44   ` Alex Bennée
2018-12-09 19:37 ` Emilio G. Cota [this message]
2018-12-14 15:57   ` [Qemu-devel] [RFC v2 05/38] plugin: add user-facing API Aaron Lindsay
2018-12-14 16:04     ` Aaron Lindsay
2018-12-14 17:08     ` Emilio G. Cota
2018-12-14 17:50       ` Emilio G. Cota
2018-12-14 18:47         ` Aaron Lindsay
2018-12-14 19:40           ` Emilio G. Cota
2018-12-14 17:59       ` Aaron Lindsay
2018-12-14 18:23         ` Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 06/38] plugin: add core code Emilio G. Cota
2018-12-10 11:37   ` Pavel Dovgalyuk
2018-12-10 17:40     ` Emilio G. Cota
2019-01-24 15:57   ` Alex Bennée
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 07/38] queue: add QTAILQ_REMOVE_SEVERAL Emilio G. Cota
2019-02-25 16:22   ` Alex Bennée
2019-02-25 18:02     ` Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 08/38] tcg: drop nargs from tcg_op_insert_{before, after} Emilio G. Cota
2018-12-13 23:52   ` Richard Henderson
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 09/38] cputlb: introduce get_page_addr_code_hostp Emilio G. Cota
2019-01-24 14:51   ` Alex Bennée
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 10/38] plugin-gen: add module for TCG-related code Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 11/38] tcg: add tcg_gen_st_ptr Emilio G. Cota
2019-05-20 13:36   ` Alex Bennée
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 12/38] tcg: add MO_HADDR to TCGMemOp Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 13/38] atomic_template: fix indentation in GEN_ATOMIC_HELPER Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 14/38] atomic_template: add inline trace/plugin helpers Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 15/38] tcg: let plugins instrument memory accesses Emilio G. Cota
2019-01-24 14:39   ` Alex Bennée
2019-05-16 15:06     ` Alex Bennée
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 16/38] translate-all: notify plugin code of tb_flush Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 17/38] *-user: notify plugin of exit Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 18/38] *-user: plugin syscalls Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 19/38] cpu: hook plugin vcpu events Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 20/38] plugin-gen: add plugin_insn_append Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 21/38] translator: add translator_ld{ub, sw, uw, l, q} Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 22/38] target/arm: call qemu_plugin_insn_append Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 23/38] target/ppc: fetch code with translator_ld Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 24/38] target/sh4: fetch code with translator_ld (WIP) Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 25/38] target/i386: fetch code with translator_ld Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 26/38] target/hppa: " Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 27/38] target/m68k: " Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 28/38] target/alpha: " Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 29/38] target/riscv: " Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 30/38] target/sparc: " Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 31/38] target/xtensa: " Emilio G. Cota
2019-02-25 14:54   ` Alex Bennée
2019-03-04  2:36     ` Max Filippov
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 32/38] target/openrisc: " Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 33/38] translator: inject instrumentation from plugins Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 34/38] plugin: add API symbols to qemu-plugins.symbols Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 35/38] configure: add --enable-plugins Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 36/38] vl: support -plugin option Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 37/38] linux-user: " Emilio G. Cota
2018-12-09 19:37 ` [Qemu-devel] [RFC v2 38/38] tests/plugin: add sample plugins Emilio G. Cota
2019-05-17 19:11 ` [Qemu-devel] [RFC PATCH] tests/tcg: enable plugin testing Alex Bennée

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181209193749.12277-6-cota@braap.org \
    --to=cota@braap.org \
    --cc=Pavel.Dovgaluk@ispras.ru \
    --cc=alex.bennee@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.