diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/disas/dis-asm.h | 8 | ||||
| -rw-r--r-- | include/gdbstub/user.h | 10 | ||||
| -rw-r--r-- | include/qemu/plugin.h | 7 | ||||
| -rw-r--r-- | include/qemu/qemu-plugin.h | 142 | ||||
| -rw-r--r-- | include/user/safe-syscall.h | 2 |
5 files changed, 137 insertions, 32 deletions
diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h index 2324f6b1a4..b26867b641 100644 --- a/include/disas/dis-asm.h +++ b/include/disas/dis-asm.h @@ -396,6 +396,14 @@ typedef struct disassemble_info { /* Command line options specific to the target disassembler. */ char * disassembler_options; + /* + * When true instruct the disassembler it may preface the + * disassembly with the opcodes values if it wants to. This is + * mainly for the benefit of the plugin interface which doesn't want + * that. + */ + bool show_opcodes; + /* Field intended to be used by targets in any way they deem suitable. */ void *target_info; diff --git a/include/gdbstub/user.h b/include/gdbstub/user.h index 68b6534130..4c4e5c4c58 100644 --- a/include/gdbstub/user.h +++ b/include/gdbstub/user.h @@ -46,10 +46,16 @@ static inline int gdb_handlesig(CPUState *cpu, int sig) void gdb_signalled(CPUArchState *as, int sig); /** - * gdbserver_fork() - disable gdb stub for child processes. + * gdbserver_fork_start() - inform gdb of the upcoming fork() + */ +void gdbserver_fork_start(void); + +/** + * gdbserver_fork_end() - inform gdb of the completed fork() * @cs: CPU + * @pid: 0 if in child process, -1 if fork failed, child process pid otherwise */ -void gdbserver_fork(CPUState *cs); +void gdbserver_fork_end(CPUState *cs, pid_t pid); /** * gdb_syscall_entry() - inform gdb of syscall entry and yield control to it diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h index b3c94a34aa..12a96cea2a 100644 --- a/include/qemu/plugin.h +++ b/include/qemu/plugin.h @@ -92,6 +92,7 @@ struct qemu_plugin_dyn_cb { /* fields specific to each dyn_cb type go here */ union { struct { + qemu_plugin_u64 entry; enum qemu_plugin_op op; uint64_t imm; } inline_insn; @@ -112,6 +113,12 @@ struct qemu_plugin_insn { bool mem_only; }; +/* A scoreboard is an array of values, indexed by vcpu_index */ +struct qemu_plugin_scoreboard { + GArray *data; + QLIST_ENTRY(qemu_plugin_scoreboard) entry; +}; + /* * qemu_plugin_insn allocate and cleanup functions. We don't expect to * cleanup many of these structures. They are reused for each fresh diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h index 45e2ebc8f8..4fc6c3739b 100644 --- a/include/qemu/qemu-plugin.h +++ b/include/qemu/qemu-plugin.h @@ -52,7 +52,11 @@ typedef uint64_t qemu_plugin_id_t; * The plugins export the API they were built against by exposing the * symbol qemu_plugin_version which can be checked. * - * version 2: removed qemu_plugin_n_vcpus and qemu_plugin_n_max_vcpus + * version 2: + * - removed qemu_plugin_n_vcpus and qemu_plugin_n_max_vcpus + * - Remove qemu_plugin_register_vcpu_{tb, insn, mem}_exec_inline. + * Those functions are replaced by *_per_vcpu variants, which guarantee + * thread-safety for operations. */ extern QEMU_PLUGIN_EXPORT int qemu_plugin_version; @@ -222,6 +226,19 @@ void qemu_plugin_register_vcpu_resume_cb(qemu_plugin_id_t id, struct qemu_plugin_tb; /** struct qemu_plugin_insn - Opaque handle for a translated instruction */ struct qemu_plugin_insn; +/** struct qemu_plugin_scoreboard - Opaque handle for a scoreboard */ +struct qemu_plugin_scoreboard; + +/** + * typedef qemu_plugin_u64 - uint64_t member of an entry in a scoreboard + * + * This field allows to access a specific uint64_t member in one given entry, + * located at a specified offset. Inline operations expect this as entry. + */ +typedef struct { + struct qemu_plugin_scoreboard *score; + size_t offset; +} qemu_plugin_u64; /** * enum qemu_plugin_cb_flags - type of callback @@ -297,23 +314,20 @@ enum qemu_plugin_op { }; /** - * qemu_plugin_register_vcpu_tb_exec_inline() - execution inline op + * qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu() - execution inline op * @tb: the opaque qemu_plugin_tb handle for the translation * @op: the type of qemu_plugin_op (e.g. ADD_U64) - * @ptr: the target memory location for the op + * @entry: entry to run op * @imm: the op data (e.g. 1) * - * Insert an inline op to every time a translated unit executes. - * Useful if you just want to increment a single counter somewhere in - * memory. - * - * Note: ops are not atomic so in multi-threaded/multi-smp situations - * you will get inexact results. + * Insert an inline op on a given scoreboard entry. */ QEMU_PLUGIN_API -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_tb_exec_inline_per_vcpu( + struct qemu_plugin_tb *tb, + enum qemu_plugin_op op, + qemu_plugin_u64 entry, + uint64_t imm); /** * qemu_plugin_register_vcpu_insn_exec_cb() - register insn execution cb @@ -331,19 +345,20 @@ void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn, void *userdata); /** - * qemu_plugin_register_vcpu_insn_exec_inline() - insn execution inline op + * qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu() - insn exec inline op * @insn: the opaque qemu_plugin_insn handle for an instruction * @op: the type of qemu_plugin_op (e.g. ADD_U64) - * @ptr: the target memory location for the op + * @entry: entry to run op * @imm: the op data (e.g. 1) * - * Insert an inline op to every time an instruction executes. Useful - * if you just want to increment a single counter somewhere in memory. + * Insert an inline op to every time an instruction executes. */ QEMU_PLUGIN_API -void qemu_plugin_register_vcpu_insn_exec_inline(struct qemu_plugin_insn *insn, - enum qemu_plugin_op op, - void *ptr, uint64_t imm); +void qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu( + struct qemu_plugin_insn *insn, + enum qemu_plugin_op op, + qemu_plugin_u64 entry, + uint64_t imm); /** * qemu_plugin_tb_n_insns() - query helper for number of insns in TB @@ -553,24 +568,23 @@ void qemu_plugin_register_vcpu_mem_cb(struct qemu_plugin_insn *insn, void *userdata); /** - * qemu_plugin_register_vcpu_mem_inline() - register an inline op to any memory access + * qemu_plugin_register_vcpu_mem_inline_per_vcpu() - inline op for mem access * @insn: handle for instruction to instrument * @rw: apply to reads, writes or both * @op: the op, of type qemu_plugin_op - * @ptr: pointer memory for the op + * @entry: entry to run op * @imm: immediate data for @op * * This registers a inline op every memory access generated by the - * instruction. This provides for a lightweight but not thread-safe - * way of counting the number of operations done. + * instruction. */ QEMU_PLUGIN_API -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); - - +void qemu_plugin_register_vcpu_mem_inline_per_vcpu( + struct qemu_plugin_insn *insn, + enum qemu_plugin_mem_rw rw, + enum qemu_plugin_op op, + qemu_plugin_u64 entry, + uint64_t imm); typedef void (*qemu_plugin_vcpu_syscall_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_index, @@ -752,5 +766,75 @@ QEMU_PLUGIN_API int qemu_plugin_read_register(struct qemu_plugin_register *handle, GByteArray *buf); +/** + * qemu_plugin_scoreboard_new() - alloc a new scoreboard + * + * @element_size: size (in bytes) for one entry + * + * Returns a pointer to a new scoreboard. It must be freed using + * qemu_plugin_scoreboard_free. + */ +QEMU_PLUGIN_API +struct qemu_plugin_scoreboard *qemu_plugin_scoreboard_new(size_t element_size); + +/** + * qemu_plugin_scoreboard_free() - free a scoreboard + * @score: scoreboard to free + */ +QEMU_PLUGIN_API +void qemu_plugin_scoreboard_free(struct qemu_plugin_scoreboard *score); + +/** + * qemu_plugin_scoreboard_find() - get pointer to an entry of a scoreboard + * @score: scoreboard to query + * @vcpu_index: entry index + * + * Returns address of entry of a scoreboard matching a given vcpu_index. This + * address can be modified later if scoreboard is resized. + */ +QEMU_PLUGIN_API +void *qemu_plugin_scoreboard_find(struct qemu_plugin_scoreboard *score, + unsigned int vcpu_index); + +/* Macros to define a qemu_plugin_u64 */ +#define qemu_plugin_scoreboard_u64(score) \ + (qemu_plugin_u64) {score, 0} +#define qemu_plugin_scoreboard_u64_in_struct(score, type, member) \ + (qemu_plugin_u64) {score, offsetof(type, member)} + +/** + * qemu_plugin_u64_add() - add a value to a qemu_plugin_u64 for a given vcpu + * @entry: entry to query + * @vcpu_index: entry index + * @added: value to add + */ +QEMU_PLUGIN_API +void qemu_plugin_u64_add(qemu_plugin_u64 entry, unsigned int vcpu_index, + uint64_t added); + +/** + * qemu_plugin_u64_get() - get value of a qemu_plugin_u64 for a given vcpu + * @entry: entry to query + * @vcpu_index: entry index + */ +QEMU_PLUGIN_API +uint64_t qemu_plugin_u64_get(qemu_plugin_u64 entry, unsigned int vcpu_index); + +/** + * qemu_plugin_u64_set() - set value of a qemu_plugin_u64 for a given vcpu + * @entry: entry to query + * @vcpu_index: entry index + * @val: new value + */ +QEMU_PLUGIN_API +void qemu_plugin_u64_set(qemu_plugin_u64 entry, unsigned int vcpu_index, + uint64_t val); + +/** + * qemu_plugin_u64_sum() - return sum of all vcpu entries in a scoreboard + * @entry: entry to sum + */ +QEMU_PLUGIN_API +uint64_t qemu_plugin_u64_sum(qemu_plugin_u64 entry); #endif /* QEMU_QEMU_PLUGIN_H */ diff --git a/include/user/safe-syscall.h b/include/user/safe-syscall.h index 27b71cdbd8..aa075f4d5c 100644 --- a/include/user/safe-syscall.h +++ b/include/user/safe-syscall.h @@ -134,7 +134,7 @@ extern char safe_syscall_start[]; extern char safe_syscall_end[]; #define safe_syscall(...) \ - safe_syscall_base(&((TaskState *)thread_cpu->opaque)->signal_pending, \ + safe_syscall_base(&get_task_state(thread_cpu)->signal_pending, \ __VA_ARGS__) #endif |