From 4eb9b16786e5002c4c10ac65ff4ad9b590df73a8 Mon Sep 17 00:00:00 2001 Message-Id: From: Blue Swirl 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 --- 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-" +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-" +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 +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 <