Keep a translation between instrumentation's QICPU and CPUState objects to avoid exposing QEMU's internals to instrumentation clients.
Signed-off-by: Lluís Vilanova <vilan...@ac.upc.edu> --- cpus-common.c | 9 +++++++++ instrument/control.c | 23 +++++++++++++++++++++++ instrument/control.h | 36 ++++++++++++++++++++++++++++++++++++ instrument/control.inc.h | 23 +++++++++++++++++++++++ 4 files changed, 91 insertions(+) diff --git a/cpus-common.c b/cpus-common.c index 59f751ecf9..ec5f46cc3d 100644 --- a/cpus-common.c +++ b/cpus-common.c @@ -22,6 +22,9 @@ #include "exec/cpu-common.h" #include "qom/cpu.h" #include "sysemu/cpus.h" +#if defined(CONFIG_INSTRUMENT) +#include "instrument/control.h" +#endif static QemuMutex qemu_cpu_list_lock; static QemuCond exclusive_cond; @@ -84,6 +87,9 @@ void cpu_list_add(CPUState *cpu) } else { assert(!cpu_index_auto_assigned); } +#if defined(CONFIG_INSTRUMENT) + instr_cpu_add(cpu); +#endif QTAILQ_INSERT_TAIL(&cpus, cpu, node); qemu_mutex_unlock(&qemu_cpu_list_lock); @@ -102,6 +108,9 @@ void cpu_list_remove(CPUState *cpu) assert(!(cpu_index_auto_assigned && cpu != QTAILQ_LAST(&cpus, CPUTailQ))); QTAILQ_REMOVE(&cpus, cpu, node); +#if defined(CONFIG_INSTRUMENT) + instr_cpu_remove(cpu); +#endif cpu->cpu_index = UNASSIGNED_CPU_INDEX; qemu_mutex_unlock(&qemu_cpu_list_lock); } diff --git a/instrument/control.c b/instrument/control.c index 3630d6b3be..8cf2b4f967 100644 --- a/instrument/control.c +++ b/instrument/control.c @@ -13,10 +13,33 @@ #include "instrument/load.h" #include "instrument/qemu-instr/control.h" #include "qemu/compiler.h" +#include "qom/cpu.h" + __thread InstrState instr_cur_state; +unsigned int instr_cpus_count; +CPUState **instr_cpus; + +void instr_cpu_add(CPUState *vcpu) +{ + unsigned int idx = vcpu->cpu_index; + if (idx >= instr_cpus_count) { + instr_cpus_count = idx + 1; + instr_cpus = realloc(instr_cpus, + sizeof(*instr_cpus) * instr_cpus_count); + } + instr_cpus[idx] = vcpu; +} + +void instr_cpu_remove(CPUState *vcpu) +{ + unsigned int idx = vcpu->cpu_index; + instr_cpus[idx] = NULL; +} + + qi_fini_fn instr_event__fini_fn; void *instr_event__fini_data; diff --git a/instrument/control.h b/instrument/control.h index f2b085f69b..57cea07fa7 100644 --- a/instrument/control.h +++ b/instrument/control.h @@ -10,6 +10,42 @@ #ifndef INSTRUMENT__CONTROL_H #define INSTRUMENT__CONTROL_H +#include "qemu/typedefs.h" +#include "instrument/qemu-instr/types.h" + + +/** + * instr_cpu_add: + * + * Make @vcpu available to instrumentation clients. + * + * Precondition: cpu_list_lock(). + */ +void instr_cpu_add(CPUState *vcpu); + +/** + * instr_cpu_remove: + * + * Make @vcpu unavailable to instrumentation clients. + * + * Precondition: cpu_list_lock(). + */ +void instr_cpu_remove(CPUState *vcpu); + +/** + * instr_cpu_to_qicpu: + * + * Get the #QICPU corresponding to the given #CPUState. + */ +static inline QICPU instr_cpu_to_qicpu(CPUState *vcpu); + +/** + * instr_cpu_from_qicpu: + * + * Get the #CPUState corresponding to the given #QICPU. + */ +static inline CPUState *instr_cpu_from_qicpu(QICPU vcpu); + /** * InstrState: diff --git a/instrument/control.inc.h b/instrument/control.inc.h index 0f649f4caa..45daae7d1d 100644 --- a/instrument/control.inc.h +++ b/instrument/control.inc.h @@ -7,9 +7,32 @@ * See the COPYING file in the top-level directory. */ +#include "qemu/osdep.h" #include "qemu/atomic.h" #include "qemu/compiler.h" +#include "qom/cpu.h" #include <stdbool.h> +#include <stdint.h> + + +extern unsigned int instr_cpus_count; +extern CPUState **instr_cpus; + +static inline QICPU instr_cpu_to_qicpu(CPUState *vcpu) +{ + uintptr_t idx = vcpu->cpu_index; + return (QICPU)idx; +} + +static inline CPUState *instr_cpu_from_qicpu(QICPU vcpu) +{ + unsigned int idx = (uintptr_t)vcpu; + if (idx >= instr_cpus_count) { + return NULL; + } else { + return instr_cpus[idx]; + } +} extern __thread InstrState instr_cur_state;