All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough
@ 2011-08-26 19:06 Blue Swirl
  2011-08-29 12:17 ` Stefan Hajnoczi
  2011-08-31  8:38 ` Avi Kivity
  0 siblings, 2 replies; 17+ messages in thread
From: Blue Swirl @ 2011-08-26 19:06 UTC (permalink / raw)
  To: Stefan Hajnoczi, qemu-devel, Dhaval Giani, Lluís

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

Let guests inject tracepoint data via fw_cfg device.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
The patch is used like this:
../configure --with-guest-trace-file=/src/openbios-devel/trace-events
make
sparc64-softmmu/qemu-system-sparc64 -trace file=foo
# ugly hack to combine the file, but my laziness^Wpython-fu is too
weak to add handling of "--guest-trace-file
/src/openbios-devel/trace-events" to simpletrace.py
cat ../trace-events /src/openbios-devel/trace-events >/tmp/trace-events
# examine trace file with OpenBIOS trace data with simpletrace.py
../scripts/simpletrace.py /tmp/trace-events foo
ob_ide_read_blocks 0.000 dest=0xfff0bed0 blk=0x0 n=0x1
ob_ide_read_blocks 6491.806 dest=0xfff0bed0 blk=0x0 n=0x1

An example of a generated guest-trace.c file:
/* This file is autogenerated by tracetool, do not edit. */
#include "trace.h"
#include "guest-trace.h"

void guest_trace(uint64_t event_id, uint64_t arg1, uint64_t arg2,
                 uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6)

{
    switch (event_id) {

    case 0:
        trace_esp_do_command(arg1, arg2, arg3);
        break;

    case 1:
        trace_ob_ide_pio_insw(arg1);
        break;

    case 2:
        trace_ob_ide_read_blocks(arg1, arg2, arg3);
        break;

    default:
        break;
   }
}

---
 Makefile.objs     |   15 +++++++++++-
 configure         |    9 +++++++-
 guest-trace.h     |    3 ++
 hw/fw_cfg.c       |   31 +++++++++++++++++++++++++++
 hw/fw_cfg.h       |   10 ++++++--
 scripts/tracetool |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 6 files changed, 120 insertions(+), 8 deletions(-)
 create mode 100644 guest-trace.h

diff --git a/Makefile.objs b/Makefile.objs
index df11aec..7412e1a 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -340,12 +340,12 @@ else
 trace.h: trace.h-timestamp
 endif
 trace.h-timestamp: $(SRC_PATH)/trace-events config-host.mak
-	$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool
--$(TRACE_BACKEND) -h < $< > $@,"  GEN   trace.h")
+	$(call quiet-command,cat $< $(CONFIG_GUEST_TRACE_FILE) | sh
$(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -h > $@,"  GEN
trace.h")
 	@cmp -s $@ trace.h || cp $@ trace.h

 trace.c: trace.c-timestamp
 trace.c-timestamp: $(SRC_PATH)/trace-events config-host.mak
-	$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool
--$(TRACE_BACKEND) -c < $< > $@,"  GEN   trace.c")
+	$(call quiet-command,cat $< $(CONFIG_GUEST_TRACE_FILE) | sh
$(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -c > $@,"  GEN
trace.c")
 	@cmp -s $@ trace.c || cp $@ trace.c

 trace.o: trace.c $(GENERATED_HEADERS)
@@ -384,6 +384,17 @@ user-obj-y += qemu-timer-common.o
 endif
 endif

+ifneq ($(CONFIG_GUEST_TRACE_FILE),)
+guest-trace.c: guest-trace.c-timestamp
+guest-trace.c-timestamp: $(CONFIG_GUEST_TRACE_FILE) config-host.mak
+	$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool
--$(TRACE_BACKEND) -g < $< > $@,"  GEN   guest-trace.c")
+	@cmp -s $@ guest-trace.c || cp $@ guest-trace.c
+
+guest-trace.o: guest-trace.c $(GENERATED_HEADERS)
+trace-obj-y += guest-trace.o
+fw_cfg.o: fw_cfg.c $(GENERATED_HEADERS)
+endif
+
 ######################################################################
 # smartcard

diff --git a/configure b/configure
index 1340c33..a120774 100755
--- a/configure
+++ b/configure
@@ -175,6 +175,7 @@ user_pie="no"
 zero_malloc=""
 trace_backend="nop"
 trace_file="trace"
+guest_trace_file=""
 spice=""
 rbd=""
 smartcard=""
@@ -537,6 +538,8 @@ for opt do
   ;;
   --with-trace-file=*) trace_file="$optarg"
   ;;
+  --with-guest-trace-file=*) guest_trace_file="$optarg"
+  ;;
   --enable-gprof) gprof="yes"
   ;;
   --static)
@@ -1033,6 +1036,7 @@ echo "  --enable-trace-backend=B Set trace backend"
 echo "                           Available backends:"
$("$source_path"/scripts/tracetool --list-backends)
 echo "  --with-trace-file=NAME   Full PATH,NAME of file to store traces"
 echo "                           Default:trace-<pid>"
+echo "  --with-guest-trace-file=NAME   Full PATH,NAME for guest trace events"
 echo "  --disable-spice          disable spice"
 echo "  --enable-spice           enable spice"
 echo "  --enable-rbd             enable building the rados block device (rbd)"
@@ -2724,6 +2728,7 @@ echo "uuid support      $uuid"
 echo "vhost-net support $vhost_net"
 echo "Trace backend     $trace_backend"
 echo "Trace output file $trace_file-<pid>"
+echo "Guest trace file  $guest_trace_file"
 echo "spice support     $spice"
 echo "rbd support       $rbd"
 echo "xfsctl support    $xfs"
@@ -3076,7 +3081,9 @@ if test "$trace_backend" = "dtrace" -a
"$trace_backend_stap" = "yes" ; then
   echo "CONFIG_SYSTEMTAP_TRACE=y" >> $config_host_mak
 fi
 echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak
-
+if test "x$guest_trace_file" != "x"; then
+    echo "CONFIG_GUEST_TRACE_FILE=$guest_trace_file" >> $config_host_mak
+fi
 echo "TOOLS=$tools" >> $config_host_mak
 echo "ROMS=$roms" >> $config_host_mak
 echo "MAKE=$make" >> $config_host_mak
diff --git a/guest-trace.h b/guest-trace.h
new file mode 100644
index 0000000..db6bb2b
--- /dev/null
+++ b/guest-trace.h
@@ -0,0 +1,3 @@
+#include <stdint.h>
+void guest_trace(uint64_t event_id, uint64_t arg1, uint64_t arg2,
+                 uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6);
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 8df265c..a6b0dbc 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -27,6 +27,9 @@
 #include "fw_cfg.h"
 #include "sysbus.h"
 #include "qemu-error.h"
+#ifdef CONFIG_GUEST_TRACE_FILE
+#include "guest-trace.h"
+#endif

 /* debug firmware config */
 //#define DEBUG_FW_CFG
@@ -55,6 +58,12 @@ struct FWCfgState {
     uint16_t cur_entry;
     uint32_t cur_offset;
     Notifier machine_ready;
+#define GUEST_TRACE_ARGS 7
+#define GUEST_TRACE_BUF_SIZE (sizeof(uint64_t) * GUEST_TRACE_ARGS)
+    union {
+        uint8_t guest_trace_buf[GUEST_TRACE_BUF_SIZE];
+        uint64_t guest_trace_args[GUEST_TRACE_ARGS];
+    } u;
 };

 #define JPG_FILE 0
@@ -477,6 +486,27 @@ static void fw_cfg_machine_ready(struct Notifier
*n, void *data)
     fw_cfg_add_file(s, "bootorder", (uint8_t*)bootindex, len);
 }

+static void fw_cfg_guest_trace(void *opaque, uint8_t *data)
+{
+#ifdef CONFIG_GUEST_TRACE_FILE
+    FWCfgState *s = opaque;
+
+    guest_trace(le64_to_cpu(s->u.guest_trace_args[0]),
+                le64_to_cpu(s->u.guest_trace_args[1]),
+                le64_to_cpu(s->u.guest_trace_args[2]),
+                le64_to_cpu(s->u.guest_trace_args[3]),
+                le64_to_cpu(s->u.guest_trace_args[4]),
+                le64_to_cpu(s->u.guest_trace_args[5]),
+                le64_to_cpu(s->u.guest_trace_args[6]));
+#endif
+}
+
+static void fw_cfg_guest_trace_init(FWCfgState *s, uint16_t key)
+{
+    fw_cfg_add_callback(s, key, fw_cfg_guest_trace, s,
+                        s->u.guest_trace_buf, sizeof(s->u.guest_trace_buf));
+}
+
 FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
                         target_phys_addr_t ctl_addr,
target_phys_addr_t data_addr)
 {
@@ -504,6 +534,7 @@ FWCfgState *fw_cfg_init(uint32_t ctl_port,
uint32_t data_port,
     fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
     fw_cfg_add_i16(s, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
     fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu);
+    fw_cfg_guest_trace_init(s, FW_CFG_GUEST_TRACE);
     fw_cfg_bootsplash(s);

     s->machine_ready.notify = fw_cfg_machine_ready;
diff --git a/hw/fw_cfg.h b/hw/fw_cfg.h
index 856bf91..45b6396 100644
--- a/hw/fw_cfg.h
+++ b/hw/fw_cfg.h
@@ -1,6 +1,9 @@
 #ifndef FW_CFG_H
 #define FW_CFG_H

+#define FW_CFG_WRITE_CHANNEL    0x4000
+#define FW_CFG_ARCH_LOCAL       0x8000
+
 #define FW_CFG_SIGNATURE        0x00
 #define FW_CFG_ID               0x01
 #define FW_CFG_UUID             0x02
@@ -30,10 +33,11 @@

 #define FW_CFG_FILE_FIRST       0x20
 #define FW_CFG_FILE_SLOTS       0x10
-#define FW_CFG_MAX_ENTRY        (FW_CFG_FILE_FIRST+FW_CFG_FILE_SLOTS)

-#define FW_CFG_WRITE_CHANNEL    0x4000
-#define FW_CFG_ARCH_LOCAL       0x8000
+#define FW_CFG_GUEST_TRACE      (FW_CFG_WRITE_CHANNEL |
(FW_CFG_FILE_FIRST+FW_CFG_FILE_SLOTS))
+
+#define FW_CFG_MAX_ENTRY        (FW_CFG_FILE_FIRST+FW_CFG_FILE_SLOTS + 1)
+
 #define FW_CFG_ENTRY_MASK       ~(FW_CFG_WRITE_CHANNEL | FW_CFG_ARCH_LOCAL)

 #define FW_CFG_INVALID          0xffff
diff --git a/scripts/tracetool b/scripts/tracetool
index 2155a57..78e7897 100755
--- a/scripts/tracetool
+++ b/scripts/tracetool
@@ -13,7 +13,7 @@ set -f
 usage()
 {
     cat >&2 <<EOF
-usage: $0 [--nop | --simple | --stderr | --ust | --dtrace] [-h | -c]
+usage: $0 [--nop | --simple | --stderr | --ust | --dtrace] [-h | -c | -d | -g]
 Generate tracing code for a file on stdin.

 Backends:
@@ -27,6 +27,7 @@ Output formats:
   -h     Generate .h file
   -c     Generate .c file
   -d     Generate .d file (DTrace only)
+  -g     Generate guest trace .c file
   --stap Generate .stp file (DTrace with SystemTAP only)

 Options:
@@ -35,6 +36,7 @@ Options:
   --target-type  [type]    QEMU emulator target type ('system' or 'user')
   --probe-prefix [prefix]  Prefix for dtrace probe names
                            (default: qemu-\$targettype-\$targetarch)
+  --guest-trace            Generate guest trace function

 EOF
     exit 1
@@ -502,6 +504,51 @@ linetostap_end_dtrace()
     return
 }

+linetog_begin_all()
+{
+    id=0
+    cat <<EOF
+#include "trace.h"
+#include "guest-trace.h"
+
+void guest_trace(uint64_t event_id, uint64_t arg1, uint64_t arg2,
+                 uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6)
+
+{
+    switch (event_id) {
+EOF
+}
+
+linetog_all()
+{
+    local name args argc arg
+    name=$(get_name "$1")
+    argc=$(get_argc "$1")
+    fieldno=1
+    args=
+    for arg in $(get_argnames "$1", ","); do
+        args="${args}arg$fieldno"
+        [ "$fieldno" = "$argc" ] || args="$args, "
+        fieldno="$((fieldno + 1))"
+    done
+    cat <<EOF
+    case $id:
+        trace_$name($args);
+        break;
+EOF
+    id="$((id + 1))"
+}
+
+linetog_end_all()
+{
+    cat <<EOF
+    default:
+        break;
+   }
+}
+EOF
+}
+
 # Process stdin by calling begin, line, and end functions for the backend
 convert()
 {
@@ -557,6 +604,13 @@ tracetoc()
     convert c
 }

+tracetog()
+{
+    echo "/* This file is autogenerated by tracetool, do not edit. */"
+    backend=all
+    convert g
+}
+
 tracetod()
 {
     if [ $backend != "dtrace" ]; then
@@ -599,6 +653,7 @@ binary=
 targettype=
 targetarch=
 probeprefix=
+guesttrace=


 until [ -z "$1" ]
@@ -610,8 +665,9 @@ do
     "--target-arch") shift ; targetarch="$1" ;;
     "--target-type") shift ; targettype="$1" ;;
     "--probe-prefix") shift ; probeprefix="$1" ;;
+    "--guest-trace") guesttrace="yes" ;;

-    "-h" | "-c" | "-d") output="${1#-}" ;;
+    "-h" | "-c" | "-d" | "-g") output="${1#-}" ;;
     "--stap") output="${1#--}" ;;

     "--check-backend") exit 0 ;; # used by ./configure to test for backend
-- 
1.6.2.4

[-- Attachment #2: 0001-trace-implement-guest-tracepoint-passthrough.patch --]
[-- Type: text/x-diff, Size: 10061 bytes --]

From 4eb9b16786e5002c4c10ac65ff4ad9b590df73a8 Mon Sep 17 00:00:00 2001
Message-Id: <4eb9b16786e5002c4c10ac65ff4ad9b590df73a8.1314384478.git.blauwirbel@gmail.com>
From: Blue Swirl <blauwirbel@gmail.com>
Date: Tue, 23 Aug 2011 17:31:53 +0000
Subject: [PATCH] trace: implement guest tracepoint passthrough

Let guests inject tracepoint data via fw_cfg device.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 Makefile.objs     |   15 +++++++++++-
 configure         |    9 +++++++-
 guest-trace.h     |    3 ++
 hw/fw_cfg.c       |   31 +++++++++++++++++++++++++++
 hw/fw_cfg.h       |   10 ++++++--
 scripts/tracetool |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 6 files changed, 120 insertions(+), 8 deletions(-)
 create mode 100644 guest-trace.h

diff --git a/Makefile.objs b/Makefile.objs
index df11aec..7412e1a 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -340,12 +340,12 @@ else
 trace.h: trace.h-timestamp
 endif
 trace.h-timestamp: $(SRC_PATH)/trace-events config-host.mak
-	$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -h < $< > $@,"  GEN   trace.h")
+	$(call quiet-command,cat $< $(CONFIG_GUEST_TRACE_FILE) | sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -h > $@,"  GEN   trace.h")
 	@cmp -s $@ trace.h || cp $@ trace.h
 
 trace.c: trace.c-timestamp
 trace.c-timestamp: $(SRC_PATH)/trace-events config-host.mak
-	$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -c < $< > $@,"  GEN   trace.c")
+	$(call quiet-command,cat $< $(CONFIG_GUEST_TRACE_FILE) | sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -c > $@,"  GEN   trace.c")
 	@cmp -s $@ trace.c || cp $@ trace.c
 
 trace.o: trace.c $(GENERATED_HEADERS)
@@ -384,6 +384,17 @@ user-obj-y += qemu-timer-common.o
 endif
 endif
 
+ifneq ($(CONFIG_GUEST_TRACE_FILE),)
+guest-trace.c: guest-trace.c-timestamp
+guest-trace.c-timestamp: $(CONFIG_GUEST_TRACE_FILE) config-host.mak
+	$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -g < $< > $@,"  GEN   guest-trace.c")
+	@cmp -s $@ guest-trace.c || cp $@ guest-trace.c
+
+guest-trace.o: guest-trace.c $(GENERATED_HEADERS)
+trace-obj-y += guest-trace.o
+fw_cfg.o: fw_cfg.c $(GENERATED_HEADERS)
+endif
+
 ######################################################################
 # smartcard
 
diff --git a/configure b/configure
index 1340c33..a120774 100755
--- a/configure
+++ b/configure
@@ -175,6 +175,7 @@ user_pie="no"
 zero_malloc=""
 trace_backend="nop"
 trace_file="trace"
+guest_trace_file=""
 spice=""
 rbd=""
 smartcard=""
@@ -537,6 +538,8 @@ for opt do
   ;;
   --with-trace-file=*) trace_file="$optarg"
   ;;
+  --with-guest-trace-file=*) guest_trace_file="$optarg"
+  ;;
   --enable-gprof) gprof="yes"
   ;;
   --static)
@@ -1033,6 +1036,7 @@ echo "  --enable-trace-backend=B Set trace backend"
 echo "                           Available backends:" $("$source_path"/scripts/tracetool --list-backends)
 echo "  --with-trace-file=NAME   Full PATH,NAME of file to store traces"
 echo "                           Default:trace-<pid>"
+echo "  --with-guest-trace-file=NAME   Full PATH,NAME for guest trace events"
 echo "  --disable-spice          disable spice"
 echo "  --enable-spice           enable spice"
 echo "  --enable-rbd             enable building the rados block device (rbd)"
@@ -2724,6 +2728,7 @@ echo "uuid support      $uuid"
 echo "vhost-net support $vhost_net"
 echo "Trace backend     $trace_backend"
 echo "Trace output file $trace_file-<pid>"
+echo "Guest trace file  $guest_trace_file"
 echo "spice support     $spice"
 echo "rbd support       $rbd"
 echo "xfsctl support    $xfs"
@@ -3076,7 +3081,9 @@ if test "$trace_backend" = "dtrace" -a "$trace_backend_stap" = "yes" ; then
   echo "CONFIG_SYSTEMTAP_TRACE=y" >> $config_host_mak
 fi
 echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak
-
+if test "x$guest_trace_file" != "x"; then
+    echo "CONFIG_GUEST_TRACE_FILE=$guest_trace_file" >> $config_host_mak
+fi
 echo "TOOLS=$tools" >> $config_host_mak
 echo "ROMS=$roms" >> $config_host_mak
 echo "MAKE=$make" >> $config_host_mak
diff --git a/guest-trace.h b/guest-trace.h
new file mode 100644
index 0000000..db6bb2b
--- /dev/null
+++ b/guest-trace.h
@@ -0,0 +1,3 @@
+#include <stdint.h>
+void guest_trace(uint64_t event_id, uint64_t arg1, uint64_t arg2,
+                 uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6);
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 8df265c..a6b0dbc 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -27,6 +27,9 @@
 #include "fw_cfg.h"
 #include "sysbus.h"
 #include "qemu-error.h"
+#ifdef CONFIG_GUEST_TRACE_FILE
+#include "guest-trace.h"
+#endif
 
 /* debug firmware config */
 //#define DEBUG_FW_CFG
@@ -55,6 +58,12 @@ struct FWCfgState {
     uint16_t cur_entry;
     uint32_t cur_offset;
     Notifier machine_ready;
+#define GUEST_TRACE_ARGS 7
+#define GUEST_TRACE_BUF_SIZE (sizeof(uint64_t) * GUEST_TRACE_ARGS)
+    union {
+        uint8_t guest_trace_buf[GUEST_TRACE_BUF_SIZE];
+        uint64_t guest_trace_args[GUEST_TRACE_ARGS];
+    } u;
 };
 
 #define JPG_FILE 0
@@ -477,6 +486,27 @@ static void fw_cfg_machine_ready(struct Notifier *n, void *data)
     fw_cfg_add_file(s, "bootorder", (uint8_t*)bootindex, len);
 }
 
+static void fw_cfg_guest_trace(void *opaque, uint8_t *data)
+{
+#ifdef CONFIG_GUEST_TRACE_FILE
+    FWCfgState *s = opaque;
+
+    guest_trace(le64_to_cpu(s->u.guest_trace_args[0]),
+                le64_to_cpu(s->u.guest_trace_args[1]),
+                le64_to_cpu(s->u.guest_trace_args[2]),
+                le64_to_cpu(s->u.guest_trace_args[3]),
+                le64_to_cpu(s->u.guest_trace_args[4]),
+                le64_to_cpu(s->u.guest_trace_args[5]),
+                le64_to_cpu(s->u.guest_trace_args[6]));
+#endif
+}
+
+static void fw_cfg_guest_trace_init(FWCfgState *s, uint16_t key)
+{
+    fw_cfg_add_callback(s, key, fw_cfg_guest_trace, s,
+                        s->u.guest_trace_buf, sizeof(s->u.guest_trace_buf));
+}
+
 FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
                         target_phys_addr_t ctl_addr, target_phys_addr_t data_addr)
 {
@@ -504,6 +534,7 @@ FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
     fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
     fw_cfg_add_i16(s, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
     fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu);
+    fw_cfg_guest_trace_init(s, FW_CFG_GUEST_TRACE);
     fw_cfg_bootsplash(s);
 
     s->machine_ready.notify = fw_cfg_machine_ready;
diff --git a/hw/fw_cfg.h b/hw/fw_cfg.h
index 856bf91..45b6396 100644
--- a/hw/fw_cfg.h
+++ b/hw/fw_cfg.h
@@ -1,6 +1,9 @@
 #ifndef FW_CFG_H
 #define FW_CFG_H
 
+#define FW_CFG_WRITE_CHANNEL    0x4000
+#define FW_CFG_ARCH_LOCAL       0x8000
+
 #define FW_CFG_SIGNATURE        0x00
 #define FW_CFG_ID               0x01
 #define FW_CFG_UUID             0x02
@@ -30,10 +33,11 @@
 
 #define FW_CFG_FILE_FIRST       0x20
 #define FW_CFG_FILE_SLOTS       0x10
-#define FW_CFG_MAX_ENTRY        (FW_CFG_FILE_FIRST+FW_CFG_FILE_SLOTS)
 
-#define FW_CFG_WRITE_CHANNEL    0x4000
-#define FW_CFG_ARCH_LOCAL       0x8000
+#define FW_CFG_GUEST_TRACE      (FW_CFG_WRITE_CHANNEL | (FW_CFG_FILE_FIRST+FW_CFG_FILE_SLOTS))
+
+#define FW_CFG_MAX_ENTRY        (FW_CFG_FILE_FIRST+FW_CFG_FILE_SLOTS + 1)
+
 #define FW_CFG_ENTRY_MASK       ~(FW_CFG_WRITE_CHANNEL | FW_CFG_ARCH_LOCAL)
 
 #define FW_CFG_INVALID          0xffff
diff --git a/scripts/tracetool b/scripts/tracetool
index 2155a57..78e7897 100755
--- a/scripts/tracetool
+++ b/scripts/tracetool
@@ -13,7 +13,7 @@ set -f
 usage()
 {
     cat >&2 <<EOF
-usage: $0 [--nop | --simple | --stderr | --ust | --dtrace] [-h | -c]
+usage: $0 [--nop | --simple | --stderr | --ust | --dtrace] [-h | -c | -d | -g]
 Generate tracing code for a file on stdin.
 
 Backends:
@@ -27,6 +27,7 @@ Output formats:
   -h     Generate .h file
   -c     Generate .c file
   -d     Generate .d file (DTrace only)
+  -g     Generate guest trace .c file
   --stap Generate .stp file (DTrace with SystemTAP only)
 
 Options:
@@ -35,6 +36,7 @@ Options:
   --target-type  [type]    QEMU emulator target type ('system' or 'user')
   --probe-prefix [prefix]  Prefix for dtrace probe names
                            (default: qemu-\$targettype-\$targetarch)
+  --guest-trace            Generate guest trace function
 
 EOF
     exit 1
@@ -502,6 +504,51 @@ linetostap_end_dtrace()
     return
 }
 
+linetog_begin_all()
+{
+    id=0
+    cat <<EOF
+#include "trace.h"
+#include "guest-trace.h"
+
+void guest_trace(uint64_t event_id, uint64_t arg1, uint64_t arg2,
+                 uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6)
+
+{
+    switch (event_id) {
+EOF
+}
+
+linetog_all()
+{
+    local name args argc arg
+    name=$(get_name "$1")
+    argc=$(get_argc "$1")
+    fieldno=1
+    args=
+    for arg in $(get_argnames "$1", ","); do
+        args="${args}arg$fieldno"
+        [ "$fieldno" = "$argc" ] || args="$args, "
+        fieldno="$((fieldno + 1))"
+    done
+    cat <<EOF
+    case $id:
+        trace_$name($args);
+        break;
+EOF
+    id="$((id + 1))"
+}
+
+linetog_end_all()
+{
+    cat <<EOF
+    default:
+        break;
+   }
+}
+EOF
+}
+
 # Process stdin by calling begin, line, and end functions for the backend
 convert()
 {
@@ -557,6 +604,13 @@ tracetoc()
     convert c
 }
 
+tracetog()
+{
+    echo "/* This file is autogenerated by tracetool, do not edit. */"
+    backend=all
+    convert g
+}
+
 tracetod()
 {
     if [ $backend != "dtrace" ]; then
@@ -599,6 +653,7 @@ binary=
 targettype=
 targetarch=
 probeprefix=
+guesttrace=
 
 
 until [ -z "$1" ]
@@ -610,8 +665,9 @@ do
     "--target-arch") shift ; targetarch="$1" ;;
     "--target-type") shift ; targettype="$1" ;;
     "--probe-prefix") shift ; probeprefix="$1" ;;
+    "--guest-trace") guesttrace="yes" ;;
 
-    "-h" | "-c" | "-d") output="${1#-}" ;;
+    "-h" | "-c" | "-d" | "-g") output="${1#-}" ;;
     "--stap") output="${1#--}" ;;
 
     "--check-backend") exit 0 ;; # used by ./configure to test for backend
-- 
1.7.2.5


[-- Attachment #3: 0001-Introduce-tracing-system-from-QEMU.patch --]
[-- Type: text/x-diff, Size: 27713 bytes --]

From 96c9925be98578480be79d2385ab4dc005f8218d Mon Sep 17 00:00:00 2001
Message-Id: <96c9925be98578480be79d2385ab4dc005f8218d.1314384470.git.blauwirbel@gmail.com>
From: Blue Swirl <blauwirbel@gmail.com>
Date: Tue, 23 Aug 2011 21:08:53 +0000
Subject: [PATCH] Introduce tracing system from QEMU

Instead of traditional debugging printf statements, which
have the bad habit of suffering from bit rot, introduce
tracepoints based on similar system in QEMU.

Only stderr (printk) and simpletrace (output via fw_cfg
device to QEMU) back ends are supported.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 config/examples/amd64_config.xml   |    3 +-
 config/examples/ppc64_config.xml   |    3 +-
 config/examples/ppc_config.xml     |    3 +-
 config/examples/sparc32_config.xml |    3 +-
 config/examples/sparc64_config.xml |    3 +-
 config/scripts/tracetool           |  692 ++++++++++++++++++++++++++++++++++++
 drivers/esp.c                      |    3 +-
 drivers/fw_cfg.c                   |   22 ++
 drivers/ide.c                      |    6 +-
 include/arch/common/fw_cfg.h       |    9 +-
 include/libopenbios/simpletrace.h  |   31 ++
 libopenbios/build.xml              |   33 ++
 libopenbios/simpletrace.c          |   76 ++++
 trace-events                       |    3 +
 14 files changed, 879 insertions(+), 11 deletions(-)
 create mode 100644 config/scripts/tracetool
 create mode 100644 include/libopenbios/simpletrace.h
 create mode 100644 libopenbios/simpletrace.c
 create mode 100644 trace-events

diff --git a/config/examples/amd64_config.xml b/config/examples/amd64_config.xml
index 33d4267..ba3838b 100644
--- a/config/examples/amd64_config.xml
+++ b/config/examples/amd64_config.xml
@@ -14,7 +14,8 @@
   <option name="CONFIG_SERIAL_PORT" type="boolean" value="true"/>
   <option name="CONFIG_SERIAL_SPEED" type="integer" value="115200"/>
   <option name="CONFIG_DEBUG_CONSOLE_VGA" type="boolean" value="true"/>
-
+  <option name="CONFIG_TRACE_SIMPLETRACE" type="boolean" value="false"/>
+  <option name="CONFIG_TRACE_STDERR" type="boolean" value="true"/>
 
   <!-- Module Configuration -->
   <option name="CONFIG_CMDLINE" type="boolean" value="true"/>
diff --git a/config/examples/ppc64_config.xml b/config/examples/ppc64_config.xml
index 5f79c21..bca5cc5 100644
--- a/config/examples/ppc64_config.xml
+++ b/config/examples/ppc64_config.xml
@@ -12,7 +12,8 @@
   <option name="CONFIG_SERIAL_SPEED" type="integer" value="115200"/>
   <option name="CONFIG_DEBUG_CONSOLE_VGA" type="boolean" value="true"/>
   <option name="CONFIG_DEBUG_OFMEM" type="boolean" value="false"/>
-
+  <option name="CONFIG_TRACE_SIMPLETRACE" type="boolean" value="false"/>
+  <option name="CONFIG_TRACE_STDERR" type="boolean" value="true"/>
 
   <!-- Module Configuration -->
   <option name="CONFIG_CMDLINE" type="boolean" value="true"/>
diff --git a/config/examples/ppc_config.xml b/config/examples/ppc_config.xml
index 352cb57..a338d56 100644
--- a/config/examples/ppc_config.xml
+++ b/config/examples/ppc_config.xml
@@ -12,7 +12,8 @@
   <option name="CONFIG_SERIAL_SPEED" type="integer" value="115200"/>
   <option name="CONFIG_DEBUG_CONSOLE_VGA" type="boolean" value="true"/>
   <option name="CONFIG_DEBUG_OFMEM" type="boolean" value="false"/>
-
+  <option name="CONFIG_TRACE_SIMPLETRACE" type="boolean" value="false"/>
+  <option name="CONFIG_TRACE_STDERR" type="boolean" value="true"/>
 
   <!-- Module Configuration -->
   <option name="CONFIG_CMDLINE" type="boolean" value="true"/>
diff --git a/config/examples/sparc32_config.xml b/config/examples/sparc32_config.xml
index f2d6afc..2b449cc 100644
--- a/config/examples/sparc32_config.xml
+++ b/config/examples/sparc32_config.xml
@@ -19,7 +19,8 @@
   <option name="CONFIG_SERIAL_PORT" type="integer" value="0"/>
   <option name="CONFIG_SERIAL_SPEED" type="integer" value="9600"/>
   <option name="CONFIG_DEBUG_OFMEM" type="boolean" value="false"/>
-
+  <option name="CONFIG_TRACE_SIMPLETRACE" type="boolean" value="true"/>
+  <option name="CONFIG_TRACE_STDERR" type="boolean" value="false"/>
 
   <!-- Module Configuration -->
   <option name="CONFIG_CMDLINE" type="boolean" value="true"/>
diff --git a/config/examples/sparc64_config.xml b/config/examples/sparc64_config.xml
index a4e1336..40fb7a6 100644
--- a/config/examples/sparc64_config.xml
+++ b/config/examples/sparc64_config.xml
@@ -16,7 +16,8 @@
   <option name="CONFIG_SERIAL_SPEED" type="integer" value="115200"/>
   <option name="CONFIG_DEBUG_CONSOLE_VGA" type="boolean" value="true"/>
   <option name="CONFIG_DEBUG_OFMEM" type="boolean" value="false"/>
-
+  <option name="CONFIG_TRACE_SIMPLETRACE" type="boolean" value="true"/>
+  <option name="CONFIG_TRACE_STDERR" type="boolean" value="false"/>
 
   <!-- Module Configuration -->
   <option name="CONFIG_CMDLINE" type="boolean" value="true"/>
diff --git a/config/scripts/tracetool b/config/scripts/tracetool
new file mode 100644
index 0000000..5c0534f
--- /dev/null
+++ b/config/scripts/tracetool
@@ -0,0 +1,692 @@
+#!/bin/sh
+#
+# Code generator for trace events
+#
+# Copyright IBM, Corp. 2010
+#
+# This work is licensed under the terms of the GNU GPL, version 2.  See
+# the COPYING file in the top-level directory.
+
+# Disable pathname expansion, makes processing text with '*' characters simpler
+set -f
+
+usage()
+{
+    cat >&2 <<EOF
+usage: $0 [--nop | --simple | --stderr | --ust | --dtrace] [-h | -c | -d | -g]
+Generate tracing code for a file on stdin.
+
+Backends:
+  --nop     Tracing disabled
+  --simple  Simple built-in backend
+  --stderr  Stderr built-in backend
+  --ust     LTTng User Space Tracing backend
+  --dtrace  DTrace/SystemTAP backend
+
+Output formats:
+  -h     Generate .h file
+  -c     Generate .c file
+  -d     Generate .d file (DTrace only)
+  -g     Generate guest trace .c file
+  --stap Generate .stp file (DTrace with SystemTAP only)
+
+Options:
+  --binary       [path]    Full path to QEMU binary
+  --target-arch  [arch]    QEMU emulator target arch
+  --target-type  [type]    QEMU emulator target type ('system' or 'user')
+  --probe-prefix [prefix]  Prefix for dtrace probe names
+                           (default: qemu-\$targettype-\$targetarch)
+  --guest-trace            Generate guest trace function
+
+EOF
+    exit 1
+}
+
+# Get the name of a trace event
+get_name()
+{
+    echo ${1%%\(*}
+}
+
+# Get the argument list of a trace event, including types and names
+get_args()
+{
+    local args
+    args=${1#*\(}
+    args=${args%%\)*}
+    echo "$args"
+}
+
+# Get the argument name list of a trace event
+get_argnames()
+{
+    local nfields field name sep
+    nfields=0
+    sep="$2"
+    for field in $(get_args "$1"); do
+        nfields=$((nfields + 1))
+
+        # Drop pointer star
+        field=${field#\*}
+
+        # Only argument names have commas at the end
+        name=${field%,}
+        test "$field" = "$name" && continue
+
+        printf "%s%s " $name $sep
+    done
+
+    # Last argument name
+    if [ "$nfields" -gt 1 ]
+    then
+        printf "%s" "$name"
+    fi
+}
+
+# Get the number of arguments to a trace event
+get_argc()
+{
+    local name argc
+    argc=0
+    for name in $(get_argnames "$1", ","); do
+        argc=$((argc + 1))
+    done
+    echo $argc
+}
+
+# Get the format string for a trace event
+get_fmt()
+{
+    local fmt
+    fmt=${1#*\"}
+    fmt=${fmt%\"*}
+    echo "$fmt"
+}
+
+# Get the state of a trace event
+get_state()
+{
+    local str disable state
+    str=$(get_name "$1")
+    disable=${str##disable }
+    if [ "$disable" = "$str" ] ; then
+        state=1
+    else
+        state=0
+    fi
+    echo "$state"
+}
+
+linetoh_begin_nop()
+{
+    return
+}
+
+linetoh_nop()
+{
+    local name args
+    name=$(get_name "$1")
+    args=$(get_args "$1")
+
+    # Define an empty function for the trace event
+    cat <<EOF
+static inline void trace_$name($args)
+{
+}
+EOF
+}
+
+linetoh_end_nop()
+{
+    return
+}
+
+linetoc_begin_nop()
+{
+    return
+}
+
+linetoc_nop()
+{
+    # No need for function definitions in nop backend
+    return
+}
+
+linetoc_end_nop()
+{
+    return
+}
+
+linetoh_begin_simple()
+{
+    cat <<EOF
+#include "libopenbios/simpletrace.h"
+EOF
+
+    simple_event_num=0
+}
+
+cast_args_to_uint64_t()
+{
+    local arg
+    for arg in $(get_argnames "$1", ","); do
+        printf "%s" "(uint64_t)(uintptr_t)$arg"
+    done
+}
+
+linetoh_simple()
+{
+    local name args argc trace_args state
+    name=$(get_name "$1")
+    args=$(get_args "$1")
+    argc=$(get_argc "$1")
+    state=$(get_state "$1")
+    if [ "$state" = "0" ]; then
+        name=${name##disable }
+    fi
+
+    trace_args="$simple_event_num"
+    if [ "$argc" -gt 0 ]
+    then
+        trace_args="$trace_args, $(cast_args_to_uint64_t "$1")"
+    fi
+
+    cat <<EOF
+static inline void trace_$name($args)
+{
+    trace$argc($trace_args);
+}
+EOF
+
+    simple_event_num=$((simple_event_num + 1))
+}
+
+linetoh_end_simple()
+{
+    cat <<EOF
+#define NR_TRACE_EVENTS $simple_event_num
+extern TraceEvent trace_list[NR_TRACE_EVENTS];
+EOF
+}
+
+linetoc_begin_simple()
+{
+    cat <<EOF
+#include "trace.h"
+
+TraceEvent trace_list[] = {
+EOF
+    simple_event_num=0
+
+}
+
+linetoc_simple()
+{
+    local name state
+    name=$(get_name "$1")
+    state=$(get_state "$1")
+    if [ "$state" = "0" ] ; then
+        name=${name##disable }
+    fi
+    cat <<EOF
+{.tp_name = "$name", .state=$state},
+EOF
+    simple_event_num=$((simple_event_num + 1))
+}
+
+linetoc_end_simple()
+{
+    cat <<EOF
+};
+EOF
+}
+
+#STDERR
+linetoh_begin_stderr()
+{
+    cat <<EOF
+#include "libc/vsprintf.h"
+EOF
+}
+
+linetoh_stderr()
+{
+    local name args argnames argc fmt
+    name=$(get_name "$1")
+    args=$(get_args "$1")
+    argnames=$(get_argnames "$1" ",")
+    argc=$(get_argc "$1")
+    fmt=$(get_fmt "$1")
+
+    if [ "$argc" -gt 0 ]; then
+        argnames=", $argnames"
+    fi
+
+    cat <<EOF
+static inline void trace_$name($args)
+{
+    printk("$name $fmt\n" $argnames);
+}
+EOF
+}
+
+linetoh_end_stderr()
+{
+return
+}
+
+linetoc_begin_stderr()
+{
+return
+}
+
+linetoc_stderr()
+{
+return
+}
+
+linetoc_end_stderr()
+{
+return
+}
+#END OF STDERR
+
+# Clean up after UST headers which pollute the namespace
+ust_clean_namespace() {
+    cat <<EOF
+#undef mutex_lock
+#undef mutex_unlock
+#undef inline
+#undef wmb
+EOF
+}
+
+linetoh_begin_ust()
+{
+    echo "#include <ust/tracepoint.h>"
+    ust_clean_namespace
+}
+
+linetoh_ust()
+{
+    local name args argnames
+    name=$(get_name "$1")
+    args=$(get_args "$1")
+    argnames=$(get_argnames "$1", ",")
+
+    cat <<EOF
+DECLARE_TRACE(ust_$name, TP_PROTO($args), TP_ARGS($argnames));
+#define trace_$name trace_ust_$name
+EOF
+}
+
+linetoh_end_ust()
+{
+    return
+}
+
+linetoc_begin_ust()
+{
+    cat <<EOF
+#include <ust/marker.h>
+$(ust_clean_namespace)
+#include "trace.h"
+EOF
+}
+
+linetoc_ust()
+{
+    local name args argnames fmt
+    name=$(get_name "$1")
+    args=$(get_args "$1")
+    argnames=$(get_argnames "$1", ",")
+    [ -z "$argnames" ] || argnames=", $argnames"
+    fmt=$(get_fmt "$1")
+
+    cat <<EOF
+DEFINE_TRACE(ust_$name);
+
+static void ust_${name}_probe($args)
+{
+    trace_mark(ust, $name, "$fmt"$argnames);
+}
+EOF
+
+    # Collect names for later
+    names="$names $name"
+}
+
+linetoc_end_ust()
+{
+    cat <<EOF
+static void __attribute__((constructor)) trace_init(void)
+{
+EOF
+
+    for name in $names; do
+        cat <<EOF
+    register_trace_ust_$name(ust_${name}_probe);
+EOF
+    done
+
+    echo "}"
+}
+
+linetoh_begin_dtrace()
+{
+    cat <<EOF
+#include "trace-dtrace.h"
+EOF
+}
+
+linetoh_dtrace()
+{
+    local name args argnames state nameupper
+    name=$(get_name "$1")
+    args=$(get_args "$1")
+    argnames=$(get_argnames "$1", ",")
+    state=$(get_state "$1")
+    if [ "$state" = "0" ] ; then
+        name=${name##disable }
+    fi
+
+    nameupper=`echo $name | tr '[:lower:]' '[:upper:]'`
+
+    # Define an empty function for the trace event
+    cat <<EOF
+static inline void trace_$name($args) {
+    if (QEMU_${nameupper}_ENABLED()) {
+        QEMU_${nameupper}($argnames);
+    }
+}
+EOF
+}
+
+linetoh_end_dtrace()
+{
+    return
+}
+
+linetoc_begin_dtrace()
+{
+    return
+}
+
+linetoc_dtrace()
+{
+    # No need for function definitions in dtrace backend
+    return
+}
+
+linetoc_end_dtrace()
+{
+    return
+}
+
+linetod_begin_dtrace()
+{
+    cat <<EOF
+provider qemu {
+EOF
+}
+
+linetod_dtrace()
+{
+    local name args state
+    name=$(get_name "$1")
+    args=$(get_args "$1")
+    state=$(get_state "$1")
+    if [ "$state" = "0" ] ; then
+        name=${name##disable }
+    fi
+
+    # DTrace provider syntax expects foo() for empty
+    # params, not foo(void)
+    if [ "$args" = "void" ]; then
+       args=""
+    fi
+
+    # Define prototype for probe arguments
+    cat <<EOF
+        probe $name($args);
+EOF
+}
+
+linetod_end_dtrace()
+{
+    cat <<EOF
+};
+EOF
+}
+
+linetostap_begin_dtrace()
+{
+    return
+}
+
+linetostap_dtrace()
+{
+    local i arg name args arglist state
+    name=$(get_name "$1")
+    args=$(get_args "$1")
+    arglist=$(get_argnames "$1", "")
+    state=$(get_state "$1")
+    if [ "$state" = "0" ] ; then
+        name=${name##disable }
+    fi
+
+    # Define prototype for probe arguments
+    cat <<EOF
+probe $probeprefix.$name = process("$binary").mark("$name")
+{
+EOF
+
+    i=1
+    for arg in $arglist
+    do
+        # 'limit' is a reserved keyword
+        if [ "$arg" = "limit" ]; then
+          arg="_limit"
+        fi
+        cat <<EOF
+  $arg = \$arg$i;
+EOF
+        i="$((i+1))"
+    done
+
+    cat <<EOF
+}
+EOF
+}
+
+linetostap_end_dtrace()
+{
+    return
+}
+
+linetog_begin_all()
+{
+    id=0
+    cat <<EOF
+#include "trace.h"
+#include "guest-trace.h"
+
+void guest_trace(uint64_t event_id, uint64_t arg1, uint64_t arg2,
+                 uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6)
+
+{
+    switch (event_id) {
+EOF
+}
+
+linetog_all()
+{
+    local name args argc arg
+    name=$(get_name "$1")
+    argc=$(get_argc "$1")
+    fieldno=1
+    args=
+    for arg in $(get_argnames "$1", ","); do
+        args="${args}arg$fieldno"
+        [ "$fieldno" = "$argc" ] || args="$args, "
+        fieldno="$((fieldno + 1))"
+    done
+    cat <<EOF
+    case $id:
+        trace_$name($args);
+        break;
+EOF
+    id="$((id + 1))"
+}
+
+linetog_end_all()
+{
+    cat <<EOF
+    default:
+        break;
+   }
+}
+EOF
+}
+
+# Process stdin by calling begin, line, and end functions for the backend
+convert()
+{
+    local begin process_line end str disable
+    begin="lineto$1_begin_$backend"
+    process_line="lineto$1_$backend"
+    end="lineto$1_end_$backend"
+
+    "$begin"
+
+    while read -r str; do
+        # Skip comments and empty lines
+        test -z "${str%%#*}" && continue
+
+        # Process the line.  The nop backend handles disabled lines.
+        disable=${str%%disable *}
+        echo
+        if test -z "$disable"; then
+            # Pass the disabled state as an arg for the simple
+            # or DTrace backends which handle it dynamically.
+            # For all other backends, call lineto$1_nop()
+            if [ $backend = "simple" -o "$backend" = "dtrace" ]; then
+                "$process_line" "$str"
+            else
+                "lineto$1_nop" "${str##disable }"
+            fi
+        else
+            "$process_line" "$str"
+        fi
+    done
+
+    echo
+    "$end"
+}
+
+tracetoh()
+{
+    cat <<EOF
+#ifndef TRACE_H
+#define TRACE_H
+
+/* This file is autogenerated by tracetool, do not edit. */
+
+EOF
+    convert h
+    echo "#endif /* TRACE_H */"
+}
+
+tracetoc()
+{
+    echo "/* This file is autogenerated by tracetool, do not edit. */"
+    convert c
+}
+
+tracetog()
+{
+    echo "/* This file is autogenerated by tracetool, do not edit. */"
+    backend=all
+    convert g
+}
+
+tracetod()
+{
+    if [ $backend != "dtrace" ]; then
+       echo "DTrace probe generator not applicable to $backend backend"
+       exit 1
+    fi
+    echo "/* This file is autogenerated by tracetool, do not edit. */"
+    convert d
+}
+
+tracetostap()
+{
+    if [ $backend != "dtrace" ]; then
+       echo "SystemTAP tapset generator not applicable to $backend backend"
+       exit 1
+    fi
+    if [ -z "$binary" ]; then
+       echo "--binary is required for SystemTAP tapset generator"
+       exit 1
+    fi
+    if [ -z "$probeprefix" -a -z "$targettype" ]; then
+       echo "--target-type is required for SystemTAP tapset generator"
+       exit 1
+    fi
+    if [ -z "$probeprefix" -a -z "$targetarch" ]; then
+       echo "--target-arch is required for SystemTAP tapset generator"
+       exit 1
+    fi
+    if [ -z "$probeprefix" ]; then
+        probeprefix="qemu.$targettype.$targetarch";
+    fi
+    echo "/* This file is autogenerated by tracetool, do not edit. */"
+    convert stap
+}
+
+
+backend=
+output=
+binary=
+targettype=
+targetarch=
+probeprefix=
+guesttrace=
+
+
+until [ -z "$1" ]
+do
+  case "$1" in
+    "--nop" | "--simple" | "--stderr" | "--ust" | "--dtrace") backend="${1#--}" ;;
+
+    "--binary") shift ; binary="$1" ;;
+    "--target-arch") shift ; targetarch="$1" ;;
+    "--target-type") shift ; targettype="$1" ;;
+    "--probe-prefix") shift ; probeprefix="$1" ;;
+    "--guest-trace") guesttrace="yes" ;;
+
+    "-h" | "-c" | "-d" | "-g") output="${1#-}" ;;
+    "--stap") output="${1#--}" ;;
+
+    "--check-backend") exit 0 ;; # used by ./configure to test for backend
+
+    "--list-backends") # used by ./configure to list available backends
+          echo "nop simple stderr ust dtrace"
+          exit 0
+          ;;
+
+    *)
+      usage;;
+  esac
+  shift
+done
+
+if [ "$backend" = "" -o "$output" = "" ]; then
+  usage
+fi
+
+gen="traceto$output"
+"$gen"
+
+exit 0
diff --git a/drivers/esp.c b/drivers/esp.c
index 41e0394..0ab1893 100644
--- a/drivers/esp.c
+++ b/drivers/esp.c
@@ -25,6 +25,7 @@
 #include "asm/dma.h"
 #include "esp.h"
 #include "libopenbios/ofmem.h"
+#include "trace.h"
 
 #define BUFSIZE         4096
 
@@ -106,7 +107,7 @@ do_command(esp_private_t *esp, sd_private_t *sd, int cmdlen, int replylen)
     // Clear interrupts to avoid guests seeing spurious interrupts
     (void)esp->ll->regs[ESP_INTRPT];
 
-    DPRINTF("do_command: id %d, cmd[0] 0x%x, status 0x%x\n", sd->id, esp->buffer[0], status);
+    trace_esp_do_command(sd->id, esp->buffer[0], status);
 
     /* Target didn't want all command data? */
     if ((status & ESP_STAT_TCNT) != ESP_STAT_TCNT) {
diff --git a/drivers/fw_cfg.c b/drivers/fw_cfg.c
index 4027570..caaab3b 100644
--- a/drivers/fw_cfg.c
+++ b/drivers/fw_cfg.c
@@ -18,6 +18,17 @@ fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes)
     for (i = 0; i < nbytes; i++)
         buf[i] = *fw_cfg_data;
 }
+
+void
+fw_cfg_write(uint16_t cmd, char *buf, unsigned int nbytes)
+{
+    unsigned int i;
+
+    *fw_cfg_cmd = cmd;
+    for (i = 0; i < nbytes; i++) {
+        *fw_cfg_data = buf[i];
+    }
+}
 #else
 // XXX depends on PCI bus location, should be removed
 void
@@ -29,6 +40,17 @@ fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes)
     for (i = 0; i < nbytes; i++)
         buf[i] = inb(CONFIG_FW_CFG_ADDR + 1);
 }
+
+void
+fw_cfg_write(uint16_t cmd, char *buf, unsigned int nbytes)
+{
+    unsigned int i;
+
+    outw(cmd, CONFIG_FW_CFG_ADDR);
+    for (i = 0; i < nbytes; i++) {
+        outb(buf[i], CONFIG_FW_CFG_ADDR + 1);
+    }
+}
 #endif
 
 uint64_t
diff --git a/drivers/ide.c b/drivers/ide.c
index 0d09bcd..e4f68f4 100644
--- a/drivers/ide.c
+++ b/drivers/ide.c
@@ -23,6 +23,7 @@
 #include "ide.h"
 #include "hdreg.h"
 #include "timer.h"
+#include "trace.h"
 
 #ifdef CONFIG_DEBUG_IDE
 #define IDE_DPRINTF(fmt, args...) \
@@ -161,7 +162,7 @@ ob_ide_pio_insw(struct ide_drive *drive, unsigned int offset,
 	struct ide_channel *chan = drive->channel;
 
 	if (len & 1) {
-		IDE_DPRINTF("%d: command not word aligned\n", drive->nr);
+                trace_ob_ide_pio_insw(drive->nr);
 		return;
 	}
 
@@ -1193,8 +1194,7 @@ ob_ide_read_blocks(int *idx)
 	unsigned char *dest = (unsigned char *)cell2pointer(POP());
 	struct ide_drive *drive = *(struct ide_drive **)idx;
 
-        IDE_DPRINTF("ob_ide_read_blocks %lx block=%ld n=%ld\n",
-                    (unsigned long)dest, (unsigned long)blk, (long)n);
+        trace_ob_ide_read_blocks((unsigned long)dest, (unsigned long)blk, (long)n);
 
 	while (n) {
 		int len = n;
diff --git a/include/arch/common/fw_cfg.h b/include/arch/common/fw_cfg.h
index b0a23cd..1448961 100644
--- a/include/arch/common/fw_cfg.h
+++ b/include/arch/common/fw_cfg.h
@@ -1,6 +1,9 @@
 #ifndef FW_CFG_H
 #define FW_CFG_H
 
+#define FW_CFG_WRITE_CHANNEL    0x4000
+#define FW_CFG_ARCH_LOCAL       0x8000
+
 #define FW_CFG_SIGNATURE        0x00
 #define FW_CFG_ID               0x01
 #define FW_CFG_UUID             0x02
@@ -30,10 +33,11 @@
 
 #define FW_CFG_FILE_FIRST       0x20
 #define FW_CFG_FILE_SLOTS       0x10
+
+#define FW_CFG_GUEST_TRACE      (FW_CFG_WRITE_CHANNEL | (FW_CFG_FILE_FIRST+FW_CFG_FILE_SLOTS))
+
 #define FW_CFG_MAX_ENTRY        (FW_CFG_FILE_FIRST+FW_CFG_FILE_SLOTS)
 
-#define FW_CFG_WRITE_CHANNEL    0x4000
-#define FW_CFG_ARCH_LOCAL       0x8000
 #define FW_CFG_ENTRY_MASK       ~(FW_CFG_WRITE_CHANNEL | FW_CFG_ARCH_LOCAL)
 
 #define FW_CFG_PPC_WIDTH        (FW_CFG_ARCH_LOCAL + 0x00)
@@ -78,6 +82,7 @@ FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
 
 #ifndef NO_OPENBIOS_PROTOS
 void fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes);
+void fw_cfg_write(uint16_t cmd, char *buf, unsigned int nbytes);
 uint64_t fw_cfg_read_i64(uint16_t cmd);
 uint32_t fw_cfg_read_i32(uint16_t cmd);
 uint16_t fw_cfg_read_i16(uint16_t cmd);
diff --git a/include/libopenbios/simpletrace.h b/include/libopenbios/simpletrace.h
new file mode 100644
index 0000000..aa98ee3
--- /dev/null
+++ b/include/libopenbios/simpletrace.h
@@ -0,0 +1,31 @@
+/*
+ * Simple trace backend
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef SIMPLETRACE_H
+#define SIMPLETRACE_H
+
+#include "asm/types.h"
+
+typedef uint64_t TraceEventID;
+
+typedef struct {
+    const char *tp_name;
+    int state;
+} TraceEvent;
+
+void trace0(TraceEventID event);
+void trace1(TraceEventID event, uint64_t x1);
+void trace2(TraceEventID event, uint64_t x1, uint64_t x2);
+void trace3(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3);
+void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4);
+void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5);
+void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6);
+
+#endif /* SIMPLETRACE_H */
diff --git a/libopenbios/build.xml b/libopenbios/build.xml
index 04e3800..b16cd35 100644
--- a/libopenbios/build.xml
+++ b/libopenbios/build.xml
@@ -19,6 +19,39 @@
   <object source="linuxbios_info.c" condition="LINUXBIOS"/>
   <object source="ofmem_common.c" condition="OFMEM"/>
   <object source="xcoff_load.c" condition="LOADER_XCOFF"/>
+  <object source="simpletrace.c" condition="TRACE_SIMPLETRACE"/>
+ <executable name="target/include/trace.h" condition="TRACE_SIMPLETRACE">
+  <rule><![CDATA[ $(ODIR)/target/include/trace.h-timestamp
+
+$(ODIR)/target/include/trace.h-timestamp: $(SRCDIR)/trace-events
+	$(call quiet-command,sh $(SRCDIR)/config/scripts/tracetool --simple -h < $< > $@,"  GEN   trace.h")
+	@cmp -s $@ $(ODIR)/target/include/trace.h || cp $@ $(ODIR)/target/include/trace.h]]></rule>
+  </executable>
+ <executable name="target/libopenbios/trace.c" condition="TRACE_SIMPLETRACE">
+  <rule><![CDATA[ $(ODIR)/target/libopenbios/trace.c-timestamp
+
+$(ODIR)/target/libopenbios/trace.c-timestamp: $(SRCDIR)/trace-events
+	$(call quiet-command,sh $(SRCDIR)/config/scripts/tracetool --simple -c < $< > $@,"  GEN   trace.c")
+	@cmp -s $@ $(ODIR)/target/libopenbios/trace.c || cp $@ $(ODIR)/target/libopenbios/trace.c]]></rule>
+  </executable>
+ <executable name="target/include/trace.h" condition="TRACE_STDERR">
+  <rule><![CDATA[ $(ODIR)/target/include/trace.h-timestamp
+
+$(ODIR)/target/include/trace.h-timestamp: $(SRCDIR)/trace-events
+	$(call quiet-command,sh $(SRCDIR)/config/scripts/tracetool --stderr -h < $< > $@,"  GEN   trace.h")
+	@cmp -s $@ $(ODIR)/target/include/trace.h || cp $@ $(ODIR)/target/include/trace.h]]></rule>
+  </executable>
+ <executable name="target/libopenbios/trace.c" condition="TRACE_STDERR">
+  <rule><![CDATA[ $(ODIR)/target/libopenbios/trace.c-timestamp
+
+$(ODIR)/target/libopenbios/trace.c-timestamp: $(SRCDIR)/trace-events
+	$(call quiet-command,sh $(SRCDIR)/config/scripts/tracetool --stderr -c < $< > $@,"  GEN   trace.c")
+	@cmp -s $@ $(ODIR)/target/libopenbios/trace.c || cp $@ $(ODIR)/target/libopenbios/trace.c]]></rule>
+  </executable>
+  <executable name="target/libopenbios/trace.o">
+   <rule><![CDATA[ $(ODIR)/target/libopenbios/trace.c $(ODIR)/target/include/trace.h
+	$(call quiet-command,$(CC) $$EXTRACFLAGS $(CFLAGS) $(INCLUDES) -c -o $@ $<, "  CC    $(TARGET_DIR)$@")]]></rule>
+  </executable>
  </library>
 
  <dictionary name="openbios" target="forth">
diff --git a/libopenbios/simpletrace.c b/libopenbios/simpletrace.c
new file mode 100644
index 0000000..8795b81
--- /dev/null
+++ b/libopenbios/simpletrace.c
@@ -0,0 +1,76 @@
+/*
+ * Simple trace backend
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "libopenbios/simpletrace.h"
+#include "trace.h"
+#include "libc/byteorder.h"
+#define NO_QEMU_PROTOS
+#include "arch/common/fw_cfg.h"
+
+/** Trace buffer entry, without timestamp */
+typedef struct {
+    uint64_t event;
+    uint64_t x1;
+    uint64_t x2;
+    uint64_t x3;
+    uint64_t x4;
+    uint64_t x5;
+    uint64_t x6;
+} TraceRecord;
+
+static void trace(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3,
+                  uint64_t x4, uint64_t x5, uint64_t x6)
+{
+    TraceRecord tmp = (TraceRecord){
+        .event = __cpu_to_le64(event),
+        .x1 = __cpu_to_le64(x1),
+        .x2 = __cpu_to_le64(x2),
+        .x3 = __cpu_to_le64(x3),
+        .x4 = __cpu_to_le64(x4),
+        .x5 = __cpu_to_le64(x5),
+        .x6 = __cpu_to_le64(x6),
+    };
+    fw_cfg_write(FW_CFG_GUEST_TRACE, (char *)&tmp, sizeof(tmp));
+}
+
+void trace0(TraceEventID event)
+{
+    trace(event, 0, 0, 0, 0, 0, 0);
+}
+
+void trace1(TraceEventID event, uint64_t x1)
+{
+    trace(event, x1, 0, 0, 0, 0, 0);
+}
+
+void trace2(TraceEventID event, uint64_t x1, uint64_t x2)
+{
+    trace(event, x1, x2, 0, 0, 0, 0);
+}
+
+void trace3(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3)
+{
+    trace(event, x1, x2, x3, 0, 0, 0);
+}
+
+void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4)
+{
+    trace(event, x1, x2, x3, x4, 0, 0);
+}
+
+void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5)
+{
+    trace(event, x1, x2, x3, x4, x5, 0);
+}
+
+void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6)
+{
+    trace(event, x1, x2, x3, x4, x5, x6);
+}
diff --git a/trace-events b/trace-events
new file mode 100644
index 0000000..0fbb853
--- /dev/null
+++ b/trace-events
@@ -0,0 +1,3 @@
+esp_do_command(int id, int cmd, int status) "id %d, cmd[0] 0x%x, status 0x%x"
+ob_ide_pio_insw(int drive) "%d: command not word aligned"
+ob_ide_read_blocks(unsigned long dest, unsigned long blk, long n) "%lx block=%ld n=%ld"
-- 
1.7.2.5


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

* Re: [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough
  2011-08-26 19:06 [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough Blue Swirl
@ 2011-08-29 12:17 ` Stefan Hajnoczi
  2011-08-29 12:51   ` Lluís
  2011-08-30 18:43   ` Blue Swirl
  2011-08-31  8:38 ` Avi Kivity
  1 sibling, 2 replies; 17+ messages in thread
From: Stefan Hajnoczi @ 2011-08-29 12:17 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Lluís, Dhaval Giani, Stefan Hajnoczi, qemu-devel

On Fri, Aug 26, 2011 at 8:06 PM, Blue Swirl <blauwirbel@gmail.com> wrote:
> Let guests inject tracepoint data via fw_cfg device.
>
> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
> ---
> The patch is used like this:
> ../configure --with-guest-trace-file=/src/openbios-devel/trace-events
> make
> sparc64-softmmu/qemu-system-sparc64 -trace file=foo
> # ugly hack to combine the file, but my laziness^Wpython-fu is too
> weak to add handling of "--guest-trace-file
> /src/openbios-devel/trace-events" to simpletrace.py
> cat ../trace-events /src/openbios-devel/trace-events >/tmp/trace-events
> # examine trace file with OpenBIOS trace data with simpletrace.py
> ../scripts/simpletrace.py /tmp/trace-events foo
> ob_ide_read_blocks 0.000 dest=0xfff0bed0 blk=0x0 n=0x1
> ob_ide_read_blocks 6491.806 dest=0xfff0bed0 blk=0x0 n=0x1
>
> An example of a generated guest-trace.c file:
> /* This file is autogenerated by tracetool, do not edit. */
> #include "trace.h"
> #include "guest-trace.h"
>
> void guest_trace(uint64_t event_id, uint64_t arg1, uint64_t arg2,
>                 uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6)
>
> {
>    switch (event_id) {
>
>    case 0:
>        trace_esp_do_command(arg1, arg2, arg3);
>        break;
>
>    case 1:
>        trace_ob_ide_pio_insw(arg1);
>        break;
>
>    case 2:
>        trace_ob_ide_read_blocks(arg1, arg2, arg3);
>        break;
>
>    default:
>        break;
>   }
> }
>
> ---
>  Makefile.objs     |   15 +++++++++++-
>  configure         |    9 +++++++-
>  guest-trace.h     |    3 ++
>  hw/fw_cfg.c       |   31 +++++++++++++++++++++++++++
>  hw/fw_cfg.h       |   10 ++++++--
>  scripts/tracetool |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++-
>  6 files changed, 120 insertions(+), 8 deletions(-)
>  create mode 100644 guest-trace.h

The ability to trace from the guest can be handy, so I think we should
have this feature.  Please add documentation on how to hook it up
(e.g. how people would use this for other firmware/guest code and/or
other architectures).

Guest and QEMU need to agree on event IDs.  The guest code needs to be
built with QEMU and they may not function with other QEMU builds or
guest builds.  This is fine for development but not feasible when QEMU
and the guest code are built or provided separately.

I suggest we merge this as a development feature that can be used when
bringing up new architectures, debugging guest code, or for some types
of performance work.  This feature falls under the Do-It-Yourself
area, where things could break relatively easy but developers who wish
to use it should be able to get it working in their area.

> +linetog_all()
> +{
> +    local name args argc arg
> +    name=$(get_name "$1")
> +    argc=$(get_argc "$1")
> +    fieldno=1

local fieldno

Stefan

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

* Re: [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough
  2011-08-29 12:17 ` Stefan Hajnoczi
@ 2011-08-29 12:51   ` Lluís
  2011-08-30 18:58     ` Blue Swirl
  2011-08-30 18:43   ` Blue Swirl
  1 sibling, 1 reply; 17+ messages in thread
From: Lluís @ 2011-08-29 12:51 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Blue Swirl, qemu-devel, Lluís, Stefan Hajnoczi, Dhaval Giani

Stefan Hajnoczi writes:

> The ability to trace from the guest can be handy, so I think we should
> have this feature.  Please add documentation on how to hook it up
> (e.g. how people would use this for other firmware/guest code and/or
> other architectures).

> Guest and QEMU need to agree on event IDs.  The guest code needs to be
> built with QEMU and they may not function with other QEMU builds or
> guest builds.  This is fine for development but not feasible when QEMU
> and the guest code are built or provided separately.

> I suggest we merge this as a development feature that can be used when
> bringing up new architectures, debugging guest code, or for some types
> of performance work.  This feature falls under the Do-It-Yourself
> area, where things could break relatively easy but developers who wish
> to use it should be able to get it working in their area.

This sounds is indeed interesting.

I suppose I could even use this as a backdoor mechanism for the guest to
communicate with QEMU. The only problem I see is that fw_cfg is one-way
(i.e., QEMU cannot return any data back to the guest), as opposed to a
backdoor mechanism based on a virtual device or "magic" instructions.


Lluis

-- 
 "And it's much the same thing with knowledge, for whenever you learn
 something new, the whole world becomes that much richer."
 -- The Princess of Pure Reason, as told by Norton Juster in The Phantom
 Tollbooth

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

* Re: [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough
  2011-08-29 12:17 ` Stefan Hajnoczi
  2011-08-29 12:51   ` Lluís
@ 2011-08-30 18:43   ` Blue Swirl
  2011-08-31  7:24     ` Stefan Hajnoczi
  1 sibling, 1 reply; 17+ messages in thread
From: Blue Swirl @ 2011-08-30 18:43 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: Lluís, Dhaval Giani, Stefan Hajnoczi, qemu-devel

On Mon, Aug 29, 2011 at 12:17 PM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
> On Fri, Aug 26, 2011 at 8:06 PM, Blue Swirl <blauwirbel@gmail.com> wrote:
>> Let guests inject tracepoint data via fw_cfg device.
>>
>> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
>> ---
>> The patch is used like this:
>> ../configure --with-guest-trace-file=/src/openbios-devel/trace-events
>> make
>> sparc64-softmmu/qemu-system-sparc64 -trace file=foo
>> # ugly hack to combine the file, but my laziness^Wpython-fu is too
>> weak to add handling of "--guest-trace-file
>> /src/openbios-devel/trace-events" to simpletrace.py
>> cat ../trace-events /src/openbios-devel/trace-events >/tmp/trace-events
>> # examine trace file with OpenBIOS trace data with simpletrace.py
>> ../scripts/simpletrace.py /tmp/trace-events foo
>> ob_ide_read_blocks 0.000 dest=0xfff0bed0 blk=0x0 n=0x1
>> ob_ide_read_blocks 6491.806 dest=0xfff0bed0 blk=0x0 n=0x1
>>
>> An example of a generated guest-trace.c file:
>> /* This file is autogenerated by tracetool, do not edit. */
>> #include "trace.h"
>> #include "guest-trace.h"
>>
>> void guest_trace(uint64_t event_id, uint64_t arg1, uint64_t arg2,
>>                 uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6)
>>
>> {
>>    switch (event_id) {
>>
>>    case 0:
>>        trace_esp_do_command(arg1, arg2, arg3);
>>        break;
>>
>>    case 1:
>>        trace_ob_ide_pio_insw(arg1);
>>        break;
>>
>>    case 2:
>>        trace_ob_ide_read_blocks(arg1, arg2, arg3);
>>        break;
>>
>>    default:
>>        break;
>>   }
>> }
>>
>> ---
>>  Makefile.objs     |   15 +++++++++++-
>>  configure         |    9 +++++++-
>>  guest-trace.h     |    3 ++
>>  hw/fw_cfg.c       |   31 +++++++++++++++++++++++++++
>>  hw/fw_cfg.h       |   10 ++++++--
>>  scripts/tracetool |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++-
>>  6 files changed, 120 insertions(+), 8 deletions(-)
>>  create mode 100644 guest-trace.h
>
> The ability to trace from the guest can be handy, so I think we should
> have this feature.  Please add documentation on how to hook it up
> (e.g. how people would use this for other firmware/guest code and/or
> other architectures).

OK. The format should be the same as raw simpletrace data, but words
always in little endian like used elsewhere with fw_cfg. BTW,
currently simpletrace file format depends on host endianness, is that
intentional?

> Guest and QEMU need to agree on event IDs.  The guest code needs to be
> built with QEMU and they may not function with other QEMU builds or
> guest builds.  This is fine for development but not feasible when QEMU
> and the guest code are built or provided separately.

Yes, for this part I'm not so happy about the code. It should be
possible to replace the (very simple) switch with (very complicated)
code to dynamically read and handle the guest tracepoint list, but
that can be added later if ever.

> I suggest we merge this as a development feature that can be used when
> bringing up new architectures, debugging guest code, or for some types
> of performance work.  This feature falls under the Do-It-Yourself
> area, where things could break relatively easy but developers who wish
> to use it should be able to get it working in their area.
>
>> +linetog_all()
>> +{
>> +    local name args argc arg
>> +    name=$(get_name "$1")
>> +    argc=$(get_argc "$1")
>> +    fieldno=1
>
> local fieldno

Thanks for the review.

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

* Re: [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough
  2011-08-29 12:51   ` Lluís
@ 2011-08-30 18:58     ` Blue Swirl
  0 siblings, 0 replies; 17+ messages in thread
From: Blue Swirl @ 2011-08-30 18:58 UTC (permalink / raw)
  To: Stefan Hajnoczi, Blue Swirl, Lluís, Dhaval Giani,
	Stefan Hajnoczi, qemu-devel

On Mon, Aug 29, 2011 at 12:51 PM, Lluís <xscript@gmx.net> wrote:
> Stefan Hajnoczi writes:
>
>> The ability to trace from the guest can be handy, so I think we should
>> have this feature.  Please add documentation on how to hook it up
>> (e.g. how people would use this for other firmware/guest code and/or
>> other architectures).
>
>> Guest and QEMU need to agree on event IDs.  The guest code needs to be
>> built with QEMU and they may not function with other QEMU builds or
>> guest builds.  This is fine for development but not feasible when QEMU
>> and the guest code are built or provided separately.
>
>> I suggest we merge this as a development feature that can be used when
>> bringing up new architectures, debugging guest code, or for some types
>> of performance work.  This feature falls under the Do-It-Yourself
>> area, where things could break relatively easy but developers who wish
>> to use it should be able to get it working in their area.
>
> This sounds is indeed interesting.
>
> I suppose I could even use this as a backdoor mechanism for the guest to
> communicate with QEMU.

Well, fw_cfg is intended for very low level BIOS code. Virtual PCI
devices would be better for OS level.

> The only problem I see is that fw_cfg is one-way
> (i.e., QEMU cannot return any data back to the guest), as opposed to a
> backdoor mechanism based on a virtual device or "magic" instructions.

This should be possible.

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

* Re: [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough
  2011-08-30 18:43   ` Blue Swirl
@ 2011-08-31  7:24     ` Stefan Hajnoczi
  0 siblings, 0 replies; 17+ messages in thread
From: Stefan Hajnoczi @ 2011-08-31  7:24 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Lluís, Dhaval Giani, Stefan Hajnoczi, qemu-devel

On Tue, Aug 30, 2011 at 7:43 PM, Blue Swirl <blauwirbel@gmail.com> wrote:
> On Mon, Aug 29, 2011 at 12:17 PM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
>> On Fri, Aug 26, 2011 at 8:06 PM, Blue Swirl <blauwirbel@gmail.com> wrote:
>>> Let guests inject tracepoint data via fw_cfg device.
>>>
>>> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
>>> ---
>>> The patch is used like this:
>>> ../configure --with-guest-trace-file=/src/openbios-devel/trace-events
>>> make
>>> sparc64-softmmu/qemu-system-sparc64 -trace file=foo
>>> # ugly hack to combine the file, but my laziness^Wpython-fu is too
>>> weak to add handling of "--guest-trace-file
>>> /src/openbios-devel/trace-events" to simpletrace.py
>>> cat ../trace-events /src/openbios-devel/trace-events >/tmp/trace-events
>>> # examine trace file with OpenBIOS trace data with simpletrace.py
>>> ../scripts/simpletrace.py /tmp/trace-events foo
>>> ob_ide_read_blocks 0.000 dest=0xfff0bed0 blk=0x0 n=0x1
>>> ob_ide_read_blocks 6491.806 dest=0xfff0bed0 blk=0x0 n=0x1
>>>
>>> An example of a generated guest-trace.c file:
>>> /* This file is autogenerated by tracetool, do not edit. */
>>> #include "trace.h"
>>> #include "guest-trace.h"
>>>
>>> void guest_trace(uint64_t event_id, uint64_t arg1, uint64_t arg2,
>>>                 uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6)
>>>
>>> {
>>>    switch (event_id) {
>>>
>>>    case 0:
>>>        trace_esp_do_command(arg1, arg2, arg3);
>>>        break;
>>>
>>>    case 1:
>>>        trace_ob_ide_pio_insw(arg1);
>>>        break;
>>>
>>>    case 2:
>>>        trace_ob_ide_read_blocks(arg1, arg2, arg3);
>>>        break;
>>>
>>>    default:
>>>        break;
>>>   }
>>> }
>>>
>>> ---
>>>  Makefile.objs     |   15 +++++++++++-
>>>  configure         |    9 +++++++-
>>>  guest-trace.h     |    3 ++
>>>  hw/fw_cfg.c       |   31 +++++++++++++++++++++++++++
>>>  hw/fw_cfg.h       |   10 ++++++--
>>>  scripts/tracetool |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++-
>>>  6 files changed, 120 insertions(+), 8 deletions(-)
>>>  create mode 100644 guest-trace.h
>>
>> The ability to trace from the guest can be handy, so I think we should
>> have this feature.  Please add documentation on how to hook it up
>> (e.g. how people would use this for other firmware/guest code and/or
>> other architectures).
>
> OK. The format should be the same as raw simpletrace data, but words
> always in little endian like used elsewhere with fw_cfg. BTW,
> currently simpletrace file format depends on host endianness, is that
> intentional?

Yes, it is intentional.  The rationale is that we want to stream trace
events to disk as quickly as possible without any overhead.  Since
there is a magic number in the first trace record, the post-processing
tool can in theory determine the endianness and do the byteswapping at
that time.  The current simpletrace.py script does not do this.

Stefan

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

* Re: [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough
  2011-08-26 19:06 [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough Blue Swirl
  2011-08-29 12:17 ` Stefan Hajnoczi
@ 2011-08-31  8:38 ` Avi Kivity
  2011-08-31  9:08   ` Stefan Hajnoczi
  2011-08-31 17:58   ` Blue Swirl
  1 sibling, 2 replies; 17+ messages in thread
From: Avi Kivity @ 2011-08-31  8:38 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Lluís, Dhaval Giani, Stefan Hajnoczi, qemu-devel

On 08/26/2011 10:06 PM, Blue Swirl wrote:
> Let guests inject tracepoint data via fw_cfg device.
>
>

At least on x86, fw_cfg is pretty slow, involving multiple exits.  IMO, 
for kvm, even one exit per tracepoint is too high.  We need to use a 
shared memory transport with a way to order guest/host events later on 
(by using a clock).

-- 
error compiling committee.c: too many arguments to function

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

* Re: [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough
  2011-08-31  8:38 ` Avi Kivity
@ 2011-08-31  9:08   ` Stefan Hajnoczi
  2011-08-31  9:11     ` Avi Kivity
  2011-08-31 10:54     ` Jan Kiszka
  2011-08-31 17:58   ` Blue Swirl
  1 sibling, 2 replies; 17+ messages in thread
From: Stefan Hajnoczi @ 2011-08-31  9:08 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Blue Swirl, Lluís, qemu-devel, Dhaval Giani

On Wed, Aug 31, 2011 at 11:38:50AM +0300, Avi Kivity wrote:
> On 08/26/2011 10:06 PM, Blue Swirl wrote:
> >Let guests inject tracepoint data via fw_cfg device.
> >
> >
> 
> At least on x86, fw_cfg is pretty slow, involving multiple exits.
> IMO, for kvm, even one exit per tracepoint is too high.  We need to
> use a shared memory transport with a way to order guest/host events
> later on (by using a clock).

It depends how you want to use this.  If you need it for guest firmware
debugging or bringing up a new target, then this approach is fine.

But this is not a mechanism that is suitable for performance analysis or
production tracing (the fact that the QEMU and guest software need to be
built together in order to sync on event IDs is the killer).

Dhaval is looking at Linux guest tracing which is suitable for
performance work.  This does not necessarily involve modifying QEMU.
Currently he uses a hypercall but a virtio device would be possible too.
The key thing is that it integrates with the host kernel tracing
infrastructure so you get a unified trace instead of terminating in QEMU
userspace.

So I see Blue's feature as a quick starting point for people who need to
debug and hack guests.  It should be simple and easy to get going for
QEMU developers, but is not suitable for other use.

Stefan

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

* Re: [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough
  2011-08-31  9:08   ` Stefan Hajnoczi
@ 2011-08-31  9:11     ` Avi Kivity
  2011-08-31 13:38       ` Stefan Hajnoczi
  2011-08-31 10:54     ` Jan Kiszka
  1 sibling, 1 reply; 17+ messages in thread
From: Avi Kivity @ 2011-08-31  9:11 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: Blue Swirl, Lluís, qemu-devel, Dhaval Giani

On 08/31/2011 12:08 PM, Stefan Hajnoczi wrote:
> >
> >  At least on x86, fw_cfg is pretty slow, involving multiple exits.
> >  IMO, for kvm, even one exit per tracepoint is too high.  We need to
> >  use a shared memory transport with a way to order guest/host events
> >  later on (by using a clock).
>
> It depends how you want to use this.  If you need it for guest firmware
> debugging or bringing up a new target, then this approach is fine.
>
> But this is not a mechanism that is suitable for performance analysis or
> production tracing (the fact that the QEMU and guest software need to be
> built together in order to sync on event IDs is the killer).
>
> Dhaval is looking at Linux guest tracing which is suitable for
> performance work.  This does not necessarily involve modifying QEMU.
> Currently he uses a hypercall but a virtio device would be possible too.

IMO a hypercall is the way to go, virtio is not entirely suitable for 
per-cpu work.

> The key thing is that it integrates with the host kernel tracing
> infrastructure so you get a unified trace instead of terminating in QEMU
> userspace.
>
> So I see Blue's feature as a quick starting point for people who need to
> debug and hack guests.  It should be simple and easy to get going for
> QEMU developers, but is not suitable for other use.
>

We should have one tracing mechanism that is useful everywhere, not 
fragmented functionality.

-- 
error compiling committee.c: too many arguments to function

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

* Re: [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough
  2011-08-31  9:08   ` Stefan Hajnoczi
  2011-08-31  9:11     ` Avi Kivity
@ 2011-08-31 10:54     ` Jan Kiszka
  1 sibling, 0 replies; 17+ messages in thread
From: Jan Kiszka @ 2011-08-31 10:54 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Blue Swirl, qemu-devel, Dhaval Giani, Avi Kivity, Lluís

On 2011-08-31 11:08, Stefan Hajnoczi wrote:
> On Wed, Aug 31, 2011 at 11:38:50AM +0300, Avi Kivity wrote:
>> On 08/26/2011 10:06 PM, Blue Swirl wrote:
>>> Let guests inject tracepoint data via fw_cfg device.
>>>
>>>
>>
>> At least on x86, fw_cfg is pretty slow, involving multiple exits.
>> IMO, for kvm, even one exit per tracepoint is too high.  We need to
>> use a shared memory transport with a way to order guest/host events
>> later on (by using a clock).
> 
> It depends how you want to use this.  If you need it for guest firmware
> debugging or bringing up a new target, then this approach is fine.
> 
> But this is not a mechanism that is suitable for performance analysis or
> production tracing (the fact that the QEMU and guest software need to be
> built together in order to sync on event IDs is the killer).
> 
> Dhaval is looking at Linux guest tracing which is suitable for
> performance work.  This does not necessarily involve modifying QEMU.
> Currently he uses a hypercall but a virtio device would be possible too.
> The key thing is that it integrates with the host kernel tracing
> infrastructure so you get a unified trace instead of terminating in QEMU
> userspace.
> 
> So I see Blue's feature as a quick starting point for people who need to
> debug and hack guests.  It should be simple and easy to get going for
> QEMU developers, but is not suitable for other use.

We already have isa-debugcon or plain serial/virtio consoles. Should be
easy to derive e.g. some mmio-debugcon and to establish a chardev
backend that writes out trace events. I also think that fw_cfg is for,
well, configuration.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

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

* Re: [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough
  2011-08-31  9:11     ` Avi Kivity
@ 2011-08-31 13:38       ` Stefan Hajnoczi
  2011-08-31 18:01         ` Dhaval Giani
  0 siblings, 1 reply; 17+ messages in thread
From: Stefan Hajnoczi @ 2011-08-31 13:38 UTC (permalink / raw)
  To: Dhaval Giani
  Cc: Blue Swirl, qemu-devel, Stefan Hajnoczi, Avi Kivity, Lluís

On Wed, Aug 31, 2011 at 10:11 AM, Avi Kivity <avi@redhat.com> wrote:
> On 08/31/2011 12:08 PM, Stefan Hajnoczi wrote:
>>
>> >
>> >  At least on x86, fw_cfg is pretty slow, involving multiple exits.
>> >  IMO, for kvm, even one exit per tracepoint is too high.  We need to
>> >  use a shared memory transport with a way to order guest/host events
>> >  later on (by using a clock).
>>
>> It depends how you want to use this.  If you need it for guest firmware
>> debugging or bringing up a new target, then this approach is fine.
>>
>> But this is not a mechanism that is suitable for performance analysis or
>> production tracing (the fact that the QEMU and guest software need to be
>> built together in order to sync on event IDs is the killer).
>>
>> Dhaval is looking at Linux guest tracing which is suitable for
>> performance work.  This does not necessarily involve modifying QEMU.
>> Currently he uses a hypercall but a virtio device would be possible too.
>
> IMO a hypercall is the way to go, virtio is not entirely suitable for
> per-cpu work.
>
>> The key thing is that it integrates with the host kernel tracing
>> infrastructure so you get a unified trace instead of terminating in QEMU
>> userspace.
>>
>> So I see Blue's feature as a quick starting point for people who need to
>> debug and hack guests.  It should be simple and easy to get going for
>> QEMU developers, but is not suitable for other use.
>>
>
> We should have one tracing mechanism that is useful everywhere, not
> fragmented functionality.

You have a point.

Dhaval: Any update on the approach you are working on?  Do you have
public code we can look at?

Stefan

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

* Re: [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough
  2011-08-31  8:38 ` Avi Kivity
  2011-08-31  9:08   ` Stefan Hajnoczi
@ 2011-08-31 17:58   ` Blue Swirl
  2011-08-31 18:00     ` Dhaval Giani
  1 sibling, 1 reply; 17+ messages in thread
From: Blue Swirl @ 2011-08-31 17:58 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Lluís, Dhaval Giani, Stefan Hajnoczi, qemu-devel

On Wed, Aug 31, 2011 at 8:38 AM, Avi Kivity <avi@redhat.com> wrote:
> On 08/26/2011 10:06 PM, Blue Swirl wrote:
>>
>> Let guests inject tracepoint data via fw_cfg device.
>>
>>
>
> At least on x86, fw_cfg is pretty slow, involving multiple exits.  IMO, for
> kvm, even one exit per tracepoint is too high.  We need to use a shared
> memory transport with a way to order guest/host events later on (by using a
> clock).

This could be an easy way, if the guest always had access to an
accurate clock, but that may not be the case.

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

* Re: [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough
  2011-08-31 17:58   ` Blue Swirl
@ 2011-08-31 18:00     ` Dhaval Giani
  2011-09-03  8:53       ` Blue Swirl
  0 siblings, 1 reply; 17+ messages in thread
From: Dhaval Giani @ 2011-08-31 18:00 UTC (permalink / raw)
  To: Blue Swirl; +Cc: qemu-devel, Lluís, Avi Kivity, Stefan Hajnoczi

On Wed, Aug 31, 2011 at 10:58 AM, Blue Swirl <blauwirbel@gmail.com> wrote:
> On Wed, Aug 31, 2011 at 8:38 AM, Avi Kivity <avi@redhat.com> wrote:
>> On 08/26/2011 10:06 PM, Blue Swirl wrote:
>>>
>>> Let guests inject tracepoint data via fw_cfg device.
>>>
>>>
>>
>> At least on x86, fw_cfg is pretty slow, involving multiple exits.  IMO, for
>> kvm, even one exit per tracepoint is too high.  We need to use a shared
>> memory transport with a way to order guest/host events later on (by using a
>> clock).
>
> This could be an easy way, if the guest always had access to an
> accurate clock, but that may not be the case.
>

>From what I understand, kvmclock should be good enoguh for this
purpose. That is what I am using.

Dhaval

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

* Re: [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough
  2011-08-31 13:38       ` Stefan Hajnoczi
@ 2011-08-31 18:01         ` Dhaval Giani
  0 siblings, 0 replies; 17+ messages in thread
From: Dhaval Giani @ 2011-08-31 18:01 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Blue Swirl, qemu-devel, Stefan Hajnoczi, Avi Kivity, Lluís

On Wed, Aug 31, 2011 at 6:38 AM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
> On Wed, Aug 31, 2011 at 10:11 AM, Avi Kivity <avi@redhat.com> wrote:
>> On 08/31/2011 12:08 PM, Stefan Hajnoczi wrote:
>>>
>>> >
>>> >  At least on x86, fw_cfg is pretty slow, involving multiple exits.
>>> >  IMO, for kvm, even one exit per tracepoint is too high.  We need to
>>> >  use a shared memory transport with a way to order guest/host events
>>> >  later on (by using a clock).
>>>
>>> It depends how you want to use this.  If you need it for guest firmware
>>> debugging or bringing up a new target, then this approach is fine.
>>>
>>> But this is not a mechanism that is suitable for performance analysis or
>>> production tracing (the fact that the QEMU and guest software need to be
>>> built together in order to sync on event IDs is the killer).
>>>
>>> Dhaval is looking at Linux guest tracing which is suitable for
>>> performance work.  This does not necessarily involve modifying QEMU.
>>> Currently he uses a hypercall but a virtio device would be possible too.
>>
>> IMO a hypercall is the way to go, virtio is not entirely suitable for
>> per-cpu work.
>>
>>> The key thing is that it integrates with the host kernel tracing
>>> infrastructure so you get a unified trace instead of terminating in QEMU
>>> userspace.
>>>
>>> So I see Blue's feature as a quick starting point for people who need to
>>> debug and hack guests.  It should be simple and easy to get going for
>>> QEMU developers, but is not suitable for other use.
>>>
>>
>> We should have one tracing mechanism that is useful everywhere, not
>> fragmented functionality.
>
> You have a point.
>
> Dhaval: Any update on the approach you are working on?  Do you have
> public code we can look at?
>

I will try to post it soon. It will probably be untested and will not
work, but you will have the approach to look at :-)

Thanks
Dhaval

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

* Re: [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough
  2011-08-31 18:00     ` Dhaval Giani
@ 2011-09-03  8:53       ` Blue Swirl
  2011-09-03  9:26         ` Dhaval Giani
  0 siblings, 1 reply; 17+ messages in thread
From: Blue Swirl @ 2011-09-03  8:53 UTC (permalink / raw)
  To: Dhaval Giani; +Cc: qemu-devel, Lluís, Avi Kivity, Stefan Hajnoczi

On Wed, Aug 31, 2011 at 6:00 PM, Dhaval Giani <dhaval.giani@gmail.com> wrote:
> On Wed, Aug 31, 2011 at 10:58 AM, Blue Swirl <blauwirbel@gmail.com> wrote:
>> On Wed, Aug 31, 2011 at 8:38 AM, Avi Kivity <avi@redhat.com> wrote:
>>> On 08/26/2011 10:06 PM, Blue Swirl wrote:
>>>>
>>>> Let guests inject tracepoint data via fw_cfg device.
>>>>
>>>>
>>>
>>> At least on x86, fw_cfg is pretty slow, involving multiple exits.  IMO, for
>>> kvm, even one exit per tracepoint is too high.  We need to use a shared
>>> memory transport with a way to order guest/host events later on (by using a
>>> clock).
>>
>> This could be an easy way, if the guest always had access to an
>> accurate clock, but that may not be the case.
>>
>
> From what I understand, kvmclock should be good enoguh for this
> purpose. That is what I am using.

It's only available for KVM on x86, that is most certainly not enough.

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

* Re: [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough
  2011-09-03  8:53       ` Blue Swirl
@ 2011-09-03  9:26         ` Dhaval Giani
  2011-09-03 10:55           ` Blue Swirl
  0 siblings, 1 reply; 17+ messages in thread
From: Dhaval Giani @ 2011-09-03  9:26 UTC (permalink / raw)
  To: Blue Swirl
  Cc: qemu-devel, Glauber Costa, Lluís, Avi Kivity, Stefan Hajnoczi

On Sat, Sep 3, 2011 at 1:53 AM, Blue Swirl <blauwirbel@gmail.com> wrote:
> On Wed, Aug 31, 2011 at 6:00 PM, Dhaval Giani <dhaval.giani@gmail.com> wrote:
>> On Wed, Aug 31, 2011 at 10:58 AM, Blue Swirl <blauwirbel@gmail.com> wrote:
>>> On Wed, Aug 31, 2011 at 8:38 AM, Avi Kivity <avi@redhat.com> wrote:
>>>> On 08/26/2011 10:06 PM, Blue Swirl wrote:
>>>>>
>>>>> Let guests inject tracepoint data via fw_cfg device.
>>>>>
>>>>>
>>>>
>>>> At least on x86, fw_cfg is pretty slow, involving multiple exits.  IMO, for
>>>> kvm, even one exit per tracepoint is too high.  We need to use a shared
>>>> memory transport with a way to order guest/host events later on (by using a
>>>> clock).
>>>
>>> This could be an easy way, if the guest always had access to an
>>> accurate clock, but that may not be the case.
>>>
>>
>> From what I understand, kvmclock should be good enoguh for this
>> purpose. That is what I am using.
>
> It's only available for KVM on x86, that is most certainly not enough.
>

>From what I understood it is available on other architectures as well,
but let us just confirm with glommer.

Thanks!
Dhaval

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

* Re: [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough
  2011-09-03  9:26         ` Dhaval Giani
@ 2011-09-03 10:55           ` Blue Swirl
  0 siblings, 0 replies; 17+ messages in thread
From: Blue Swirl @ 2011-09-03 10:55 UTC (permalink / raw)
  To: Dhaval Giani
  Cc: qemu-devel, Glauber Costa, Lluís, Avi Kivity, Stefan Hajnoczi

On Sat, Sep 3, 2011 at 9:26 AM, Dhaval Giani <dhaval.giani@gmail.com> wrote:
> On Sat, Sep 3, 2011 at 1:53 AM, Blue Swirl <blauwirbel@gmail.com> wrote:
>> On Wed, Aug 31, 2011 at 6:00 PM, Dhaval Giani <dhaval.giani@gmail.com> wrote:
>>> On Wed, Aug 31, 2011 at 10:58 AM, Blue Swirl <blauwirbel@gmail.com> wrote:
>>>> On Wed, Aug 31, 2011 at 8:38 AM, Avi Kivity <avi@redhat.com> wrote:
>>>>> On 08/26/2011 10:06 PM, Blue Swirl wrote:
>>>>>>
>>>>>> Let guests inject tracepoint data via fw_cfg device.
>>>>>>
>>>>>>
>>>>>
>>>>> At least on x86, fw_cfg is pretty slow, involving multiple exits.  IMO, for
>>>>> kvm, even one exit per tracepoint is too high.  We need to use a shared
>>>>> memory transport with a way to order guest/host events later on (by using a
>>>>> clock).
>>>>
>>>> This could be an easy way, if the guest always had access to an
>>>> accurate clock, but that may not be the case.
>>>>
>>>
>>> From what I understand, kvmclock should be good enoguh for this
>>> purpose. That is what I am using.
>>
>> It's only available for KVM on x86, that is most certainly not enough.
>>
>
> From what I understood it is available on other architectures as well,
> but let us just confirm with glommer.

This line in Makefile.target limits the device to KVM on x86:
obj-i386-$(CONFIG_KVM) += kvmclock.o

Moreover, the code assumes that CPUState structure contains a field
cpuid_kvm_features but that is only available on x86.

Perhaps the device can be made generic but I don't see how it should
work with TCG. Actually I don't understand it at all, I think key
functionality must be inside KVM module.

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

end of thread, other threads:[~2011-09-03 10:56 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-26 19:06 [Qemu-devel] [PATCH, RFC] trace: implement guest tracepoint passthrough Blue Swirl
2011-08-29 12:17 ` Stefan Hajnoczi
2011-08-29 12:51   ` Lluís
2011-08-30 18:58     ` Blue Swirl
2011-08-30 18:43   ` Blue Swirl
2011-08-31  7:24     ` Stefan Hajnoczi
2011-08-31  8:38 ` Avi Kivity
2011-08-31  9:08   ` Stefan Hajnoczi
2011-08-31  9:11     ` Avi Kivity
2011-08-31 13:38       ` Stefan Hajnoczi
2011-08-31 18:01         ` Dhaval Giani
2011-08-31 10:54     ` Jan Kiszka
2011-08-31 17:58   ` Blue Swirl
2011-08-31 18:00     ` Dhaval Giani
2011-09-03  8:53       ` Blue Swirl
2011-09-03  9:26         ` Dhaval Giani
2011-09-03 10:55           ` Blue Swirl

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.