On 2015-08-03 10:14, Alex Bennée wrote: > This allows the perf tool to map samples to each individual translation > block. This could be expanded for user space but currently it gives > enough information to find any hotblocks by other means. > > Signed-off-by: Alex Bennée <alex.ben...@linaro.org> > > --- > > v2: > - hoist up into translate-all.c > - don't use pointless glib wrappers > - use proper format types for portability > - mark prologue/epilog area > - rebase > > v3: > - fix bracket for perf-map > - find an include for the tb_enable_perfmap() declaration > - checkpatch clean-ups > --- > include/qemu-common.h | 2 ++ > qemu-options.hx | 9 +++++++++ > translate-all.c | 26 ++++++++++++++++++++++++++ > vl.c | 4 ++++ > 4 files changed, 41 insertions(+) > > diff --git a/include/qemu-common.h b/include/qemu-common.h > index fb3da6c..60b87d0 100644 > --- a/include/qemu-common.h > +++ b/include/qemu-common.h > @@ -382,6 +382,8 @@ typedef struct PCIHostDeviceAddress { > void tcg_exec_init(unsigned long tb_size); > bool tcg_enabled(void); > > +void tb_enable_perfmap(void); > + > void cpu_exec_init_all(void); > > /* CPU save/load. */ > diff --git a/qemu-options.hx b/qemu-options.hx > index 77f5853..ae53346 100644 > --- a/qemu-options.hx > +++ b/qemu-options.hx > @@ -3572,6 +3572,15 @@ to the RNG daemon. > > ETEXI > > +DEF("perfmap", 0, QEMU_OPTION_PERFMAP, \ > + "-perfmap generate a /tmp/perf-${pid}.map file for perf\n", > + QEMU_ARCH_ALL) > +STEXI > +@item -perfmap > +@findex -perfmap > +This will cause QEMU to generate a map file for Linux perf tools that will > allow > +basic profiling information to be broken down into basic blocks. > +ETEXI > > HXCOMM This is the last statement. Insert new options before this line! > STEXI > diff --git a/translate-all.c b/translate-all.c > index 60a3d8b..c05e2a5 100644 > --- a/translate-all.c > +++ b/translate-all.c > @@ -27,6 +27,7 @@ > #include <stdio.h> > #include <string.h> > #include <inttypes.h> > +#include <glib.h> > > #include "config.h" > > @@ -133,6 +134,24 @@ static void tb_link_page(TranslationBlock *tb, > tb_page_addr_t phys_pc, > tb_page_addr_t phys_page2); > static TranslationBlock *tb_find_pc(uintptr_t tc_ptr); > > +static FILE *tb_perfmap; > + > +void tb_enable_perfmap(void) > +{ > + gchar *map_file = g_strdup_printf("/tmp/perf-%d.map", getpid()); > + tb_perfmap = fopen(map_file, "w");
What about symlink attacks there? > + g_free(map_file); > +} > + > +static void tb_write_perfmap(tcg_insn_unit *start, int size, target_ulong pc) > +{ > + if (tb_perfmap) { > + fprintf(tb_perfmap, > + "%"PRIxPTR" %x subject-"TARGET_FMT_lx"\n", > + (uintptr_t) start, size, pc); > + } > +} > + > void cpu_gen_init(void) > { > tcg_context_init(&tcg_ctx); > @@ -190,6 +209,7 @@ int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, > int *gen_code_size_ptr > s->code_out_len += gen_code_size; > #endif > > + tb_write_perfmap(gen_code_buf, gen_code_size, tb->pc); > #ifdef DEBUG_DISAS > if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) { > qemu_log("OUT: [size=%d]\n", gen_code_size); > @@ -669,6 +689,12 @@ static inline void code_gen_alloc(size_t tb_size) > tcg_ctx.code_gen_buffer_size - 1024; > tcg_ctx.code_gen_buffer_size -= 1024; > > + if (tb_perfmap) { > + fprintf(tb_perfmap, > + "%"PRIxPTR" %x tcg-prologue-buffer\n", > + (uintptr_t) tcg_ctx.code_gen_prologue, 1024); > + } > + > tcg_ctx.code_gen_buffer_max_size = tcg_ctx.code_gen_buffer_size - > (TCG_MAX_OP_SIZE * OPC_BUF_SIZE); > tcg_ctx.code_gen_max_blocks = tcg_ctx.code_gen_buffer_size / > diff --git a/vl.c b/vl.c > index 0adbbd6..1d2de4f 100644 > --- a/vl.c > +++ b/vl.c > @@ -122,6 +122,7 @@ int main(int argc, char **argv) > #include "qapi-event.h" > #include "exec/semihost.h" > #include "crypto/init.h" > +#include "qemu-common.h" > > #define MAX_VIRTIO_CONSOLES 1 > #define MAX_SCLP_CONSOLES 1 > @@ -3348,6 +3349,9 @@ int main(int argc, char **argv, char **envp) > case QEMU_OPTION_D: > log_file = optarg; > break; > + case QEMU_OPTION_PERFMAP: > + tb_enable_perfmap(); > + break; > case QEMU_OPTION_s: > add_device_config(DEV_GDB, "tcp::" DEFAULT_GDBSTUB_PORT); > break; > -- > 2.5.0 > > -- Aurelien Jarno GPG: 4096R/1DDD8C9B aurel...@aurel32.net http://www.aurel32.net