All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism
@ 2016-01-14 10:55 Peer Adelt
  2016-01-14 10:55 ` [Qemu-devel] [RFC PATCH 1/3] tb-annotation: Added annotation XML file parser Peer Adelt
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Peer Adelt @ 2016-01-14 10:55 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peer Adelt, kbastian

Hey guys :)

We have developed a generic concept to annotate TranslationBlocks during
runtime. The initial idea was to use it for time annotation with data from
static analysis tools. However, we have kept this approach as generic as
possible to allow other kinds of annotation (e.g. power consumption, etc.).

Our extension expects an XML file specifying the CFG of the program (similar
to what you get from "gcc -ftree-dump-cfg"), where the edges are annotated
with the data, that QEMU ought to accumulate during program execution. Each
edge has a source and target context in which it is executed.
For example: a for-loop that runs several times has its own context dependent
edge for each iteration. We plan on making this more flexible by allowing
to specify iterative context edges, i.e. from context n to context n+1.

This approach is not limited to one target architecture but we only tested
it for ARM and TriCore so far.

To show the current state of this patch we have attached a very small example
consisting of an ARM STM32F205 program and a timing annotation XML file (see
reply to this letter). You can provide the XML file to QEMU with the 
"-annotation <XML-File>" option. During execution, the "value_sum" field of
the CPUState data structure will accumulate a total value of 70 (cycles).

Are there any comments? Is this in general a good idea to be added to upstream
QEMU?

All the best,
Peer

Peer Adelt (3):
  tb-annotation: Added annotation XML file parser
  tb-annotation: Add control flow graph mapper
  tb-annotation: Activate annotation extension

 Makefile                                     |   5 +-
 Makefile.objs                                |   4 +
 Makefile.target                              |   4 +-
 configure                                    |  13 ++
 include/exec/gen-icount.h                    |  18 +++
 include/qom/cpu.h                            |   9 ++
 include/tb-annotation/tb-annotation-parser.h |  29 +++++
 include/tb-annotation/tb-annotation.h        |  64 ++++++++++
 qemu-options.hx                              |   8 ++
 tb-annotation/Makefile.objs                  |   1 +
 tb-annotation/tb-annotation-parser.c         | 174 +++++++++++++++++++++++++++
 tcg-runtime.c                                |  99 +++++++++++++++
 tcg/tcg-runtime.h                            |   4 +
 vl.c                                         |  25 ++++
 14 files changed, 454 insertions(+), 3 deletions(-)
 create mode 100644 include/tb-annotation/tb-annotation-parser.h
 create mode 100644 include/tb-annotation/tb-annotation.h
 create mode 100644 tb-annotation/Makefile.objs
 create mode 100644 tb-annotation/tb-annotation-parser.c

-- 
2.5.0

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Qemu-devel] [RFC PATCH 1/3] tb-annotation: Added annotation XML file parser
  2016-01-14 10:55 [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism Peer Adelt
@ 2016-01-14 10:55 ` Peer Adelt
  2016-01-14 10:55 ` [Qemu-devel] [RFC PATCH 2/3] tb-annotation: Add control flow graph mapper Peer Adelt
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Peer Adelt @ 2016-01-14 10:55 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peer Adelt, kbastian

The XML file contains a control flow graph, where each edge
is annotated with a context-dependent value. The parser reads
this information into a data structure within CPUState.

Signed-off-by: Peer Adelt <peer.adelt@c-lab.de>
---
 include/qom/cpu.h                            |   9 ++
 include/tb-annotation/tb-annotation-parser.h |  29 +++++
 include/tb-annotation/tb-annotation.h        |  64 ++++++++++
 tb-annotation/tb-annotation-parser.c         | 174 +++++++++++++++++++++++++++
 4 files changed, 276 insertions(+)
 create mode 100644 include/tb-annotation/tb-annotation-parser.h
 create mode 100644 include/tb-annotation/tb-annotation.h
 create mode 100644 tb-annotation/tb-annotation-parser.c

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 51a1323..afc532b 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -30,6 +30,10 @@
 #include "qemu/thread.h"
 #include "qemu/typedefs.h"
 
+#ifdef CONFIG_TB_ANNOTATION
+#include "tb-annotation/tb-annotation.h"
+#endif
+
 typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size,
                                      void *opaque);
 
@@ -329,6 +333,11 @@ struct CPUState {
      */
     bool throttle_thread_scheduled;
 
+#ifdef CONFIG_TB_ANNOTATION
+    /* Used to annotate cpu state during tb execution */
+    TbAnnotation *tb_annotation;
+#endif
+
     /* Note that this is accessed at the start of every TB via a negative
        offset from AREG0.  Leave this field at the end so as to make the
        (absolute value) offset as small as possible.  This reduces code
diff --git a/include/tb-annotation/tb-annotation-parser.h b/include/tb-annotation/tb-annotation-parser.h
new file mode 100644
index 0000000..aacab8e
--- /dev/null
+++ b/include/tb-annotation/tb-annotation-parser.h
@@ -0,0 +1,29 @@
+/*
+ *  Copyright (c) 2015-2016 Bastian Koppelmann
+ *                          Peer Adelt
+ *                          C-Lab/Paderborn University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INCLUDE_TB_ANNOTATION_PARSER_H_
+#define INCLUDE_TB_ANNOTATION_PARSER_H_
+
+#include "tb-annotation/tb-annotation.h"
+
+void tb_annotation_xml_init(const char *filename);
+void tb_annotation_xml_close(void);
+TbAnnotation *tb_annotation_parse(const char *filename);
+
+#endif /* INCLUDE_TB_ANNOTATION_PARSER_H_ */
diff --git a/include/tb-annotation/tb-annotation.h b/include/tb-annotation/tb-annotation.h
new file mode 100644
index 0000000..e1093b2
--- /dev/null
+++ b/include/tb-annotation/tb-annotation.h
@@ -0,0 +1,64 @@
+/*
+ *  Copyright (c) 2015-2016 Bastian Koppelmann
+ *                          Peer Adelt
+ *                          C-Lab/Paderborn University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INCLUDE_TB_ANNOTATION_H_
+#define INCLUDE_TB_ANNOTATION_H_
+
+#include <glib.h>
+
+typedef struct tb_leaving_edge_tuple TbAnnotationLeavingEdgeTuple;
+typedef struct tb_annotation_block TbAnnotationBlock;
+typedef struct tb_annotation_edge TbAnnotationEdge;
+typedef struct tb_annotation TbAnnotation;
+
+struct tb_leaving_edge_tuple {
+    TbAnnotationEdge *out1;
+    TbAnnotationEdge *out2;
+};
+
+struct tb_annotation_block {
+    uint8_t is_end_block;
+    const char *id;
+    unsigned int address;
+    /* This hashtable points to all pairs of leaving edges
+     * from all source contexts.
+     * Note: string -> tb_leaving_edge_tuple
+     */
+    GHashTable *out_edges_hash_table;
+};
+
+struct tb_annotation_edge {
+    TbAnnotationBlock *source;
+    TbAnnotationBlock *target;
+    const char *source_context;
+    const char *target_context;
+    unsigned int value;
+};
+
+struct tb_annotation {
+
+    TbAnnotationBlock *last_block;
+    const char *last_ctx;
+    /* Hashes from PC to TbAnnotationBlock */
+    GHashTable *tb_annotation_blocks;
+    unsigned int value_sum;
+
+};
+
+#endif /* INCLUDE_TB_ANNOTATION_H_ */
diff --git a/tb-annotation/tb-annotation-parser.c b/tb-annotation/tb-annotation-parser.c
new file mode 100644
index 0000000..b3cb2e7
--- /dev/null
+++ b/tb-annotation/tb-annotation-parser.c
@@ -0,0 +1,174 @@
+/*
+ *  Copyright (c) 2015-2016 Bastian Koppelmann
+ *                          Peer Adelt
+ *                          C-Lab/Paderborn University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <assert.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/tree.h>
+
+#include "tb-annotation/tb-annotation.h"
+#include "tb-annotation/tb-annotation-parser.h"
+
+xmlDocPtr tb_annotation_doc;
+xmlXPathContextPtr tb_annotation_xpathctx;
+xmlXPathObjectPtr tb_annotation_xpath;
+
+void tb_annotation_xml_init(const char *filename)
+{
+
+    /* Load XML file */
+    tb_annotation_doc = xmlParseFile(filename);
+    assert(tb_annotation_doc);
+
+    /* Create XPath evaluation context */
+    tb_annotation_xpathctx = xmlXPathNewContext(tb_annotation_doc);
+    assert(tb_annotation_xpathctx);
+}
+
+void tb_annotation_xml_close(void)
+{
+
+    xmlXPathFreeObject(tb_annotation_xpath);
+    xmlXPathFreeContext(tb_annotation_xpathctx);
+    xmlFreeDoc(tb_annotation_doc);
+}
+
+static int32_t tb_annotation_xml_evalxpath(const char *xpath,
+        xmlNodeSetPtr *nodes)
+{
+
+    /* Evaluate the expression */
+    tb_annotation_xpath = xmlXPathEvalExpression(BAD_CAST xpath,
+            tb_annotation_xpathctx);
+    assert(tb_annotation_xpath);
+
+    /* Set the return value */
+    *nodes = tb_annotation_xpath->nodesetval;
+    return tb_annotation_xpath->nodesetval->nodeNr;
+}
+
+TbAnnotation *tb_annotation_parse(const char *filename)
+{
+    int32_t i;
+    xmlNodeSetPtr nodes = NULL;
+    TbAnnotationBlock *cur_block;
+    TbAnnotationLeavingEdgeTuple *cur_leaving_edge_tuple;
+    TbAnnotationEdge *cur_edge;
+    GHashTable *id_to_block = g_hash_table_new(g_str_hash, g_str_equal);
+    TbAnnotation *tba = g_new0(TbAnnotation, 1);
+    tba->tb_annotation_blocks = g_hash_table_new(g_int_hash, g_int_equal);
+
+    /* Open XML file */
+    tb_annotation_xml_init(filename);
+
+    /* Parse Blocks */
+    tb_annotation_xml_evalxpath("/QEMU-annotation/Blocks/Block", &nodes);
+    for (i = 0; i < nodes->nodeNr; i++) {
+
+        /* Read XML description of current block */
+        const char *id = (const char *) xmlGetNoNsProp(
+                nodes->nodeTab[i], BAD_CAST "id");
+        const char *address_str = (const char *) xmlGetNoNsProp(
+                nodes->nodeTab[i], BAD_CAST "address");
+
+        /* Create the block */
+        cur_block = g_new0(TbAnnotationBlock, 1);
+        cur_block->out_edges_hash_table = g_hash_table_new(
+                g_str_hash, g_str_equal);
+        cur_block->id = id;
+        cur_block->address = -1;
+
+        if (g_strcmp0("None", address_str) == 0) {
+
+            cur_block->is_end_block = 1;
+
+        } else {
+
+            cur_block->is_end_block = 0;
+            sscanf(address_str, "%x", &cur_block->address);
+
+            /* Store current block in TbAnnotations PC -> block map */
+            g_hash_table_insert(tba->tb_annotation_blocks, &cur_block->address,
+                    cur_block);
+        }
+
+        /* Store in id -> block map for edge creation */
+        g_hash_table_insert(id_to_block, (gpointer) id, cur_block);
+    }
+
+    /* Parse Edges (also adding out_edges to blocks) */
+    tb_annotation_xml_evalxpath("/QEMU-annotation/Edges/Edge", &nodes);
+    for (i = 0; i < nodes->nodeNr; i++) {
+
+        /* Read XML description of current edge */
+        const char *source_id = (const char *) xmlGetNoNsProp(
+                nodes->nodeTab[i], BAD_CAST "source");
+        const char *source_ctx = (const char *) xmlGetNoNsProp(
+                nodes->nodeTab[i], BAD_CAST "source_context");
+        const char *target_id = (const char *) xmlGetNoNsProp(
+                nodes->nodeTab[i], BAD_CAST "target");
+        const char *target_ctx = (const char *) xmlGetNoNsProp(
+                nodes->nodeTab[i], BAD_CAST "target_context");
+        const char *value_str = (const char *) xmlGetNoNsProp(
+                nodes->nodeTab[i], BAD_CAST "value");
+
+        /* Create the edge */
+        cur_edge = g_new0(TbAnnotationEdge, 1);
+        cur_edge->source = g_hash_table_lookup(id_to_block, source_id);
+        cur_edge->target = g_hash_table_lookup(id_to_block, target_id);
+        cur_edge->source_context = source_ctx;
+        cur_edge->target_context = target_ctx;
+        sscanf(value_str, "%u", &cur_edge->value);
+
+        /* Store this edge in source blocks leaving_edge_tuple */
+        cur_leaving_edge_tuple = g_hash_table_lookup(
+                cur_edge->source->out_edges_hash_table,
+                cur_edge->source_context);
+        if (cur_leaving_edge_tuple == NULL) {
+            cur_leaving_edge_tuple = g_new0(TbAnnotationLeavingEdgeTuple, 1);
+            g_hash_table_insert(cur_edge->source->out_edges_hash_table,
+                    (gpointer) cur_edge->source_context,
+                    cur_leaving_edge_tuple);
+        }
+        /* There must be free space in the leaving_edge_tuple ... */
+        assert(cur_leaving_edge_tuple->out1 == NULL ||
+               cur_leaving_edge_tuple->out2 == NULL);
+        if (cur_leaving_edge_tuple->out1 == NULL) {
+            cur_leaving_edge_tuple->out1 = cur_edge;
+        } else {
+            cur_leaving_edge_tuple->out2 = cur_edge;
+        }
+    }
+
+    /* Parse Startcontext */
+    tb_annotation_xml_evalxpath("/QEMU-annotation/Start-context", &nodes);
+    assert(nodes->nodeNr == 1);
+    tba->last_ctx = (const char *) xmlGetNoNsProp(nodes->nodeTab[0],
+    BAD_CAST "value");
+
+    /* Destroy temporary block id -> block map */
+    g_hash_table_destroy(id_to_block);
+
+    /* Close XML file */
+    tb_annotation_xml_close();
+
+    /* Return TbAnnotation data */
+    return tba;
+}
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [RFC PATCH 2/3] tb-annotation: Add control flow graph mapper
  2016-01-14 10:55 [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism Peer Adelt
  2016-01-14 10:55 ` [Qemu-devel] [RFC PATCH 1/3] tb-annotation: Added annotation XML file parser Peer Adelt
@ 2016-01-14 10:55 ` Peer Adelt
  2016-01-14 10:55 ` [Qemu-devel] [RFC PATCH 3/3] tb-annotation: Activate annotation extension Peer Adelt
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Peer Adelt @ 2016-01-14 10:55 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peer Adelt, kbastian

Added helper function at the start of every TranslationBlock
that maps the sequence of static basic blocks (obtained from
the XML file) to the current TranslationBlock. The helper also
accumulates the values that are annotated on the corresponding
edges of the control flow graph.

Signed-off-by: Peer Adelt <peer.adelt@c-lab.de>
---
 include/exec/gen-icount.h | 18 +++++++++
 tcg-runtime.c             | 99 +++++++++++++++++++++++++++++++++++++++++++++++
 tcg/tcg-runtime.h         |  4 ++
 3 files changed, 121 insertions(+)

diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index 05d89d3..0b8821b 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -14,6 +14,11 @@ static inline void gen_tb_start(TranslationBlock *tb)
     TCGv_i32 count, flag, imm;
     int i;
 
+#ifdef CONFIG_TB_ANNOTATION
+    TCGv_ptr annotation_ptr;
+    TCGv_i64 pc;
+#endif
+
     exitreq_label = gen_new_label();
     flag = tcg_temp_new_i32();
     tcg_gen_ld_i32(flag, cpu_env,
@@ -21,6 +26,17 @@ static inline void gen_tb_start(TranslationBlock *tb)
     tcg_gen_brcondi_i32(TCG_COND_NE, flag, 0, exitreq_label);
     tcg_temp_free_i32(flag);
 
+#ifdef CONFIG_TB_ANNOTATION
+    pc = tcg_const_i64(tb->pc);
+    annotation_ptr = tcg_temp_new_ptr();
+    tcg_gen_ld_ptr(annotation_ptr, cpu_env,
+                   -ENV_OFFSET + offsetof(CPUState, tb_annotation));
+
+    gen_helper_annotation(pc, annotation_ptr);
+    tcg_temp_free_i64(pc);
+    tcg_temp_free_ptr(annotation_ptr);
+#endif
+
     if (!(tb->cflags & CF_USE_ICOUNT)) {
         return;
     }
@@ -45,6 +61,8 @@ static inline void gen_tb_start(TranslationBlock *tb)
     tcg_gen_st16_i32(count, cpu_env,
                      -ENV_OFFSET + offsetof(CPUState, icount_decr.u16.low));
     tcg_temp_free_i32(count);
+
+
 }
 
 static void gen_tb_end(TranslationBlock *tb, int num_insns)
diff --git a/tcg-runtime.c b/tcg-runtime.c
index 9daba69..fc2526c 100644
--- a/tcg-runtime.c
+++ b/tcg-runtime.c
@@ -29,6 +29,10 @@
 
 #include "exec/helper-head.h"
 
+#ifdef CONFIG_TB_ANNOTATION
+#include "tb-annotation/tb-annotation.h"
+#endif
+
 #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
   dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2));
 
@@ -107,3 +111,98 @@ int64_t HELPER(mulsh_i64)(int64_t arg1, int64_t arg2)
     muls64(&l, &h, arg1, arg2);
     return h;
 }
+
+#ifdef CONFIG_TB_ANNOTATION
+static inline void take_final_edge(TbAnnotation *env, TbAnnotationEdge *edge)
+{
+    /* Store current context and block */
+    env->last_ctx = edge->target_context;
+    env->last_block = edge->target;
+    /* Accumulate value */
+    env->value_sum += edge->value;
+}
+
+static inline void take_edge(TbAnnotation *env, TbAnnotationEdge *edge)
+{
+    TbAnnotationLeavingEdgeTuple *out;
+
+    /* Store current context and block */
+    env->last_ctx = edge->target_context;
+    env->last_block = edge->target;
+    /* Accumulate value */
+    env->value_sum += edge->value;
+
+    /* Check whether we are at the end of our analysis... */
+    if (env->last_block->out_edges_hash_table != NULL) {
+        out = g_hash_table_lookup(env->last_block->out_edges_hash_table,
+                                  env->last_ctx);
+        if (out != NULL && out->out1->target->is_end_block) {
+            take_final_edge(env, out->out1);
+        }
+    }
+}
+
+void HELPER(annotation)(uint64_t pc, void *opaque)
+{
+    TbAnnotation *env = (TbAnnotation *) opaque;
+    TbAnnotationBlock *b;
+    TbAnnotationLeavingEdgeTuple *out;
+
+    if (!env) {
+        return;
+    }
+
+    /* does the block corresponding to pc exist? */
+    if (!g_hash_table_contains(env->tb_annotation_blocks, &pc)) {
+        return;
+    }
+    /* if last_block == NULL we're in the first block */
+    if (env->last_block == NULL) {
+
+        b = (TbAnnotationBlock *)g_hash_table_lookup(env->tb_annotation_blocks,
+                                                     &pc);
+        env->last_block = b;
+
+    } else {
+        /* while not reached block with current pc (target)
+         * take the next distinct edge if it exists
+         * otherwise we're one edge away from the target and
+         * take the edge directly leading to the target
+         */
+        out = g_hash_table_lookup(env->last_block->out_edges_hash_table,
+                                  env->last_ctx);
+
+        while (out != NULL && out->out2 == NULL) {
+            /* We found a distinct path to "out1" */
+            take_edge(env, out->out1);
+
+            /* Have we reached our target? */
+            if (env->last_block->address == pc) {
+                return;
+            }
+
+            /* Get the current out edge tuple */
+            out = g_hash_table_lookup(env->last_block->out_edges_hash_table,
+                                      env->last_ctx);
+        }
+
+        /* If we get here, we are on a branch block.
+           Take the edge leading to the target. */
+        if (out != NULL && out->out1->target->address == pc) {
+
+            /* Take this edge */
+            take_edge(env, out->out1);
+
+
+        } else if (out != NULL && out->out2->target->address == pc) {
+
+            /* Take the other edge */
+            take_edge(env, out->out2);
+
+        } else {
+
+            /* Something went terribly wrong here... */
+        }
+    }
+        }
+#endif
diff --git a/tcg/tcg-runtime.h b/tcg/tcg-runtime.h
index 23a0c37..004bf8f 100644
--- a/tcg/tcg-runtime.h
+++ b/tcg/tcg-runtime.h
@@ -14,3 +14,7 @@ DEF_HELPER_FLAGS_2(sar_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
 
 DEF_HELPER_FLAGS_2(mulsh_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
 DEF_HELPER_FLAGS_2(muluh_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
+
+#ifdef CONFIG_TB_ANNOTATION
+DEF_HELPER_2(annotation, void, i64, ptr)
+#endif
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [RFC PATCH 3/3] tb-annotation: Activate annotation extension
  2016-01-14 10:55 [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism Peer Adelt
  2016-01-14 10:55 ` [Qemu-devel] [RFC PATCH 1/3] tb-annotation: Added annotation XML file parser Peer Adelt
  2016-01-14 10:55 ` [Qemu-devel] [RFC PATCH 2/3] tb-annotation: Add control flow graph mapper Peer Adelt
@ 2016-01-14 10:55 ` Peer Adelt
  2016-01-14 10:57 ` [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism Peer Adelt
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Peer Adelt @ 2016-01-14 10:55 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peer Adelt, kbastian

This changeset activates the TranslationBlock annotation
mechanism for the QEMU system mode.

Signed-off-by: Peer Adelt <peer.adelt@c-lab.de>
---
 Makefile                    |  5 +++--
 Makefile.objs               |  4 ++++
 Makefile.target             |  4 +++-
 configure                   | 13 +++++++++++++
 qemu-options.hx             |  8 ++++++++
 tb-annotation/Makefile.objs |  1 +
 vl.c                        | 25 +++++++++++++++++++++++++
 7 files changed, 57 insertions(+), 3 deletions(-)
 create mode 100644 tb-annotation/Makefile.objs

diff --git a/Makefile b/Makefile
index 82b2fc8..c351b31 100644
--- a/Makefile
+++ b/Makefile
@@ -161,7 +161,8 @@ dummy := $(call unnest-vars,, \
                 qom-obj-y \
                 io-obj-y \
                 common-obj-y \
-                common-obj-m)
+                common-obj-m \
+		annotation-obj-y)
 
 ifneq ($(wildcard config-host.mak),)
 include $(SRC_PATH)/tests/Makefile
@@ -204,7 +205,7 @@ subdir-dtc:dtc/libfdt dtc/tests
 dtc/%:
 	mkdir -p $@
 
-$(SUBDIR_RULES): libqemuutil.a libqemustub.a $(common-obj-y) $(qom-obj-y) $(crypto-aes-obj-$(CONFIG_USER_ONLY))
+$(SUBDIR_RULES): libqemuutil.a libqemustub.a $(common-obj-y) $(qom-obj-y) $(crypto-aes-obj-$(CONFIG_USER_ONLY)) $(annotation-obj-$(CONFIG_TB_ANNOTATION))
 
 ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
 romsubdir-%:
diff --git a/Makefile.objs b/Makefile.objs
index dac2c02..9b64358 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -116,3 +116,7 @@ qga-vss-dll-obj-y = qga/
 # contrib
 ivshmem-client-obj-y = contrib/ivshmem-client/
 ivshmem-server-obj-y = contrib/ivshmem-server/
+
+######################################################################
+# annotation
+annotation-obj-y = tb-annotation/
\ No newline at end of file
diff --git a/Makefile.target b/Makefile.target
index 34ddb7e..50a969d 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -178,7 +178,8 @@ dummy := $(call unnest-vars,.., \
                qom-obj-y \
                io-obj-y \
                common-obj-y \
-               common-obj-m)
+               common-obj-m \
+               annotation-obj-y)
 target-obj-y := $(target-obj-y-save)
 all-obj-y += $(common-obj-y)
 all-obj-y += $(target-obj-y)
@@ -187,6 +188,7 @@ all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y)
 all-obj-$(CONFIG_USER_ONLY) += $(crypto-aes-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(crypto-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(io-obj-y)
+all-obj-$(CONFIG_TB_ANNOTATION) += $(annotation-obj-y)
 
 $(QEMU_PROG_BUILD): config-devices.mak
 
diff --git a/configure b/configure
index 83b40fc..5e72e06 100755
--- a/configure
+++ b/configure
@@ -345,6 +345,7 @@ vhdx=""
 numa=""
 tcmalloc="no"
 jemalloc="no"
+tbannotation="no"
 
 # parse CC options first
 for opt do
@@ -1169,6 +1170,10 @@ for opt do
   ;;
   --enable-jemalloc) jemalloc="yes"
   ;;
+  --disable-tbannotation) tbannotation="no"
+  ;;
+  --enable-tbannotation) tbannotation="yes"
+  ;;
   *)
       echo "ERROR: unknown option $opt"
       echo "Try '$0 --help' for more information"
@@ -1391,6 +1396,7 @@ disabled with --disable-FEATURE, default is enabled if available:
   numa            libnuma support
   tcmalloc        tcmalloc support
   jemalloc        jemalloc support
+  tbannotation    TB annotation support
 
 NOTE: The object files are built at the place where configure is launched
 EOF
@@ -4855,6 +4861,7 @@ echo "bzip2 support     $bzip2"
 echo "NUMA host support $numa"
 echo "tcmalloc support  $tcmalloc"
 echo "jemalloc support  $jemalloc"
+echo "TB annotation support $tbannotation"
 
 if test "$sdl_too_old" = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -5400,6 +5407,12 @@ if test "$rdma" = "yes" ; then
   echo "CONFIG_RDMA=y" >> $config_host_mak
 fi
 
+if test "$tbannotation" = "yes" ; then
+  echo "CONFIG_TB_ANNOTATION=y" >> $config_host_mak
+  echo "LIBS+=-lxml2" >> $config_host_mak
+  QEMU_CFLAGS="-I/usr/include/libxml2 $QEMU_CFLAGS"
+fi
+
 # Hold two types of flag:
 #   CONFIG_THREAD_SETNAME_BYTHREAD  - we've got a way of setting the name on
 #                                     a thread we have a handle to
diff --git a/qemu-options.hx b/qemu-options.hx
index 215d00d..e3d9df9 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2737,6 +2737,14 @@ Use @var{bzImage} as kernel image. The kernel can be either a Linux kernel
 or in multiboot format.
 ETEXI
 
+DEF("annotation", HAS_ARG, QEMU_OPTION_annotation, \
+    "-annotation tbAnnotation use 'tbAnnotation' as annotation file\n", QEMU_ARCH_ALL)
+STEXI
+@item -annotation @var{tbAnnotation}
+@findex -annotation
+Use @var{tbAnnotation} as annotation file. TODO: specify file format...
+ETEXI
+
 DEF("append", HAS_ARG, QEMU_OPTION_append, \
     "-append cmdline use 'cmdline' as kernel command line\n", QEMU_ARCH_ALL)
 STEXI
diff --git a/tb-annotation/Makefile.objs b/tb-annotation/Makefile.objs
new file mode 100644
index 0000000..468cd42
--- /dev/null
+++ b/tb-annotation/Makefile.objs
@@ -0,0 +1 @@
+annotation-obj-y += tb-annotation-parser.o
\ No newline at end of file
diff --git a/vl.c b/vl.c
index 5aaea77..02bb11e 100644
--- a/vl.c
+++ b/vl.c
@@ -125,6 +125,8 @@ int main(int argc, char **argv)
 #include "sysemu/replay.h"
 #include "qapi/qmp/qerror.h"
 
+#include "tb-annotation/tb-annotation-parser.h"
+
 #define MAX_VIRTIO_CONSOLES 1
 #define MAX_SCLP_CONSOLES 1
 
@@ -2971,6 +2973,10 @@ int main(int argc, char **argv, char **envp)
     int snapshot, linux_boot;
     const char *initrd_filename;
     const char *kernel_filename, *kernel_cmdline;
+#ifdef CONFIG_TB_ANNOTATION
+    CPUState *cpu = NULL;
+    const char *annotation_filename = NULL;
+#endif
     const char *boot_order = NULL;
     const char *boot_once = NULL;
     DisplayState *ds;
@@ -4017,6 +4023,11 @@ int main(int argc, char **argv, char **envp)
                     exit(1);
                 }
                 break;
+#ifdef CONFIG_TB_ANNOTATION
+            case QEMU_OPTION_annotation:
+                annotation_filename = optarg;
+                break;
+#endif
             default:
                 os_parse_cmd_args(popt->index, optarg);
             }
@@ -4629,6 +4640,20 @@ int main(int argc, char **argv, char **envp)
 
     qdev_machine_creation_done();
 
+#ifdef CONFIG_TB_ANNOTATION
+    if (annotation_filename && (smp_cpus > 1 || smp_cores > 1)) {
+        perror("At the moment only single CPU/core systems are supported " \
+               "by the annotation extension.");
+        exit(1);
+    }
+    if (annotation_filename) {
+        cpu = qemu_get_cpu(0);
+        if (cpu != NULL) {
+            cpu->tb_annotation = tb_annotation_parse(annotation_filename);
+        }
+    }
+#endif
+
     /* TODO: once all bus devices are qdevified, this should be done
      * when bus is created by qdev.c */
     qemu_register_reset(qbus_reset_all_fn, sysbus_get_default());
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism
  2016-01-14 10:55 [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism Peer Adelt
                   ` (2 preceding siblings ...)
  2016-01-14 10:55 ` [Qemu-devel] [RFC PATCH 3/3] tb-annotation: Activate annotation extension Peer Adelt
@ 2016-01-14 10:57 ` Peer Adelt
  2016-01-25 13:54 ` Peter Maydell
  2016-01-28 15:26 ` Frederic Konrad
  5 siblings, 0 replies; 14+ messages in thread
From: Peer Adelt @ 2016-01-14 10:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: kbastian

[-- Attachment #1: Type: text/plain, Size: 2853 bytes --]

On 14.01.2016 11:55, Peer Adelt wrote:
> Hey guys :)
>
> We have developed a generic concept to annotate TranslationBlocks during
> runtime. The initial idea was to use it for time annotation with data from
> static analysis tools. However, we have kept this approach as generic as
> possible to allow other kinds of annotation (e.g. power consumption, etc.).
>
> Our extension expects an XML file specifying the CFG of the program (similar
> to what you get from "gcc -ftree-dump-cfg"), where the edges are annotated
> with the data, that QEMU ought to accumulate during program execution. Each
> edge has a source and target context in which it is executed.
> For example: a for-loop that runs several times has its own context dependent
> edge for each iteration. We plan on making this more flexible by allowing
> to specify iterative context edges, i.e. from context n to context n+1.
>
> This approach is not limited to one target architecture but we only tested
> it for ARM and TriCore so far.
>
> To show the current state of this patch we have attached a very small example
> consisting of an ARM STM32F205 program and a timing annotation XML file (see
> reply to this letter). You can provide the XML file to QEMU with the
> "-annotation <XML-File>" option. During execution, the "value_sum" field of
> the CPUState data structure will accumulate a total value of 70 (cycles).
>
> Are there any comments? Is this in general a good idea to be added to upstream
> QEMU?
>
> All the best,
> Peer
>
> Peer Adelt (3):
>    tb-annotation: Added annotation XML file parser
>    tb-annotation: Add control flow graph mapper
>    tb-annotation: Activate annotation extension
>
>   Makefile                                     |   5 +-
>   Makefile.objs                                |   4 +
>   Makefile.target                              |   4 +-
>   configure                                    |  13 ++
>   include/exec/gen-icount.h                    |  18 +++
>   include/qom/cpu.h                            |   9 ++
>   include/tb-annotation/tb-annotation-parser.h |  29 +++++
>   include/tb-annotation/tb-annotation.h        |  64 ++++++++++
>   qemu-options.hx                              |   8 ++
>   tb-annotation/Makefile.objs                  |   1 +
>   tb-annotation/tb-annotation-parser.c         | 174 +++++++++++++++++++++++++++
>   tcg-runtime.c                                |  99 +++++++++++++++
>   tcg/tcg-runtime.h                            |   4 +
>   vl.c                                         |  25 ++++
>   14 files changed, 454 insertions(+), 3 deletions(-)
>   create mode 100644 include/tb-annotation/tb-annotation-parser.h
>   create mode 100644 include/tb-annotation/tb-annotation.h
>   create mode 100644 tb-annotation/Makefile.objs
>   create mode 100644 tb-annotation/tb-annotation-parser.c
>
See attachment

[-- Attachment #2: annotation-example-project.tar.bz2 --]
[-- Type: application/x-bzip, Size: 6529 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism
  2016-01-14 10:55 [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism Peer Adelt
                   ` (3 preceding siblings ...)
  2016-01-14 10:57 ` [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism Peer Adelt
@ 2016-01-25 13:54 ` Peter Maydell
  2016-01-26 11:02   ` Bastian Koppelmann
  2016-01-28 15:26 ` Frederic Konrad
  5 siblings, 1 reply; 14+ messages in thread
From: Peter Maydell @ 2016-01-25 13:54 UTC (permalink / raw)
  To: Peer Adelt; +Cc: Paolo Bonzini, kbastian, QEMU Developers, Lluís Vilanova

On 14 January 2016 at 10:55, Peer Adelt <peer.adelt@c-lab.de> wrote:
> We have developed a generic concept to annotate TranslationBlocks during
> runtime. The initial idea was to use it for time annotation with data from
> static analysis tools. However, we have kept this approach as generic as
> possible to allow other kinds of annotation (e.g. power consumption, etc.).
>
> Our extension expects an XML file specifying the CFG of the program (similar
> to what you get from "gcc -ftree-dump-cfg")

(Do you mean -fdump-tree-cfg? But that gives rather different output format.)

> , where the edges are annotated
> with the data, that QEMU ought to accumulate during program execution. Each
> edge has a source and target context in which it is executed.
> For example: a for-loop that runs several times has its own context dependent
> edge for each iteration. We plan on making this more flexible by allowing
> to specify iterative context edges, i.e. from context n to context n+1.
>
> This approach is not limited to one target architecture but we only tested
> it for ARM and TriCore so far.
>
> To show the current state of this patch we have attached a very small example
> consisting of an ARM STM32F205 program and a timing annotation XML file (see
> reply to this letter). You can provide the XML file to QEMU with the
> "-annotation <XML-File>" option. During execution, the "value_sum" field of
> the CPUState data structure will accumulate a total value of 70 (cycles).
>
> Are there any comments? Is this in general a good idea to be added to upstream
> QEMU?

Firstly, apologies for not getting round to replying to this earlier.
(I was hoping somebody else might have a more informed view.)
I think this is interesting, but it has a couple of issues that make
it not really suitable for mainline:
 (1) it's a bit askew from what QEMU currently does -- we don't
really do much in the way of providing introspection into what the
guest is doing
 (2) it feels a bit unpolished at the moment (lack of documentation,
doesn't have any existing analysis tools that produce the format that
the code reads that would make it immediately usable by an end-user)

I think that a design that would likely get better traction here with
QEMU upstream would be one where you had tracepoints for relevant
events like "executing new TB", and some means of writing a plugin
to run code on those events, or perhaps just a post-analysis tool that
ran on the trace file. Then the code for reading XML and adding up the
relevant annotations would be confined to the plugin and wouldn't
necessarily need to be upstream at all.

However you should take that design suggestion with a considerable
pinch of salt, as I am very much not up to speed with the current
state of our tracing infrastructure.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism
  2016-01-25 13:54 ` Peter Maydell
@ 2016-01-26 11:02   ` Bastian Koppelmann
  2016-01-27 18:54     ` Lluís Vilanova
  0 siblings, 1 reply; 14+ messages in thread
From: Bastian Koppelmann @ 2016-01-26 11:02 UTC (permalink / raw)
  To: Peter Maydell, Peer Adelt
  Cc: Paolo Bonzini, kbastian, QEMU Developers, Lluís Vilanova

Hi Peter,

thank you for your feedback.

>  (2) it feels a bit unpolished at the moment (lack of documentation,
> doesn't have any existing analysis tools that produce the format that
> the code reads that would make it immediately usable by an end-user)
> 
Sure this is unpolished but we wanted to get feedback before we put too
much work into it.

> I think that a design that would likely get better traction here with
> QEMU upstream would be one where you had tracepoints for relevant
> events like "executing new TB", and some means of writing a plugin
> to run code on those events, or perhaps just a post-analysis tool that
> ran on the trace file. Then the code for reading XML and adding up the
> relevant annotations would be confined to the plugin and wouldn't
> necessarily need to be upstream at all.
> 

We like your idea of a "plugin-api" that exposes hooks for relevant
events since this is more generic than our approach. We came up with a
list of relevant events for tracing:

    - pre-/post-execute_tb
    - pre-/post-translate_tb
    - pre-/post-interrupt
    (- memory access)

These are the hooks that would be sufficient for our ideas for plugins.
Do you have more suggestions for suitable hooks? Also, is there anything
similar already in QEMU on which we could build on?

> However you should take that design suggestion with a considerable
> pinch of salt, as I am very much not up to speed with the current
> state of our tracing infrastructure.

Who would I ask for the current state of tracing? Stefan?

Cheers,
Bastian

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism
  2016-01-26 11:02   ` Bastian Koppelmann
@ 2016-01-27 18:54     ` Lluís Vilanova
  2016-01-28 13:40       ` Bastian Koppelmann
  0 siblings, 1 reply; 14+ messages in thread
From: Lluís Vilanova @ 2016-01-27 18:54 UTC (permalink / raw)
  To: Bastian Koppelmann
  Cc: Peter Maydell, Paolo Bonzini, kbastian, QEMU Developers, Peer Adelt

Bastian Koppelmann writes:

> Hi Peter,
> thank you for your feedback.

>> (2) it feels a bit unpolished at the moment (lack of documentation,
>> doesn't have any existing analysis tools that produce the format that
>> the code reads that would make it immediately usable by an end-user)
>> 
> Sure this is unpolished but we wanted to get feedback before we put too
> much work into it.

>> I think that a design that would likely get better traction here with
>> QEMU upstream would be one where you had tracepoints for relevant
>> events like "executing new TB", and some means of writing a plugin
>> to run code on those events, or perhaps just a post-analysis tool that
>> ran on the trace file. Then the code for reading XML and adding up the
>> relevant annotations would be confined to the plugin and wouldn't
>> necessarily need to be upstream at all.
>> 

> We like your idea of a "plugin-api" that exposes hooks for relevant
> events since this is more generic than our approach. We came up with a
> list of relevant events for tracing:

>     - pre-/post-execute_tb
>     - pre-/post-translate_tb
>     - pre-/post-interrupt
>     (- memory access)

> These are the hooks that would be sufficient for our ideas for plugins.
> Do you have more suggestions for suitable hooks? Also, is there anything
> similar already in QEMU on which we could build on?

There is this modified version I wrote [1], which precisely provides a plugin
infrastructure to attach callbacks into guest code events (a binary
instrumentation framework based on QEMU). At the time, the discussion resolved
that a full code instrumentation interface for plugins was too much code that
regular QEMU users & developers would not care about, easily leading to bitrot.

Instead, the list resolved (AFAIU) that it would be better to mainstream support
for guest code events, and make instrumentation an unofficial extension. I've
been (slowly) working to separate both pieces, making instrumentation a QEMU
patch that can be easily maintained out of tree.

The last patch series I sent sets the final stone on the core infrastructure for
the mainline part, just missing the patches I have queued to start adding guest
code trace events.

So, I'd say that such support is on the list of current developments (at least
mine, specially now that I have a bit more time for it). But getting the core
infrastructure mainlined takes some time to ensure it makes sense and can be
easily maintained and be generally usefull to vanilla QEMU.


[1] https://projects.gso.ac.upc.edu/projects/qemu-dbi
    The code is not up-to-date with the latest QEMU

Cheers,
  Lluis

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism
  2016-01-27 18:54     ` Lluís Vilanova
@ 2016-01-28 13:40       ` Bastian Koppelmann
  2016-01-28 18:29         ` Lluís Vilanova
  0 siblings, 1 reply; 14+ messages in thread
From: Bastian Koppelmann @ 2016-01-28 13:40 UTC (permalink / raw)
  To: Lluís Vilanova
  Cc: Peter Maydell, Paolo Bonzini, kbastian, QEMU Developers, Peer Adelt

Hi Lluis,

On 01/27/2016 07:54 PM, Lluís Vilanova wrote:
> There is this modified version I wrote [1], which precisely provides a plugin
> infrastructure to attach callbacks into guest code events (a binary
> instrumentation framework based on QEMU). At the time, the discussion resolved
> that a full code instrumentation interface for plugins was too much code that
> regular QEMU users & developers would not care about, easily leading to bitrot.
> 

This is too bad but looking at the discussion back then the
argumentation is reasonable since an instrumentation API would and
should touch everything in QEMU.

> Instead, the list resolved (AFAIU) that it would be better to mainstream support
> for guest code events, and make instrumentation an unofficial extension. I've
> been (slowly) working to separate both pieces, making instrumentation a QEMU
> patch that can be easily maintained out of tree.
> 
> The last patch series I sent sets the final stone on the core infrastructure for
> the mainline part, just missing the patches I have queued to start adding guest
> code trace events.

Can you give me the name of the series.

> 
> So, I'd say that such support is on the list of current developments (at least
> mine, specially now that I have a bit more time for it). But getting the core
> infrastructure mainlined takes some time to ensure it makes sense and can be
> easily maintained and be generally usefull to vanilla QEMU.
> 

For us such a API would make a lot of sense and there is no benefit for
us to do our own API. Would it make sense for you if we helped you?

Cheers,
Bastian

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism
  2016-01-14 10:55 [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism Peer Adelt
                   ` (4 preceding siblings ...)
  2016-01-25 13:54 ` Peter Maydell
@ 2016-01-28 15:26 ` Frederic Konrad
  2016-02-04 14:59   ` Bastian Koppelmann
  5 siblings, 1 reply; 14+ messages in thread
From: Frederic Konrad @ 2016-01-28 15:26 UTC (permalink / raw)
  To: Peer Adelt, qemu-devel; +Cc: Mark Burton, kbastian, Guillaume Delbergue

Hi,

Is there a git tree with this series somewhere?
Looks nice.

Thanks,
Fred

On 14/01/2016 11:55, Peer Adelt wrote:
> Hey guys :)
>
> We have developed a generic concept to annotate TranslationBlocks during
> runtime. The initial idea was to use it for time annotation with data from
> static analysis tools. However, we have kept this approach as generic as
> possible to allow other kinds of annotation (e.g. power consumption, etc.).
>
> Our extension expects an XML file specifying the CFG of the program (similar
> to what you get from "gcc -ftree-dump-cfg"), where the edges are annotated
> with the data, that QEMU ought to accumulate during program execution. Each
> edge has a source and target context in which it is executed.
> For example: a for-loop that runs several times has its own context dependent
> edge for each iteration. We plan on making this more flexible by allowing
> to specify iterative context edges, i.e. from context n to context n+1.
>
> This approach is not limited to one target architecture but we only tested
> it for ARM and TriCore so far.
>
> To show the current state of this patch we have attached a very small example
> consisting of an ARM STM32F205 program and a timing annotation XML file (see
> reply to this letter). You can provide the XML file to QEMU with the 
> "-annotation <XML-File>" option. During execution, the "value_sum" field of
> the CPUState data structure will accumulate a total value of 70 (cycles).
>
> Are there any comments? Is this in general a good idea to be added to upstream
> QEMU?
>
> All the best,
> Peer
>
> Peer Adelt (3):
>   tb-annotation: Added annotation XML file parser
>   tb-annotation: Add control flow graph mapper
>   tb-annotation: Activate annotation extension
>
>  Makefile                                     |   5 +-
>  Makefile.objs                                |   4 +
>  Makefile.target                              |   4 +-
>  configure                                    |  13 ++
>  include/exec/gen-icount.h                    |  18 +++
>  include/qom/cpu.h                            |   9 ++
>  include/tb-annotation/tb-annotation-parser.h |  29 +++++
>  include/tb-annotation/tb-annotation.h        |  64 ++++++++++
>  qemu-options.hx                              |   8 ++
>  tb-annotation/Makefile.objs                  |   1 +
>  tb-annotation/tb-annotation-parser.c         | 174 +++++++++++++++++++++++++++
>  tcg-runtime.c                                |  99 +++++++++++++++
>  tcg/tcg-runtime.h                            |   4 +
>  vl.c                                         |  25 ++++
>  14 files changed, 454 insertions(+), 3 deletions(-)
>  create mode 100644 include/tb-annotation/tb-annotation-parser.h
>  create mode 100644 include/tb-annotation/tb-annotation.h
>  create mode 100644 tb-annotation/Makefile.objs
>  create mode 100644 tb-annotation/tb-annotation-parser.c
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism
  2016-01-28 13:40       ` Bastian Koppelmann
@ 2016-01-28 18:29         ` Lluís Vilanova
  2016-02-01 22:33           ` Lluís Vilanova
  0 siblings, 1 reply; 14+ messages in thread
From: Lluís Vilanova @ 2016-01-28 18:29 UTC (permalink / raw)
  To: Bastian Koppelmann
  Cc: Peter Maydell, Peer Adelt, kbastian, QEMU Developers, Paolo Bonzini

Bastian Koppelmann writes:

> Hi Lluis,
> On 01/27/2016 07:54 PM, Lluís Vilanova wrote:
>> There is this modified version I wrote [1], which precisely provides a plugin
>> infrastructure to attach callbacks into guest code events (a binary
>> instrumentation framework based on QEMU). At the time, the discussion resolved
>> that a full code instrumentation interface for plugins was too much code that
>> regular QEMU users & developers would not care about, easily leading to bitrot.
>> 

> This is too bad but looking at the discussion back then the
> argumentation is reasonable since an instrumentation API would and
> should touch everything in QEMU.

I tried (and I think succeeded) to keep the separation reasonably clean. The
main problem was adding public functions for plugins to peek/poke at guest state
and to inline additional TCG code, which would not be used anywhere else in
QEMU.


>> Instead, the list resolved (AFAIU) that it would be better to mainstream support
>> for guest code events, and make instrumentation an unofficial extension. I've
>> been (slowly) working to separate both pieces, making instrumentation a QEMU
>> patch that can be easily maintained out of tree.
>> 
>> The last patch series I sent sets the final stone on the core infrastructure for
>> the mainline part, just missing the patches I have queued to start adding guest
>> code trace events.

> Can you give me the name of the series.

This is it: https://lists.gnu.org/archive/html/qemu-devel/2016-01/msg02833.html


>> 
>> So, I'd say that such support is on the list of current developments (at least
>> mine, specially now that I have a bit more time for it). But getting the core
>> infrastructure mainlined takes some time to ensure it makes sense and can be
>> easily maintained and be generally usefull to vanilla QEMU.
>> 

> For us such a API would make a lot of sense and there is no benefit for
> us to do our own API. Would it make sense for you if we helped you?

Definitely. The instrumentation code needs some serious update to bring it
up-to-date with the latest QEMU, but adding generally useful guest code tracing
events is something that can be easily pararellized.

For one, my current implementation for instruction/bbl tracing modifies the main
disassembler loop on all targets. This can easily get out of sync as targets
evolve or new ones are added, so my plan was to refactor that into a common
disassembly loop with per-target hooks (since it's C, probably using ugly macros
like in softmmu_template.in).

Also, I never got to add meaningful events for CPU interrupts, for example.

As a side note, I wanted to write a paper about it once the interface stabilized
a bit more, but I haven't had time to implement some interesting/useful use
cases to accompany and motivate it (I've mainly used it to write ad-hoc analysis
tools for my PhD).

Cheers,
  Lluis

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism
  2016-01-28 18:29         ` Lluís Vilanova
@ 2016-02-01 22:33           ` Lluís Vilanova
  0 siblings, 0 replies; 14+ messages in thread
From: Lluís Vilanova @ 2016-02-01 22:33 UTC (permalink / raw)
  To: Bastian Koppelmann
  Cc: Peter Maydell, Paolo Bonzini, kbastian, QEMU Developers, Peer Adelt

Lluís Vilanova writes:

> Bastian Koppelmann writes:
>> Hi Lluis,
>> On 01/27/2016 07:54 PM, Lluís Vilanova wrote:
[...]
>>> 
>>> So, I'd say that such support is on the list of current developments (at least
>>> mine, specially now that I have a bit more time for it). But getting the core
>>> infrastructure mainlined takes some time to ensure it makes sense and can be
>>> easily maintained and be generally usefull to vanilla QEMU.
>>> 

>> For us such a API would make a lot of sense and there is no benefit for
>> us to do our own API. Would it make sense for you if we helped you?

> Definitely. The instrumentation code needs some serious update to bring it
> up-to-date with the latest QEMU, but adding generally useful guest code tracing
> events is something that can be easily pararellized.

FYI, I've rebased my local queue and pushed it to the public repository
[1]. Note that except for the head of the queue, patches are not tested (may not
even compile), but it's a first step at seriously rebooting the project.

I've also started splitting some of the series into separate branches to ease
their development in parallel (devel-*).

[1] https://projects.gso.ac.upc.edu/projects/qemu-dbi
    https://code.gso.ac.upc.edu/git/qemu-dbi

PS: if you had a previous checkout, you might need to get it again (or do some
    tedious checkout+rm+merge+checkout sequence), since I'm developing all these
    series using stgit (which rewrites the story).


Cheers,
  Lluis

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism
  2016-01-28 15:26 ` Frederic Konrad
@ 2016-02-04 14:59   ` Bastian Koppelmann
  0 siblings, 0 replies; 14+ messages in thread
From: Bastian Koppelmann @ 2016-02-04 14:59 UTC (permalink / raw)
  To: Frederic Konrad, Peer Adelt, qemu-devel
  Cc: Mark Burton, kbastian, Guillaume Delbergue

Hi Fred,

On 01/28/2016 04:26 PM, Frederic Konrad wrote:
> Hi,
> 
> Is there a git tree with this series somewhere?
> Looks nice.
> 

here you go: https://github.com/bkoppelmann/tb-annotation.git

> Thanks,
> Fred
> 

Cheers,
Bastian

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Qemu-devel] [RFC PATCH 2/3] tb-annotation: Add control flow graph mapper
  2016-01-08 16:36 [Qemu-devel] [RFC PATCH 1/3] tb-annotation: Added annotation XML file parser Peer Adelt
@ 2016-01-08 16:36 ` Peer Adelt
  0 siblings, 0 replies; 14+ messages in thread
From: Peer Adelt @ 2016-01-08 16:36 UTC (permalink / raw)
  To: qemu-devel; +Cc: kbastian, Peer Adelt

Added helper function at the start of every TranslationBlock
that maps the sequence of static basic blocks (obtained from
the XML file) to the current TranslationBlock. The helper also
accumulates the values that are annotated on the corresponding
edges of the control flow graph.

Signed-off-by: Peer Adelt <peer.adelt@c-lab.de>
---
 include/exec/gen-icount.h | 18 +++++++++
 tcg-runtime.c             | 99 +++++++++++++++++++++++++++++++++++++++++++++++
 tcg/tcg-runtime.h         |  4 ++
 3 files changed, 121 insertions(+)

diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index 05d89d3..0b8821b 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -14,6 +14,11 @@ static inline void gen_tb_start(TranslationBlock *tb)
     TCGv_i32 count, flag, imm;
     int i;
 
+#ifdef CONFIG_TB_ANNOTATION
+    TCGv_ptr annotation_ptr;
+    TCGv_i64 pc;
+#endif
+
     exitreq_label = gen_new_label();
     flag = tcg_temp_new_i32();
     tcg_gen_ld_i32(flag, cpu_env,
@@ -21,6 +26,17 @@ static inline void gen_tb_start(TranslationBlock *tb)
     tcg_gen_brcondi_i32(TCG_COND_NE, flag, 0, exitreq_label);
     tcg_temp_free_i32(flag);
 
+#ifdef CONFIG_TB_ANNOTATION
+    pc = tcg_const_i64(tb->pc);
+    annotation_ptr = tcg_temp_new_ptr();
+    tcg_gen_ld_ptr(annotation_ptr, cpu_env,
+                   -ENV_OFFSET + offsetof(CPUState, tb_annotation));
+
+    gen_helper_annotation(pc, annotation_ptr);
+    tcg_temp_free_i64(pc);
+    tcg_temp_free_ptr(annotation_ptr);
+#endif
+
     if (!(tb->cflags & CF_USE_ICOUNT)) {
         return;
     }
@@ -45,6 +61,8 @@ static inline void gen_tb_start(TranslationBlock *tb)
     tcg_gen_st16_i32(count, cpu_env,
                      -ENV_OFFSET + offsetof(CPUState, icount_decr.u16.low));
     tcg_temp_free_i32(count);
+
+
 }
 
 static void gen_tb_end(TranslationBlock *tb, int num_insns)
diff --git a/tcg-runtime.c b/tcg-runtime.c
index 9daba69..fc2526c 100644
--- a/tcg-runtime.c
+++ b/tcg-runtime.c
@@ -29,6 +29,10 @@
 
 #include "exec/helper-head.h"
 
+#ifdef CONFIG_TB_ANNOTATION
+#include "tb-annotation/tb-annotation.h"
+#endif
+
 #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
   dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2));
 
@@ -107,3 +111,98 @@ int64_t HELPER(mulsh_i64)(int64_t arg1, int64_t arg2)
     muls64(&l, &h, arg1, arg2);
     return h;
 }
+
+#ifdef CONFIG_TB_ANNOTATION
+static inline void take_final_edge(TbAnnotation *env, TbAnnotationEdge *edge)
+{
+    /* Store current context and block */
+    env->last_ctx = edge->target_context;
+    env->last_block = edge->target;
+    /* Accumulate value */
+    env->value_sum += edge->value;
+}
+
+static inline void take_edge(TbAnnotation *env, TbAnnotationEdge *edge)
+{
+    TbAnnotationLeavingEdgeTuple *out;
+
+    /* Store current context and block */
+    env->last_ctx = edge->target_context;
+    env->last_block = edge->target;
+    /* Accumulate value */
+    env->value_sum += edge->value;
+
+    /* Check whether we are at the end of our analysis... */
+    if (env->last_block->out_edges_hash_table != NULL) {
+        out = g_hash_table_lookup(env->last_block->out_edges_hash_table,
+                                  env->last_ctx);
+        if (out != NULL && out->out1->target->is_end_block) {
+            take_final_edge(env, out->out1);
+        }
+    }
+}
+
+void HELPER(annotation)(uint64_t pc, void *opaque)
+{
+    TbAnnotation *env = (TbAnnotation *) opaque;
+    TbAnnotationBlock *b;
+    TbAnnotationLeavingEdgeTuple *out;
+
+    if (!env) {
+        return;
+    }
+
+    /* does the block corresponding to pc exist? */
+    if (!g_hash_table_contains(env->tb_annotation_blocks, &pc)) {
+        return;
+    }
+    /* if last_block == NULL we're in the first block */
+    if (env->last_block == NULL) {
+
+        b = (TbAnnotationBlock *)g_hash_table_lookup(env->tb_annotation_blocks,
+                                                     &pc);
+        env->last_block = b;
+
+    } else {
+        /* while not reached block with current pc (target)
+         * take the next distinct edge if it exists
+         * otherwise we're one edge away from the target and
+         * take the edge directly leading to the target
+         */
+        out = g_hash_table_lookup(env->last_block->out_edges_hash_table,
+                                  env->last_ctx);
+
+        while (out != NULL && out->out2 == NULL) {
+            /* We found a distinct path to "out1" */
+            take_edge(env, out->out1);
+
+            /* Have we reached our target? */
+            if (env->last_block->address == pc) {
+                return;
+            }
+
+            /* Get the current out edge tuple */
+            out = g_hash_table_lookup(env->last_block->out_edges_hash_table,
+                                      env->last_ctx);
+        }
+
+        /* If we get here, we are on a branch block.
+           Take the edge leading to the target. */
+        if (out != NULL && out->out1->target->address == pc) {
+
+            /* Take this edge */
+            take_edge(env, out->out1);
+
+
+        } else if (out != NULL && out->out2->target->address == pc) {
+
+            /* Take the other edge */
+            take_edge(env, out->out2);
+
+        } else {
+
+            /* Something went terribly wrong here... */
+        }
+    }
+        }
+#endif
diff --git a/tcg/tcg-runtime.h b/tcg/tcg-runtime.h
index 23a0c37..004bf8f 100644
--- a/tcg/tcg-runtime.h
+++ b/tcg/tcg-runtime.h
@@ -14,3 +14,7 @@ DEF_HELPER_FLAGS_2(sar_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
 
 DEF_HELPER_FLAGS_2(mulsh_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
 DEF_HELPER_FLAGS_2(muluh_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
+
+#ifdef CONFIG_TB_ANNOTATION
+DEF_HELPER_2(annotation, void, i64, ptr)
+#endif
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2016-02-04 14:59 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-14 10:55 [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism Peer Adelt
2016-01-14 10:55 ` [Qemu-devel] [RFC PATCH 1/3] tb-annotation: Added annotation XML file parser Peer Adelt
2016-01-14 10:55 ` [Qemu-devel] [RFC PATCH 2/3] tb-annotation: Add control flow graph mapper Peer Adelt
2016-01-14 10:55 ` [Qemu-devel] [RFC PATCH 3/3] tb-annotation: Activate annotation extension Peer Adelt
2016-01-14 10:57 ` [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism Peer Adelt
2016-01-25 13:54 ` Peter Maydell
2016-01-26 11:02   ` Bastian Koppelmann
2016-01-27 18:54     ` Lluís Vilanova
2016-01-28 13:40       ` Bastian Koppelmann
2016-01-28 18:29         ` Lluís Vilanova
2016-02-01 22:33           ` Lluís Vilanova
2016-01-28 15:26 ` Frederic Konrad
2016-02-04 14:59   ` Bastian Koppelmann
  -- strict thread matches above, loose matches on Subject: below --
2016-01-08 16:36 [Qemu-devel] [RFC PATCH 1/3] tb-annotation: Added annotation XML file parser Peer Adelt
2016-01-08 16:36 ` [Qemu-devel] [RFC PATCH 2/3] tb-annotation: Add control flow graph mapper Peer Adelt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.