[PATCH trivial] plugins: add missing docstrings to qemu-plugin.h

Florian Hofhammer posted 1 patch 1 month ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260309-add-missing-plugin-docs-v1-1-41dddcd177c8@epfl.ch
Maintainers: Michael Tokarev <mjt@tls.msk.ru>, Laurent Vivier <laurent@vivier.eu>
There is a newer version of this series
include/plugins/qemu-plugin.h | 98 ++++++++++++++++++++++++++++++++++++++-----
1 file changed, 88 insertions(+), 10 deletions(-)
[PATCH trivial] plugins: add missing docstrings to qemu-plugin.h
Posted by Florian Hofhammer 1 month ago
This patch adds docstrings for typedefs and function declarations in
include/plugins/qemu-plugin.h that were previously missing. This
resolves inconsistencies in the docs, e.g., the description for
qemu_plugin_read_register() referring to qemu_plugin_register_flush_cb()
but code cache flush callbacks not being documented themselves.

Signed-off-by: Florian Hofhammer <florian.hofhammer@epfl.ch>
---
Hi,

While working on a QEMU plugin and browsing the online docs at
https://www.qemu.org/docs/master/devel/tcg-plugins.html, I noticed that
some of the API functions were not actually documented.

I went through the include/plugins/qemu-plugin.h header file and added
docstrings where they were missing, hoping of course that I documented
the correct functionality based on my understanding of the plugin
internals.

I hope that's useful and I didn't miss anything!

Best regards,
Florian

--
Florian Hofhammer
---
 include/plugins/qemu-plugin.h | 98 ++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 88 insertions(+), 10 deletions(-)

diff --git a/include/plugins/qemu-plugin.h b/include/plugins/qemu-plugin.h
index 827e8e1787..fcf5af52ed 100644
--- a/include/plugins/qemu-plugin.h
+++ b/include/plugins/qemu-plugin.h
@@ -339,12 +339,28 @@ enum qemu_plugin_cb_flags {
     QEMU_PLUGIN_CB_RW_REGS_PC,
 };
 
+/**
+ * enum qemu_plugin_mem_rw - type of memory access
+ *
+ * @QEMU_PLUGIN_MEM_R: memory read access only
+ * @QEMU_PLUGIN_MEM_W: memory write access only
+ * @QEMU_PLUGIN_MEM_RW: memory read and write access
+ */
 enum qemu_plugin_mem_rw {
     QEMU_PLUGIN_MEM_R = 1,
     QEMU_PLUGIN_MEM_W,
     QEMU_PLUGIN_MEM_RW,
 };
 
+/**
+ * enum qemu_plugin_mem_value_type - size of memory value
+ *
+ * @QEMU_PLUGIN_MEM_VALUE_U8: unsigned 8-bit value
+ * @QEMU_PLUGIN_MEM_VALUE_U16: unsigned 16-bit value
+ * @QEMU_PLUGIN_MEM_VALUE_U32: unsigned 32-bit value
+ * @QEMU_PLUGIN_MEM_VALUE_U64: unsigned 64-bit value
+ * @QEMU_PLUGIN_MEM_VALUE_U128: unsigned 128-bit value
+ */
 enum qemu_plugin_mem_value_type {
     QEMU_PLUGIN_MEM_VALUE_U8,
     QEMU_PLUGIN_MEM_VALUE_U16,
@@ -353,7 +369,13 @@ enum qemu_plugin_mem_value_type {
     QEMU_PLUGIN_MEM_VALUE_U128,
 };
 
-/* typedef qemu_plugin_mem_value - value accessed during a load/store */
+/**
+ * typedef qemu_plugin_mem_value - value accessed during a load/store
+ *
+ * @type: the memory access size
+ * @data: the value accessed during the memory operation (value after
+ *        read/write)
+ */
 typedef struct {
     enum qemu_plugin_mem_value_type type;
     union {
@@ -462,7 +484,6 @@ void qemu_plugin_register_vcpu_tb_exec_cond_cb(struct qemu_plugin_tb *tb,
  * @QEMU_PLUGIN_INLINE_ADD_U64: add an immediate value uint64_t
  * @QEMU_PLUGIN_INLINE_STORE_U64: store an immediate value uint64_t
  */
-
 enum qemu_plugin_op {
     QEMU_PLUGIN_INLINE_ADD_U64,
     QEMU_PLUGIN_INLINE_STORE_U64,
@@ -803,6 +824,20 @@ const void *qemu_plugin_request_time_control(void);
 QEMU_PLUGIN_API
 void qemu_plugin_update_ns(const void *handle, int64_t time);
 
+/**
+ * typedef qemu_plugin_vcpu_syscall_cb_t - vCPU syscall callback function type
+ * @id: plugin id
+ * @vcpu_index: the executing vCPU
+ * @num: the syscall number
+ * @a1: the 1st syscall argument
+ * @a2: the 2nd syscall argument
+ * @a3: the 3rd syscall argument
+ * @a4: the 4th syscall argument
+ * @a5: the 5th syscall argument
+ * @a6: the 6th syscall argument
+ * @a7: the 7th syscall argument
+ * @a8: the 8th syscall argument
+ */
 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,
@@ -836,24 +871,61 @@ typedef bool
                                         uint64_t a6, uint64_t a7, uint64_t a8,
                                         uint64_t *sysret);
 
-QEMU_PLUGIN_API
-void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
-                                          qemu_plugin_vcpu_syscall_cb_t cb);
-
+/**
+ * typedef qemu_plugin_vcpu_syscall_ret_cb_t - vCPU syscall return callback
+ * function type
+ * @id: plugin id
+ * @vcpu_index: the executing vCPU
+ * @num: the syscall number
+ * @ret: the syscall return value
+ */
 typedef void
 (*qemu_plugin_vcpu_syscall_ret_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_idx,
                                      int64_t num, int64_t ret);
 
+/**
+ * qemu_plugin_register_vcpu_syscall_cb() - register a syscall entry callback
+ * @id: plugin id
+ * @cb: callback of type qemu_plugin_vcpu_syscall_cb_t
+ *
+ * This registers a callback for every syscall executed by the guest. The @cb
+ * function is executed before a syscall is handled by the host.
+ */
 QEMU_PLUGIN_API
-void
-qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
-                                         qemu_plugin_vcpu_syscall_ret_cb_t cb);
+void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
+                                          qemu_plugin_vcpu_syscall_cb_t cb);
 
+/**
+ * qemu_plugin_register_vcpu_syscall_filter_cb() - register a syscall filter
+ * callback
+ * @id: plugin id
+ * @cb: callback of type qemu_plugin_vcpu_syscall_filter_cb_t
+ *
+ * This registers a callback for every syscall executed by the guest. The @cb
+ * function is executed before a syscall is handled by the host. If the
+ * callback returns true, the syscall is filtered and will not be executed by
+ * the host. The callback must then set the syscall return value via the
+ * corresponding pointer passed to it.
+ */
 QEMU_PLUGIN_API
 void
 qemu_plugin_register_vcpu_syscall_filter_cb(qemu_plugin_id_t id,
                                             qemu_plugin_vcpu_syscall_filter_cb_t cb);
 
+/**
+ * qemu_plugin_register_vcpu_syscall_ret_cb() - register a syscall entry
+ * callback
+ * @id: plugin id
+ * @cb: callback of type qemu_plugin_vcpu_syscall_ret_cb_t
+ *
+ * This registers a callback for every syscall executed by the guest. The @cb
+ * function is executed upon return from the host syscall before execution is
+ * handed back to the guest.
+ */
+QEMU_PLUGIN_API
+void
+qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
+                                         qemu_plugin_vcpu_syscall_ret_cb_t cb);
 
 /**
  * qemu_plugin_insn_disas() - return disassembly string for instruction
@@ -861,7 +933,6 @@ qemu_plugin_register_vcpu_syscall_filter_cb(qemu_plugin_id_t id,
  *
  * Returns an allocated string containing the disassembly
  */
-
 QEMU_PLUGIN_API
 char *qemu_plugin_insn_disas(const struct qemu_plugin_insn *insn);
 
@@ -888,6 +959,13 @@ QEMU_PLUGIN_API
 void qemu_plugin_vcpu_for_each(qemu_plugin_id_t id,
                                qemu_plugin_vcpu_simple_cb_t cb);
 
+/**
+ * qemu_plugin_register_flush_cb() - register code cache flush callback
+ * @id: plugin ID
+ * @cb: callback
+ *
+ * The @cb function is called every time the code cache is flushed.
+ */
 QEMU_PLUGIN_API
 void qemu_plugin_register_flush_cb(qemu_plugin_id_t id,
                                    qemu_plugin_simple_cb_t cb);

---
base-commit: 7608a95d2e0bd8c8d069ab77824d02586dd94648
change-id: 20260309-add-missing-plugin-docs-159d7ff315f9

Re: [PATCH trivial] plugins: add missing docstrings to qemu-plugin.h
Posted by Pierrick Bouvier 1 month ago
On 3/9/26 9:21 AM, Florian Hofhammer wrote:
> This patch adds docstrings for typedefs and function declarations in
> include/plugins/qemu-plugin.h that were previously missing. This
> resolves inconsistencies in the docs, e.g., the description for
> qemu_plugin_read_register() referring to qemu_plugin_register_flush_cb()
> but code cache flush callbacks not being documented themselves.
> 
> Signed-off-by: Florian Hofhammer <florian.hofhammer@epfl.ch>
> ---
> Hi,
> 
> While working on a QEMU plugin and browsing the online docs at
> https://www.qemu.org/docs/master/devel/tcg-plugins.html, I noticed that
> some of the API functions were not actually documented.
> 
> I went through the include/plugins/qemu-plugin.h header file and added
> docstrings where they were missing, hoping of course that I documented
> the correct functionality based on my understanding of the plugin
> internals.
> 
> I hope that's useful and I didn't miss anything!
>

Thanks for the effort, that's always welcome to add documentation on a 
public API like this!

> Best regards,
> Florian
> 
> --
> Florian Hofhammer
> ---
>   include/plugins/qemu-plugin.h | 98 ++++++++++++++++++++++++++++++++++++++-----
>   1 file changed, 88 insertions(+), 10 deletions(-)
> 
> diff --git a/include/plugins/qemu-plugin.h b/include/plugins/qemu-plugin.h
> index 827e8e1787..fcf5af52ed 100644
> --- a/include/plugins/qemu-plugin.h
> +++ b/include/plugins/qemu-plugin.h
> @@ -339,12 +339,28 @@ enum qemu_plugin_cb_flags {
>       QEMU_PLUGIN_CB_RW_REGS_PC,
>   };
>   
> +/**
> + * enum qemu_plugin_mem_rw - type of memory access
> + *
> + * @QEMU_PLUGIN_MEM_R: memory read access only
> + * @QEMU_PLUGIN_MEM_W: memory write access only
> + * @QEMU_PLUGIN_MEM_RW: memory read and write access
> + */
>   enum qemu_plugin_mem_rw {
>       QEMU_PLUGIN_MEM_R = 1,
>       QEMU_PLUGIN_MEM_W,
>       QEMU_PLUGIN_MEM_RW,
>   };
>   
> +/**
> + * enum qemu_plugin_mem_value_type - size of memory value
> + *
> + * @QEMU_PLUGIN_MEM_VALUE_U8: unsigned 8-bit value
> + * @QEMU_PLUGIN_MEM_VALUE_U16: unsigned 16-bit value
> + * @QEMU_PLUGIN_MEM_VALUE_U32: unsigned 32-bit value
> + * @QEMU_PLUGIN_MEM_VALUE_U64: unsigned 64-bit value
> + * @QEMU_PLUGIN_MEM_VALUE_U128: unsigned 128-bit value
> + */
>   enum qemu_plugin_mem_value_type {
>       QEMU_PLUGIN_MEM_VALUE_U8,
>       QEMU_PLUGIN_MEM_VALUE_U16,
> @@ -353,7 +369,13 @@ enum qemu_plugin_mem_value_type {
>       QEMU_PLUGIN_MEM_VALUE_U128,
>   };
>   
> -/* typedef qemu_plugin_mem_value - value accessed during a load/store */
> +/**
> + * typedef qemu_plugin_mem_value - value accessed during a load/store
> + *
> + * @type: the memory access size
> + * @data: the value accessed during the memory operation (value after
> + *        read/write)
> + */
>   typedef struct {
>       enum qemu_plugin_mem_value_type type;
>       union {
> @@ -462,7 +484,6 @@ void qemu_plugin_register_vcpu_tb_exec_cond_cb(struct qemu_plugin_tb *tb,
>    * @QEMU_PLUGIN_INLINE_ADD_U64: add an immediate value uint64_t
>    * @QEMU_PLUGIN_INLINE_STORE_U64: store an immediate value uint64_t
>    */
> -
>   enum qemu_plugin_op {
>       QEMU_PLUGIN_INLINE_ADD_U64,
>       QEMU_PLUGIN_INLINE_STORE_U64,
> @@ -803,6 +824,20 @@ const void *qemu_plugin_request_time_control(void);
>   QEMU_PLUGIN_API
>   void qemu_plugin_update_ns(const void *handle, int64_t time);
>   
> +/**
> + * typedef qemu_plugin_vcpu_syscall_cb_t - vCPU syscall callback function type
> + * @id: plugin id
> + * @vcpu_index: the executing vCPU
> + * @num: the syscall number
> + * @a1: the 1st syscall argument
> + * @a2: the 2nd syscall argument
> + * @a3: the 3rd syscall argument
> + * @a4: the 4th syscall argument
> + * @a5: the 5th syscall argument
> + * @a6: the 6th syscall argument
> + * @a7: the 7th syscall argument
> + * @a8: the 8th syscall argument
> + */
>   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,
> @@ -836,24 +871,61 @@ typedef bool
>                                           uint64_t a6, uint64_t a7, uint64_t a8,
>                                           uint64_t *sysret);
>   
> -QEMU_PLUGIN_API
> -void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
> -                                          qemu_plugin_vcpu_syscall_cb_t cb);
> -
> +/**
> + * typedef qemu_plugin_vcpu_syscall_ret_cb_t - vCPU syscall return callback
> + * function type
> + * @id: plugin id
> + * @vcpu_index: the executing vCPU
> + * @num: the syscall number
> + * @ret: the syscall return value
> + */
>   typedef void
>   (*qemu_plugin_vcpu_syscall_ret_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_idx,
>                                        int64_t num, int64_t ret);
>   
> +/**
> + * qemu_plugin_register_vcpu_syscall_cb() - register a syscall entry callback
> + * @id: plugin id
> + * @cb: callback of type qemu_plugin_vcpu_syscall_cb_t
> + *
> + * This registers a callback for every syscall executed by the guest. The @cb
> + * function is executed before a syscall is handled by the host.
> + */
>   QEMU_PLUGIN_API
> -void
> -qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
> -                                         qemu_plugin_vcpu_syscall_ret_cb_t cb);
> +void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
> +                                          qemu_plugin_vcpu_syscall_cb_t cb);
>   
> +/**
> + * qemu_plugin_register_vcpu_syscall_filter_cb() - register a syscall filter
> + * callback
> + * @id: plugin id
> + * @cb: callback of type qemu_plugin_vcpu_syscall_filter_cb_t
> + *
> + * This registers a callback for every syscall executed by the guest. The @cb
> + * function is executed before a syscall is handled by the host. If the
> + * callback returns true, the syscall is filtered and will not be executed by
> + * the host. The callback must then set the syscall return value via the
> + * corresponding pointer passed to it.
> + */
>   QEMU_PLUGIN_API
>   void
>   qemu_plugin_register_vcpu_syscall_filter_cb(qemu_plugin_id_t id,
>                                               qemu_plugin_vcpu_syscall_filter_cb_t cb);
>   
> +/**
> + * qemu_plugin_register_vcpu_syscall_ret_cb() - register a syscall entry
> + * callback
> + * @id: plugin id
> + * @cb: callback of type qemu_plugin_vcpu_syscall_ret_cb_t
> + *
> + * This registers a callback for every syscall executed by the guest. The @cb
> + * function is executed upon return from the host syscall before execution is
> + * handed back to the guest.
> + */
> +QEMU_PLUGIN_API
> +void
> +qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
> +                                         qemu_plugin_vcpu_syscall_ret_cb_t cb);
>   
>   /**
>    * qemu_plugin_insn_disas() - return disassembly string for instruction
> @@ -861,7 +933,6 @@ qemu_plugin_register_vcpu_syscall_filter_cb(qemu_plugin_id_t id,
>    *
>    * Returns an allocated string containing the disassembly
>    */
> -
>   QEMU_PLUGIN_API
>   char *qemu_plugin_insn_disas(const struct qemu_plugin_insn *insn);
>   
> @@ -888,6 +959,13 @@ QEMU_PLUGIN_API
>   void qemu_plugin_vcpu_for_each(qemu_plugin_id_t id,
>                                  qemu_plugin_vcpu_simple_cb_t cb);
>   
> +/**
> + * qemu_plugin_register_flush_cb() - register code cache flush callback
> + * @id: plugin ID
> + * @cb: callback
> + *
> + * The @cb function is called every time the code cache is flushed.
> + */

Thanks, I was thinking to document this since someone asked a question 
on IRC a few weeks ago.

May you add here:
"This callback can be used to free resources associated with existing 
translated blocks in a plugin. @cb is guaranteed to run with all cpus 
being stopped, thus no lock is required within it."

>   QEMU_PLUGIN_API
>   void qemu_plugin_register_flush_cb(qemu_plugin_id_t id,
>                                      qemu_plugin_simple_cb_t cb);
> 
> ---
> base-commit: 7608a95d2e0bd8c8d069ab77824d02586dd94648
> change-id: 20260309-add-missing-plugin-docs-159d7ff315f9
> 

Regards,
Pierrick
Re: [PATCH trivial] plugins: add missing docstrings to qemu-plugin.h
Posted by Alex Bennée 1 month ago
Pierrick Bouvier <pierrick.bouvier@linaro.org> writes:

> On 3/9/26 9:21 AM, Florian Hofhammer wrote:
>> This patch adds docstrings for typedefs and function declarations in
>> include/plugins/qemu-plugin.h that were previously missing. This
>> resolves inconsistencies in the docs, e.g., the description for
>> qemu_plugin_read_register() referring to qemu_plugin_register_flush_cb()
>> but code cache flush callbacks not being documented themselves.
>> Signed-off-by: Florian Hofhammer <florian.hofhammer@epfl.ch>
>> ---
>> Hi,
>> While working on a QEMU plugin and browsing the online docs at
>> https://www.qemu.org/docs/master/devel/tcg-plugins.html, I noticed that
>> some of the API functions were not actually documented.
>> I went through the include/plugins/qemu-plugin.h header file and
>> added
>> docstrings where they were missing, hoping of course that I documented
>> the correct functionality based on my understanding of the plugin
>> internals.
>> I hope that's useful and I didn't miss anything!
>>
>
> Thanks for the effort, that's always welcome to add documentation on a
> public API like this!
>
>> Best regards,
>> Florian
>> --
>> Florian Hofhammer
>> ---
>>   include/plugins/qemu-plugin.h | 98 ++++++++++++++++++++++++++++++++++++++-----
>>   1 file changed, 88 insertions(+), 10 deletions(-)
>> diff --git a/include/plugins/qemu-plugin.h
>> b/include/plugins/qemu-plugin.h
>> index 827e8e1787..fcf5af52ed 100644
>> --- a/include/plugins/qemu-plugin.h
>> +++ b/include/plugins/qemu-plugin.h
>> @@ -339,12 +339,28 @@ enum qemu_plugin_cb_flags {
>>       QEMU_PLUGIN_CB_RW_REGS_PC,
>>   };
>>   +/**
>> + * enum qemu_plugin_mem_rw - type of memory access
>> + *
>> + * @QEMU_PLUGIN_MEM_R: memory read access only
>> + * @QEMU_PLUGIN_MEM_W: memory write access only
>> + * @QEMU_PLUGIN_MEM_RW: memory read and write access
>> + */
>>   enum qemu_plugin_mem_rw {
>>       QEMU_PLUGIN_MEM_R = 1,
>>       QEMU_PLUGIN_MEM_W,
>>       QEMU_PLUGIN_MEM_RW,
>>   };
>>   +/**
>> + * enum qemu_plugin_mem_value_type - size of memory value
>> + *
>> + * @QEMU_PLUGIN_MEM_VALUE_U8: unsigned 8-bit value
>> + * @QEMU_PLUGIN_MEM_VALUE_U16: unsigned 16-bit value
>> + * @QEMU_PLUGIN_MEM_VALUE_U32: unsigned 32-bit value
>> + * @QEMU_PLUGIN_MEM_VALUE_U64: unsigned 64-bit value
>> + * @QEMU_PLUGIN_MEM_VALUE_U128: unsigned 128-bit value
>> + */
>>   enum qemu_plugin_mem_value_type {
>>       QEMU_PLUGIN_MEM_VALUE_U8,
>>       QEMU_PLUGIN_MEM_VALUE_U16,
>> @@ -353,7 +369,13 @@ enum qemu_plugin_mem_value_type {
>>       QEMU_PLUGIN_MEM_VALUE_U128,
>>   };
>>   -/* typedef qemu_plugin_mem_value - value accessed during a
>> load/store */
>> +/**
>> + * typedef qemu_plugin_mem_value - value accessed during a load/store
>> + *
>> + * @type: the memory access size
>> + * @data: the value accessed during the memory operation (value after
>> + *        read/write)
>> + */
>>   typedef struct {
>>       enum qemu_plugin_mem_value_type type;
>>       union {
>> @@ -462,7 +484,6 @@ void qemu_plugin_register_vcpu_tb_exec_cond_cb(struct qemu_plugin_tb *tb,
>>    * @QEMU_PLUGIN_INLINE_ADD_U64: add an immediate value uint64_t
>>    * @QEMU_PLUGIN_INLINE_STORE_U64: store an immediate value uint64_t
>>    */
>> -
>>   enum qemu_plugin_op {
>>       QEMU_PLUGIN_INLINE_ADD_U64,
>>       QEMU_PLUGIN_INLINE_STORE_U64,
>> @@ -803,6 +824,20 @@ const void *qemu_plugin_request_time_control(void);
>>   QEMU_PLUGIN_API
>>   void qemu_plugin_update_ns(const void *handle, int64_t time);
>>   +/**
>> + * typedef qemu_plugin_vcpu_syscall_cb_t - vCPU syscall callback function type
>> + * @id: plugin id
>> + * @vcpu_index: the executing vCPU
>> + * @num: the syscall number
>> + * @a1: the 1st syscall argument
>> + * @a2: the 2nd syscall argument
>> + * @a3: the 3rd syscall argument
>> + * @a4: the 4th syscall argument
>> + * @a5: the 5th syscall argument
>> + * @a6: the 6th syscall argument
>> + * @a7: the 7th syscall argument
>> + * @a8: the 8th syscall argument
>> + */
>>   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,
>> @@ -836,24 +871,61 @@ typedef bool
>>                                           uint64_t a6, uint64_t a7, uint64_t a8,
>>                                           uint64_t *sysret);
>>   -QEMU_PLUGIN_API
>> -void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
>> -                                          qemu_plugin_vcpu_syscall_cb_t cb);
>> -
>> +/**
>> + * typedef qemu_plugin_vcpu_syscall_ret_cb_t - vCPU syscall return callback
>> + * function type
>> + * @id: plugin id
>> + * @vcpu_index: the executing vCPU
>> + * @num: the syscall number
>> + * @ret: the syscall return value
>> + */
>>   typedef void
>>   (*qemu_plugin_vcpu_syscall_ret_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_idx,
>>                                        int64_t num, int64_t ret);
>>   +/**
>> + * qemu_plugin_register_vcpu_syscall_cb() - register a syscall entry callback
>> + * @id: plugin id
>> + * @cb: callback of type qemu_plugin_vcpu_syscall_cb_t
>> + *
>> + * This registers a callback for every syscall executed by the guest. The @cb
>> + * function is executed before a syscall is handled by the host.
>> + */
>>   QEMU_PLUGIN_API
>> -void
>> -qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
>> -                                         qemu_plugin_vcpu_syscall_ret_cb_t cb);
>> +void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
>> +                                          qemu_plugin_vcpu_syscall_cb_t cb);
>>   +/**
>> + * qemu_plugin_register_vcpu_syscall_filter_cb() - register a syscall filter
>> + * callback
>> + * @id: plugin id
>> + * @cb: callback of type qemu_plugin_vcpu_syscall_filter_cb_t
>> + *
>> + * This registers a callback for every syscall executed by the guest. The @cb
>> + * function is executed before a syscall is handled by the host. If the
>> + * callback returns true, the syscall is filtered and will not be executed by
>> + * the host. The callback must then set the syscall return value via the
>> + * corresponding pointer passed to it.
>> + */
>>   QEMU_PLUGIN_API
>>   void
>>   qemu_plugin_register_vcpu_syscall_filter_cb(qemu_plugin_id_t id,
>>                                               qemu_plugin_vcpu_syscall_filter_cb_t cb);
>>   +/**
>> + * qemu_plugin_register_vcpu_syscall_ret_cb() - register a syscall entry
>> + * callback
>> + * @id: plugin id
>> + * @cb: callback of type qemu_plugin_vcpu_syscall_ret_cb_t
>> + *
>> + * This registers a callback for every syscall executed by the guest. The @cb
>> + * function is executed upon return from the host syscall before execution is
>> + * handed back to the guest.
>> + */
>> +QEMU_PLUGIN_API
>> +void
>> +qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
>> +                                         qemu_plugin_vcpu_syscall_ret_cb_t cb);
>>     /**
>>    * qemu_plugin_insn_disas() - return disassembly string for instruction
>> @@ -861,7 +933,6 @@ qemu_plugin_register_vcpu_syscall_filter_cb(qemu_plugin_id_t id,
>>    *
>>    * Returns an allocated string containing the disassembly
>>    */
>> -
>>   QEMU_PLUGIN_API
>>   char *qemu_plugin_insn_disas(const struct qemu_plugin_insn *insn);
>>   @@ -888,6 +959,13 @@ QEMU_PLUGIN_API
>>   void qemu_plugin_vcpu_for_each(qemu_plugin_id_t id,
>>                                  qemu_plugin_vcpu_simple_cb_t cb);
>>   +/**
>> + * qemu_plugin_register_flush_cb() - register code cache flush callback
>> + * @id: plugin ID
>> + * @cb: callback
>> + *
>> + * The @cb function is called every time the code cache is flushed.
>> + */
>
> Thanks, I was thinking to document this since someone asked a question
> on IRC a few weeks ago.
>
> May you add here:
> "This callback can be used to free resources associated with existing
> translated blocks in a plugin. @cb is guaranteed to run with all cpus
> being stopped, thus no lock is required within it."

This does make me wonder what the use case for this callback is? In
theory the state of the code cache should be an internal implementation
detail that plugins shouldn't need to concern themselves with.

>
>>   QEMU_PLUGIN_API
>>   void qemu_plugin_register_flush_cb(qemu_plugin_id_t id,
>>                                      qemu_plugin_simple_cb_t cb);
>> ---
>> base-commit: 7608a95d2e0bd8c8d069ab77824d02586dd94648
>> change-id: 20260309-add-missing-plugin-docs-159d7ff315f9
>> 
>
> Regards,
> Pierrick

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro
Re: [PATCH trivial] plugins: add missing docstrings to qemu-plugin.h
Posted by Pierrick Bouvier 1 month ago
On 3/11/26 2:59 AM, Alex Bennée wrote:
> Pierrick Bouvier <pierrick.bouvier@linaro.org> writes:
> 
>> On 3/9/26 9:21 AM, Florian Hofhammer wrote:
>>> This patch adds docstrings for typedefs and function declarations in
>>> include/plugins/qemu-plugin.h that were previously missing. This
>>> resolves inconsistencies in the docs, e.g., the description for
>>> qemu_plugin_read_register() referring to qemu_plugin_register_flush_cb()
>>> but code cache flush callbacks not being documented themselves.
>>> Signed-off-by: Florian Hofhammer <florian.hofhammer@epfl.ch>
>>> ---
>>> Hi,
>>> While working on a QEMU plugin and browsing the online docs at
>>> https://www.qemu.org/docs/master/devel/tcg-plugins.html, I noticed that
>>> some of the API functions were not actually documented.
>>> I went through the include/plugins/qemu-plugin.h header file and
>>> added
>>> docstrings where they were missing, hoping of course that I documented
>>> the correct functionality based on my understanding of the plugin
>>> internals.
>>> I hope that's useful and I didn't miss anything!
>>>
>>
>> Thanks for the effort, that's always welcome to add documentation on a
>> public API like this!
>>
>>> Best regards,
>>> Florian
>>> --
>>> Florian Hofhammer
>>> ---
>>>    include/plugins/qemu-plugin.h | 98 ++++++++++++++++++++++++++++++++++++++-----
>>>    1 file changed, 88 insertions(+), 10 deletions(-)
>>> diff --git a/include/plugins/qemu-plugin.h
>>> b/include/plugins/qemu-plugin.h
>>> index 827e8e1787..fcf5af52ed 100644
>>> --- a/include/plugins/qemu-plugin.h
>>> +++ b/include/plugins/qemu-plugin.h
>>> @@ -339,12 +339,28 @@ enum qemu_plugin_cb_flags {
>>>        QEMU_PLUGIN_CB_RW_REGS_PC,
>>>    };
>>>    +/**
>>> + * enum qemu_plugin_mem_rw - type of memory access
>>> + *
>>> + * @QEMU_PLUGIN_MEM_R: memory read access only
>>> + * @QEMU_PLUGIN_MEM_W: memory write access only
>>> + * @QEMU_PLUGIN_MEM_RW: memory read and write access
>>> + */
>>>    enum qemu_plugin_mem_rw {
>>>        QEMU_PLUGIN_MEM_R = 1,
>>>        QEMU_PLUGIN_MEM_W,
>>>        QEMU_PLUGIN_MEM_RW,
>>>    };
>>>    +/**
>>> + * enum qemu_plugin_mem_value_type - size of memory value
>>> + *
>>> + * @QEMU_PLUGIN_MEM_VALUE_U8: unsigned 8-bit value
>>> + * @QEMU_PLUGIN_MEM_VALUE_U16: unsigned 16-bit value
>>> + * @QEMU_PLUGIN_MEM_VALUE_U32: unsigned 32-bit value
>>> + * @QEMU_PLUGIN_MEM_VALUE_U64: unsigned 64-bit value
>>> + * @QEMU_PLUGIN_MEM_VALUE_U128: unsigned 128-bit value
>>> + */
>>>    enum qemu_plugin_mem_value_type {
>>>        QEMU_PLUGIN_MEM_VALUE_U8,
>>>        QEMU_PLUGIN_MEM_VALUE_U16,
>>> @@ -353,7 +369,13 @@ enum qemu_plugin_mem_value_type {
>>>        QEMU_PLUGIN_MEM_VALUE_U128,
>>>    };
>>>    -/* typedef qemu_plugin_mem_value - value accessed during a
>>> load/store */
>>> +/**
>>> + * typedef qemu_plugin_mem_value - value accessed during a load/store
>>> + *
>>> + * @type: the memory access size
>>> + * @data: the value accessed during the memory operation (value after
>>> + *        read/write)
>>> + */
>>>    typedef struct {
>>>        enum qemu_plugin_mem_value_type type;
>>>        union {
>>> @@ -462,7 +484,6 @@ void qemu_plugin_register_vcpu_tb_exec_cond_cb(struct qemu_plugin_tb *tb,
>>>     * @QEMU_PLUGIN_INLINE_ADD_U64: add an immediate value uint64_t
>>>     * @QEMU_PLUGIN_INLINE_STORE_U64: store an immediate value uint64_t
>>>     */
>>> -
>>>    enum qemu_plugin_op {
>>>        QEMU_PLUGIN_INLINE_ADD_U64,
>>>        QEMU_PLUGIN_INLINE_STORE_U64,
>>> @@ -803,6 +824,20 @@ const void *qemu_plugin_request_time_control(void);
>>>    QEMU_PLUGIN_API
>>>    void qemu_plugin_update_ns(const void *handle, int64_t time);
>>>    +/**
>>> + * typedef qemu_plugin_vcpu_syscall_cb_t - vCPU syscall callback function type
>>> + * @id: plugin id
>>> + * @vcpu_index: the executing vCPU
>>> + * @num: the syscall number
>>> + * @a1: the 1st syscall argument
>>> + * @a2: the 2nd syscall argument
>>> + * @a3: the 3rd syscall argument
>>> + * @a4: the 4th syscall argument
>>> + * @a5: the 5th syscall argument
>>> + * @a6: the 6th syscall argument
>>> + * @a7: the 7th syscall argument
>>> + * @a8: the 8th syscall argument
>>> + */
>>>    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,
>>> @@ -836,24 +871,61 @@ typedef bool
>>>                                            uint64_t a6, uint64_t a7, uint64_t a8,
>>>                                            uint64_t *sysret);
>>>    -QEMU_PLUGIN_API
>>> -void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
>>> -                                          qemu_plugin_vcpu_syscall_cb_t cb);
>>> -
>>> +/**
>>> + * typedef qemu_plugin_vcpu_syscall_ret_cb_t - vCPU syscall return callback
>>> + * function type
>>> + * @id: plugin id
>>> + * @vcpu_index: the executing vCPU
>>> + * @num: the syscall number
>>> + * @ret: the syscall return value
>>> + */
>>>    typedef void
>>>    (*qemu_plugin_vcpu_syscall_ret_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_idx,
>>>                                         int64_t num, int64_t ret);
>>>    +/**
>>> + * qemu_plugin_register_vcpu_syscall_cb() - register a syscall entry callback
>>> + * @id: plugin id
>>> + * @cb: callback of type qemu_plugin_vcpu_syscall_cb_t
>>> + *
>>> + * This registers a callback for every syscall executed by the guest. The @cb
>>> + * function is executed before a syscall is handled by the host.
>>> + */
>>>    QEMU_PLUGIN_API
>>> -void
>>> -qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
>>> -                                         qemu_plugin_vcpu_syscall_ret_cb_t cb);
>>> +void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
>>> +                                          qemu_plugin_vcpu_syscall_cb_t cb);
>>>    +/**
>>> + * qemu_plugin_register_vcpu_syscall_filter_cb() - register a syscall filter
>>> + * callback
>>> + * @id: plugin id
>>> + * @cb: callback of type qemu_plugin_vcpu_syscall_filter_cb_t
>>> + *
>>> + * This registers a callback for every syscall executed by the guest. The @cb
>>> + * function is executed before a syscall is handled by the host. If the
>>> + * callback returns true, the syscall is filtered and will not be executed by
>>> + * the host. The callback must then set the syscall return value via the
>>> + * corresponding pointer passed to it.
>>> + */
>>>    QEMU_PLUGIN_API
>>>    void
>>>    qemu_plugin_register_vcpu_syscall_filter_cb(qemu_plugin_id_t id,
>>>                                                qemu_plugin_vcpu_syscall_filter_cb_t cb);
>>>    +/**
>>> + * qemu_plugin_register_vcpu_syscall_ret_cb() - register a syscall entry
>>> + * callback
>>> + * @id: plugin id
>>> + * @cb: callback of type qemu_plugin_vcpu_syscall_ret_cb_t
>>> + *
>>> + * This registers a callback for every syscall executed by the guest. The @cb
>>> + * function is executed upon return from the host syscall before execution is
>>> + * handed back to the guest.
>>> + */
>>> +QEMU_PLUGIN_API
>>> +void
>>> +qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
>>> +                                         qemu_plugin_vcpu_syscall_ret_cb_t cb);
>>>      /**
>>>     * qemu_plugin_insn_disas() - return disassembly string for instruction
>>> @@ -861,7 +933,6 @@ qemu_plugin_register_vcpu_syscall_filter_cb(qemu_plugin_id_t id,
>>>     *
>>>     * Returns an allocated string containing the disassembly
>>>     */
>>> -
>>>    QEMU_PLUGIN_API
>>>    char *qemu_plugin_insn_disas(const struct qemu_plugin_insn *insn);
>>>    @@ -888,6 +959,13 @@ QEMU_PLUGIN_API
>>>    void qemu_plugin_vcpu_for_each(qemu_plugin_id_t id,
>>>                                   qemu_plugin_vcpu_simple_cb_t cb);
>>>    +/**
>>> + * qemu_plugin_register_flush_cb() - register code cache flush callback
>>> + * @id: plugin ID
>>> + * @cb: callback
>>> + *
>>> + * The @cb function is called every time the code cache is flushed.
>>> + */
>>
>> Thanks, I was thinking to document this since someone asked a question
>> on IRC a few weeks ago.
>>
>> May you add here:
>> "This callback can be used to free resources associated with existing
>> translated blocks in a plugin. @cb is guaranteed to run with all cpus
>> being stopped, thus no lock is required within it."
> 
> This does make me wonder what the use case for this callback is? In
> theory the state of the code cache should be an internal implementation
> detail that plugins shouldn't need to concern themselves with.
>

It can be useful for plugins who want a callback to cleanup resources 
they allocated for each tb (like a hashtable associating a pc to some 
data). At the moment, that's the only way to be notified that a TB won't 
be used anymore.
Even though it's an implementation detail when we do such an operation, 
it's one thing that is mandatory for plugins allocating a lot of data 
per tb, which quickly adds up.
In all cases, when a tb won't be used anymore will always be an 
implementation detail, since we need to do flush them in case we fill 
the jump cache for instance.

All that said, there is no usage of this callback in any existing 
plugins, and the documentation I asked to Florian was inspired by 
someone coming on IRC a few weeks ago with the question "How can I know 
when a tb won't be used anymore so I can free data associated?".

Regards,
Pierrick

Re: [PATCH trivial] plugins: add missing docstrings to qemu-plugin.h
Posted by Florian Hofhammer 1 month ago
On 09/03/2026 18:25, Pierrick Bouvier wrote:
> On 3/9/26 9:21 AM, Florian Hofhammer wrote:
>> This patch adds docstrings for typedefs and function declarations in
>> include/plugins/qemu-plugin.h that were previously missing. This
>> resolves inconsistencies in the docs, e.g., the description for
>> qemu_plugin_read_register() referring to qemu_plugin_register_flush_cb()
>> but code cache flush callbacks not being documented themselves.
>>
>> Signed-off-by: Florian Hofhammer <florian.hofhammer@epfl.ch>
>> ---
>> Hi,
>>
>> While working on a QEMU plugin and browsing the online docs at
>> https://www.qemu.org/docs/master/devel/tcg-plugins.html, I noticed that
>> some of the API functions were not actually documented.
>>
>> I went through the include/plugins/qemu-plugin.h header file and added
>> docstrings where they were missing, hoping of course that I documented
>> the correct functionality based on my understanding of the plugin
>> internals.
>>
>> I hope that's useful and I didn't miss anything!
>>
> 
> Thanks for the effort, that's always welcome to add documentation on a public API like this!

No worries, it's also helping myself when I look up the APIs :)

> 
>> Best regards,
>> Florian
>>
>> -- 
>> Florian Hofhammer
>> ---
>>   include/plugins/qemu-plugin.h | 98 ++++++++++++++++++++++++++++++++++++++-----
>>   1 file changed, 88 insertions(+), 10 deletions(-)
>>
>> diff --git a/include/plugins/qemu-plugin.h b/include/plugins/qemu-plugin.h
>> index 827e8e1787..fcf5af52ed 100644
>> --- a/include/plugins/qemu-plugin.h
>> +++ b/include/plugins/qemu-plugin.h
>> @@ -339,12 +339,28 @@ enum qemu_plugin_cb_flags {
>>       QEMU_PLUGIN_CB_RW_REGS_PC,
>>   };
>>   +/**
>> + * enum qemu_plugin_mem_rw - type of memory access
>> + *
>> + * @QEMU_PLUGIN_MEM_R: memory read access only
>> + * @QEMU_PLUGIN_MEM_W: memory write access only
>> + * @QEMU_PLUGIN_MEM_RW: memory read and write access
>> + */
>>   enum qemu_plugin_mem_rw {
>>       QEMU_PLUGIN_MEM_R = 1,
>>       QEMU_PLUGIN_MEM_W,
>>       QEMU_PLUGIN_MEM_RW,
>>   };
>>   +/**
>> + * enum qemu_plugin_mem_value_type - size of memory value
>> + *
>> + * @QEMU_PLUGIN_MEM_VALUE_U8: unsigned 8-bit value
>> + * @QEMU_PLUGIN_MEM_VALUE_U16: unsigned 16-bit value
>> + * @QEMU_PLUGIN_MEM_VALUE_U32: unsigned 32-bit value
>> + * @QEMU_PLUGIN_MEM_VALUE_U64: unsigned 64-bit value
>> + * @QEMU_PLUGIN_MEM_VALUE_U128: unsigned 128-bit value
>> + */
>>   enum qemu_plugin_mem_value_type {
>>       QEMU_PLUGIN_MEM_VALUE_U8,
>>       QEMU_PLUGIN_MEM_VALUE_U16,
>> @@ -353,7 +369,13 @@ enum qemu_plugin_mem_value_type {
>>       QEMU_PLUGIN_MEM_VALUE_U128,
>>   };
>>   -/* typedef qemu_plugin_mem_value - value accessed during a load/store */
>> +/**
>> + * typedef qemu_plugin_mem_value - value accessed during a load/store
>> + *
>> + * @type: the memory access size
>> + * @data: the value accessed during the memory operation (value after
>> + *        read/write)
>> + */
>>   typedef struct {
>>       enum qemu_plugin_mem_value_type type;
>>       union {
>> @@ -462,7 +484,6 @@ void qemu_plugin_register_vcpu_tb_exec_cond_cb(struct qemu_plugin_tb *tb,
>>    * @QEMU_PLUGIN_INLINE_ADD_U64: add an immediate value uint64_t
>>    * @QEMU_PLUGIN_INLINE_STORE_U64: store an immediate value uint64_t
>>    */
>> -
>>   enum qemu_plugin_op {
>>       QEMU_PLUGIN_INLINE_ADD_U64,
>>       QEMU_PLUGIN_INLINE_STORE_U64,
>> @@ -803,6 +824,20 @@ const void *qemu_plugin_request_time_control(void);
>>   QEMU_PLUGIN_API
>>   void qemu_plugin_update_ns(const void *handle, int64_t time);
>>   +/**
>> + * typedef qemu_plugin_vcpu_syscall_cb_t - vCPU syscall callback function type
>> + * @id: plugin id
>> + * @vcpu_index: the executing vCPU
>> + * @num: the syscall number
>> + * @a1: the 1st syscall argument
>> + * @a2: the 2nd syscall argument
>> + * @a3: the 3rd syscall argument
>> + * @a4: the 4th syscall argument
>> + * @a5: the 5th syscall argument
>> + * @a6: the 6th syscall argument
>> + * @a7: the 7th syscall argument
>> + * @a8: the 8th syscall argument
>> + */
>>   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,
>> @@ -836,24 +871,61 @@ typedef bool
>>                                           uint64_t a6, uint64_t a7, uint64_t a8,
>>                                           uint64_t *sysret);
>>   -QEMU_PLUGIN_API
>> -void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
>> -                                          qemu_plugin_vcpu_syscall_cb_t cb);
>> -
>> +/**
>> + * typedef qemu_plugin_vcpu_syscall_ret_cb_t - vCPU syscall return callback
>> + * function type
>> + * @id: plugin id
>> + * @vcpu_index: the executing vCPU
>> + * @num: the syscall number
>> + * @ret: the syscall return value
>> + */
>>   typedef void
>>   (*qemu_plugin_vcpu_syscall_ret_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_idx,
>>                                        int64_t num, int64_t ret);
>>   +/**
>> + * qemu_plugin_register_vcpu_syscall_cb() - register a syscall entry callback
>> + * @id: plugin id
>> + * @cb: callback of type qemu_plugin_vcpu_syscall_cb_t
>> + *
>> + * This registers a callback for every syscall executed by the guest. The @cb
>> + * function is executed before a syscall is handled by the host.
>> + */
>>   QEMU_PLUGIN_API
>> -void
>> -qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
>> -                                         qemu_plugin_vcpu_syscall_ret_cb_t cb);
>> +void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
>> +                                          qemu_plugin_vcpu_syscall_cb_t cb);
>>   +/**
>> + * qemu_plugin_register_vcpu_syscall_filter_cb() - register a syscall filter
>> + * callback
>> + * @id: plugin id
>> + * @cb: callback of type qemu_plugin_vcpu_syscall_filter_cb_t
>> + *
>> + * This registers a callback for every syscall executed by the guest. The @cb
>> + * function is executed before a syscall is handled by the host. If the
>> + * callback returns true, the syscall is filtered and will not be executed by
>> + * the host. The callback must then set the syscall return value via the
>> + * corresponding pointer passed to it.
>> + */
>>   QEMU_PLUGIN_API
>>   void
>>   qemu_plugin_register_vcpu_syscall_filter_cb(qemu_plugin_id_t id,
>>                                               qemu_plugin_vcpu_syscall_filter_cb_t cb);
>>   +/**
>> + * qemu_plugin_register_vcpu_syscall_ret_cb() - register a syscall entry
>> + * callback
>> + * @id: plugin id
>> + * @cb: callback of type qemu_plugin_vcpu_syscall_ret_cb_t
>> + *
>> + * This registers a callback for every syscall executed by the guest. The @cb
>> + * function is executed upon return from the host syscall before execution is
>> + * handed back to the guest.
>> + */
>> +QEMU_PLUGIN_API
>> +void
>> +qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
>> +                                         qemu_plugin_vcpu_syscall_ret_cb_t cb);
>>     /**
>>    * qemu_plugin_insn_disas() - return disassembly string for instruction
>> @@ -861,7 +933,6 @@ qemu_plugin_register_vcpu_syscall_filter_cb(qemu_plugin_id_t id,
>>    *
>>    * Returns an allocated string containing the disassembly
>>    */
>> -
>>   QEMU_PLUGIN_API
>>   char *qemu_plugin_insn_disas(const struct qemu_plugin_insn *insn);
>>   @@ -888,6 +959,13 @@ QEMU_PLUGIN_API
>>   void qemu_plugin_vcpu_for_each(qemu_plugin_id_t id,
>>                                  qemu_plugin_vcpu_simple_cb_t cb);
>>   +/**
>> + * qemu_plugin_register_flush_cb() - register code cache flush callback
>> + * @id: plugin ID
>> + * @cb: callback
>> + *
>> + * The @cb function is called every time the code cache is flushed.
>> + */
> 
> Thanks, I was thinking to document this since someone asked a question on IRC a few weeks ago.
> 
> May you add here:
> "This callback can be used to free resources associated with existing translated blocks in a plugin. @cb is guaranteed to run with all cpus being stopped, thus no lock is required within it."

Ok, thanks for the clarification! I wasn't aware of those detailed
semantics, will add it!

> 
>>   QEMU_PLUGIN_API
>>   void qemu_plugin_register_flush_cb(qemu_plugin_id_t id,
>>                                      qemu_plugin_simple_cb_t cb);
>>
>> ---
>> base-commit: 7608a95d2e0bd8c8d069ab77824d02586dd94648
>> change-id: 20260309-add-missing-plugin-docs-159d7ff315f9
>>
> 
> Regards,
> Pierrick

Best regards,
Florian
Re: [PATCH trivial] plugins: add missing docstrings to qemu-plugin.h
Posted by Peter Maydell 1 month ago
On Mon, 9 Mar 2026 at 16:22, Florian Hofhammer
<florian.hofhammer@epfl.ch> wrote:
>
> This patch adds docstrings for typedefs and function declarations in
> include/plugins/qemu-plugin.h that were previously missing. This
> resolves inconsistencies in the docs, e.g., the description for
> qemu_plugin_read_register() referring to qemu_plugin_register_flush_cb()
> but code cache flush callbacks not being documented themselves.
>
> Signed-off-by: Florian Hofhammer <florian.hofhammer@epfl.ch>

I don't know this API either, so a couple of questions below
for those who do:

> +/**
> + * enum qemu_plugin_mem_rw - type of memory access
> + *
> + * @QEMU_PLUGIN_MEM_R: memory read access only
> + * @QEMU_PLUGIN_MEM_W: memory write access only
> + * @QEMU_PLUGIN_MEM_RW: memory read and write access
> + */
>  enum qemu_plugin_mem_rw {
>      QEMU_PLUGIN_MEM_R = 1,
>      QEMU_PLUGIN_MEM_W,
>      QEMU_PLUGIN_MEM_RW,
>  };

This define sets up the values such that you can use
the _R and _W values as bit checks (i.e. _RW == _R | _W).
Is that intentional and can code using the API rely on it,
or must it strictly check against _R and _RW separately?

> +/**
> + * enum qemu_plugin_mem_value_type - size of memory value
> + *
> + * @QEMU_PLUGIN_MEM_VALUE_U8: unsigned 8-bit value
> + * @QEMU_PLUGIN_MEM_VALUE_U16: unsigned 16-bit value
> + * @QEMU_PLUGIN_MEM_VALUE_U32: unsigned 32-bit value
> + * @QEMU_PLUGIN_MEM_VALUE_U64: unsigned 64-bit value
> + * @QEMU_PLUGIN_MEM_VALUE_U128: unsigned 128-bit value
> + */
>  enum qemu_plugin_mem_value_type {
>      QEMU_PLUGIN_MEM_VALUE_U8,
>      QEMU_PLUGIN_MEM_VALUE_U16,
> @@ -353,7 +369,13 @@ enum qemu_plugin_mem_value_type {
>      QEMU_PLUGIN_MEM_VALUE_U128,
>  };

In this enum, the values are set up such that if you have
a qemu_plugin_mem_value_type vt, then the size of the data
is (1 << vt) (i.e., a byte is 0, a short is 1, 32 bits are 2,
and so on up). Is that intentional and can code using the
API rely on it, or must it strictly use the enum only as
something to switch() on to select a length.

I actually ran into that last one in tests/tcg/plugins/mem.c:
update_region_info() has a switch() on this enum which (among
other things) sets val_size in each case, because I didn't
know if it was guaranteed to work to set val_size = 1 << value.type.

thanks
-- PMM
Re: [PATCH trivial] plugins: add missing docstrings to qemu-plugin.h
Posted by Pierrick Bouvier 1 month ago
On 3/9/26 9:35 AM, Peter Maydell wrote:
> On Mon, 9 Mar 2026 at 16:22, Florian Hofhammer
> <florian.hofhammer@epfl.ch> wrote:
>>
>> This patch adds docstrings for typedefs and function declarations in
>> include/plugins/qemu-plugin.h that were previously missing. This
>> resolves inconsistencies in the docs, e.g., the description for
>> qemu_plugin_read_register() referring to qemu_plugin_register_flush_cb()
>> but code cache flush callbacks not being documented themselves.
>>
>> Signed-off-by: Florian Hofhammer <florian.hofhammer@epfl.ch>
> 
> I don't know this API either, so a couple of questions below
> for those who do:
> 
>> +/**
>> + * enum qemu_plugin_mem_rw - type of memory access
>> + *
>> + * @QEMU_PLUGIN_MEM_R: memory read access only
>> + * @QEMU_PLUGIN_MEM_W: memory write access only
>> + * @QEMU_PLUGIN_MEM_RW: memory read and write access
>> + */
>>   enum qemu_plugin_mem_rw {
>>       QEMU_PLUGIN_MEM_R = 1,
>>       QEMU_PLUGIN_MEM_W,
>>       QEMU_PLUGIN_MEM_RW,
>>   };
> 
> This define sets up the values such that you can use
> the _R and _W values as bit checks (i.e. _RW == _R | _W).
> Is that intentional and can code using the API rely on it,
> or must it strictly check against _R and _RW separately?
>

It's intentional, but if people explicitely check both, there is nothing 
wrong with it.
Re: [PATCH trivial] plugins: add missing docstrings to qemu-plugin.h
Posted by Pierrick Bouvier 1 month ago
On 3/9/26 9:35 AM, Peter Maydell wrote:
> On Mon, 9 Mar 2026 at 16:22, Florian Hofhammer
> <florian.hofhammer@epfl.ch> wrote:
>>
>> This patch adds docstrings for typedefs and function declarations in
>> include/plugins/qemu-plugin.h that were previously missing. This
>> resolves inconsistencies in the docs, e.g., the description for
>> qemu_plugin_read_register() referring to qemu_plugin_register_flush_cb()
>> but code cache flush callbacks not being documented themselves.
>>
>> Signed-off-by: Florian Hofhammer <florian.hofhammer@epfl.ch>
> 
> I don't know this API either, so a couple of questions below
> for those who do:
> 
>> +/**
>> + * enum qemu_plugin_mem_rw - type of memory access
>> + *
>> + * @QEMU_PLUGIN_MEM_R: memory read access only
>> + * @QEMU_PLUGIN_MEM_W: memory write access only
>> + * @QEMU_PLUGIN_MEM_RW: memory read and write access
>> + */
>>   enum qemu_plugin_mem_rw {
>>       QEMU_PLUGIN_MEM_R = 1,
>>       QEMU_PLUGIN_MEM_W,
>>       QEMU_PLUGIN_MEM_RW,
>>   };
> 
> This define sets up the values such that you can use
> the _R and _W values as bit checks (i.e. _RW == _R | _W).
> Is that intentional and can code using the API rely on it,
> or must it strictly check against _R and _RW separately?
> 
>> +/**
>> + * enum qemu_plugin_mem_value_type - size of memory value
>> + *
>> + * @QEMU_PLUGIN_MEM_VALUE_U8: unsigned 8-bit value
>> + * @QEMU_PLUGIN_MEM_VALUE_U16: unsigned 16-bit value
>> + * @QEMU_PLUGIN_MEM_VALUE_U32: unsigned 32-bit value
>> + * @QEMU_PLUGIN_MEM_VALUE_U64: unsigned 64-bit value
>> + * @QEMU_PLUGIN_MEM_VALUE_U128: unsigned 128-bit value
>> + */
>>   enum qemu_plugin_mem_value_type {
>>       QEMU_PLUGIN_MEM_VALUE_U8,
>>       QEMU_PLUGIN_MEM_VALUE_U16,
>> @@ -353,7 +369,13 @@ enum qemu_plugin_mem_value_type {
>>       QEMU_PLUGIN_MEM_VALUE_U128,
>>   };
> 
> In this enum, the values are set up such that if you have
> a qemu_plugin_mem_value_type vt, then the size of the data
> is (1 << vt) (i.e., a byte is 0, a short is 1, 32 bits are 2,
> and so on up). Is that intentional and can code using the
> API rely on it, or must it strictly use the enum only as
> something to switch() on to select a length.
>

The latter, see it as something similar to Rust enums, or what theory 
calls an Algebraic data type:
https://doc.rust-lang.org/std/keyword.enum.html

> I actually ran into that last one in tests/tcg/plugins/mem.c:
> update_region_info() has a switch() on this enum which (among
> other things) sets val_size in each case, because I didn't
> know if it was guaranteed to work to set val_size = 1 << value.type.
> 
> thanks
> -- PMM