diff mbox series

[RFC,47/48] plugin: support guest hooks

Message ID 20181025172057.20414-48-cota@braap.org
State New
Headers show
Series Plugin support | expand

Commit Message

Emilio Cota Oct. 25, 2018, 5:20 p.m. UTC
These "hooks" are callbacks from the guest to plugins. This is
useful when we need guest-host communication, for instance to
signal the beginning/end of a certain "region of interest" in
the guest program. Simulators typically would use "magic"
instructions for this, but that is painful to maintain across
ISAs. Instead, we use plugin-chan PCI device through which we can
relay guest messages to the host.

Signed-off-by: Emilio G. Cota <cota@braap.org>
---
 include/qemu/plugin-api.h |  6 ++++++
 include/qemu/plugin.h     |  2 ++
 plugin.c                  | 13 +++++++++++++
 qemu-plugins.symbols      |  1 +
 4 files changed, 22 insertions(+)

Comments

Alex Bennée Nov. 27, 2018, 6:28 p.m. UTC | #1
Emilio G. Cota <cota@braap.org> writes:

> These "hooks" are callbacks from the guest to plugins. This is
> useful when we need guest-host communication, for instance to
> signal the beginning/end of a certain "region of interest" in
> the guest program. Simulators typically would use "magic"
> instructions for this, but that is painful to maintain across
> ISAs. Instead, we use plugin-chan PCI device through which we can
> relay guest messages to the host.

I suspect the solution for this is either a virtio socket that may (or
may not) be located on a PCI bus. However definitely out of scope for a
first cut of the plugin API, especially without an example usage.

Android has a similar guest-aware channel although the host side was
outside of QEMU and QEMU's part was just to expose a socket on the host
side that adb could talk to.

>
> Signed-off-by: Emilio G. Cota <cota@braap.org>
> ---
>  include/qemu/plugin-api.h |  6 ++++++
>  include/qemu/plugin.h     |  2 ++
>  plugin.c                  | 13 +++++++++++++
>  qemu-plugins.symbols      |  1 +
>  4 files changed, 22 insertions(+)
>
> diff --git a/include/qemu/plugin-api.h b/include/qemu/plugin-api.h
> index 5062e20e08..a5faff6a2a 100644
> --- a/include/qemu/plugin-api.h
> +++ b/include/qemu/plugin-api.h
> @@ -234,6 +234,12 @@ void qemu_plugin_register_lockstep_cb(qemu_plugin_id_t id,
>
>  void qemu_plugin_end_time_slice(void);
>
> +typedef void (*qemu_plugin_hook_cb_t)(uint32_t cmd, const void *data,
> +                                      size_t size);
> +
> +void qemu_plugin_register_hook_cb(qemu_plugin_id_t id,
> +                                  qemu_plugin_hook_cb_t cb);
> +
>  /* returns -1 in user-mode */
>  int qemu_plugin_n_vcpus(void);
>
> diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
> index f3c18d1032..ced265a127 100644
> --- a/include/qemu/plugin.h
> +++ b/include/qemu/plugin.h
> @@ -61,12 +61,14 @@ enum qemu_plugin_event {
>      QEMU_PLUGIN_EV_LOCKSTEP,
>      QEMU_PLUGIN_EV_FLUSH,
>      QEMU_PLUGIN_EV_ATEXIT,
> +    QEMU_PLUGIN_EV_HOOK,
>      QEMU_PLUGIN_EV_MAX,
>  };
>
>  union qemu_plugin_cb_sig {
>      qemu_plugin_simple_cb_t          simple;
>      qemu_plugin_udata_cb_t           udata;
> +    qemu_plugin_hook_cb_t            hook;
>      qemu_plugin_vcpu_simple_cb_t     vcpu_simple;
>      qemu_plugin_vcpu_udata_cb_t      vcpu_udata;
>      qemu_plugin_vcpu_tb_trans_cb_t   vcpu_tb_trans;
> diff --git a/plugin.c b/plugin.c
> index 2bbc14e2f3..4004451bdb 100644
> --- a/plugin.c
> +++ b/plugin.c
> @@ -1078,8 +1078,21 @@ void plugin_lockstep_cb(void)
>      plugin_cb__simple(QEMU_PLUGIN_EV_LOCKSTEP);
>  }
>
> +void qemu_plugin_register_hook_cb(qemu_plugin_id_t id, qemu_plugin_hook_cb_t cb)
> +{
> +    plugin_register_cb(id, QEMU_PLUGIN_EV_HOOK, cb);
> +}
> +
>  void plugin_chan_xmit(uint32_t cmd, const void *data, size_t size)
>  {
> +    struct qemu_plugin_cb *cb, *next;
> +    enum qemu_plugin_event ev = QEMU_PLUGIN_EV_HOOK;
> +
> +    QLIST_FOREACH_SAFE_RCU(cb, &plugin.cb_lists[ev], entry, next) {
> +        qemu_plugin_hook_cb_t func = cb->f.hook;
> +
> +        func(cmd, data, size);
> +    }
>  }
>
>  static void __attribute__((__constructor__)) plugin_init(void)
> diff --git a/qemu-plugins.symbols b/qemu-plugins.symbols
> index a3268a40c7..2e17693da8 100644
> --- a/qemu-plugins.symbols
> +++ b/qemu-plugins.symbols
> @@ -31,6 +31,7 @@
>    qemu_plugin_mem_is_big_endian;
>    qemu_plugin_mem_is_store;
>    qemu_plugin_vcpu_for_each;
> +  qemu_plugin_register_hook_cb;
>    qemu_plugin_n_vcpus;
>    qemu_plugin_n_max_vcpus;
>  };


--
Alex Bennée
diff mbox series

Patch

diff --git a/include/qemu/plugin-api.h b/include/qemu/plugin-api.h
index 5062e20e08..a5faff6a2a 100644
--- a/include/qemu/plugin-api.h
+++ b/include/qemu/plugin-api.h
@@ -234,6 +234,12 @@  void qemu_plugin_register_lockstep_cb(qemu_plugin_id_t id,
 
 void qemu_plugin_end_time_slice(void);
 
+typedef void (*qemu_plugin_hook_cb_t)(uint32_t cmd, const void *data,
+                                      size_t size);
+
+void qemu_plugin_register_hook_cb(qemu_plugin_id_t id,
+                                  qemu_plugin_hook_cb_t cb);
+
 /* returns -1 in user-mode */
 int qemu_plugin_n_vcpus(void);
 
diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
index f3c18d1032..ced265a127 100644
--- a/include/qemu/plugin.h
+++ b/include/qemu/plugin.h
@@ -61,12 +61,14 @@  enum qemu_plugin_event {
     QEMU_PLUGIN_EV_LOCKSTEP,
     QEMU_PLUGIN_EV_FLUSH,
     QEMU_PLUGIN_EV_ATEXIT,
+    QEMU_PLUGIN_EV_HOOK,
     QEMU_PLUGIN_EV_MAX,
 };
 
 union qemu_plugin_cb_sig {
     qemu_plugin_simple_cb_t          simple;
     qemu_plugin_udata_cb_t           udata;
+    qemu_plugin_hook_cb_t            hook;
     qemu_plugin_vcpu_simple_cb_t     vcpu_simple;
     qemu_plugin_vcpu_udata_cb_t      vcpu_udata;
     qemu_plugin_vcpu_tb_trans_cb_t   vcpu_tb_trans;
diff --git a/plugin.c b/plugin.c
index 2bbc14e2f3..4004451bdb 100644
--- a/plugin.c
+++ b/plugin.c
@@ -1078,8 +1078,21 @@  void plugin_lockstep_cb(void)
     plugin_cb__simple(QEMU_PLUGIN_EV_LOCKSTEP);
 }
 
+void qemu_plugin_register_hook_cb(qemu_plugin_id_t id, qemu_plugin_hook_cb_t cb)
+{
+    plugin_register_cb(id, QEMU_PLUGIN_EV_HOOK, cb);
+}
+
 void plugin_chan_xmit(uint32_t cmd, const void *data, size_t size)
 {
+    struct qemu_plugin_cb *cb, *next;
+    enum qemu_plugin_event ev = QEMU_PLUGIN_EV_HOOK;
+
+    QLIST_FOREACH_SAFE_RCU(cb, &plugin.cb_lists[ev], entry, next) {
+        qemu_plugin_hook_cb_t func = cb->f.hook;
+
+        func(cmd, data, size);
+    }
 }
 
 static void __attribute__((__constructor__)) plugin_init(void)
diff --git a/qemu-plugins.symbols b/qemu-plugins.symbols
index a3268a40c7..2e17693da8 100644
--- a/qemu-plugins.symbols
+++ b/qemu-plugins.symbols
@@ -31,6 +31,7 @@ 
   qemu_plugin_mem_is_big_endian;
   qemu_plugin_mem_is_store;
   qemu_plugin_vcpu_for_each;
+  qemu_plugin_register_hook_cb;
   qemu_plugin_n_vcpus;
   qemu_plugin_n_max_vcpus;
 };