Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' into staging

# gpg: Signature made Wed 28 Sep 2016 22:30:45 BST
# gpg:                using RSA key 0x9CA4ABB381AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"
# Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35  775A 9CA4 ABB3 81AB 73C8

* remotes/stefanha/tags/tracing-pull-request:
  trace: Document the execution mode of guest events
  trace: Add event "guest_cpu_reset"
  trace: Add event "guest_cpu_enter"
  trace: Properly initialize dynamic event states in hot-plugged vCPUs
  trace: move hw/virtio/virtio-balloon.c trace points into correct file
  trace: move hw/mem/pc-dimm.c trace points into correct file
  trace: move util/qemu-coroutine*.c trace points into correct file
  trace: move util/buffer.c trace points into correct file

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/Makefile.objs b/Makefile.objs
index a8e0224..02fb8e7 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -142,6 +142,7 @@
 trace-events-y += hw/sparc/trace-events
 trace-events-y += hw/sd/trace-events
 trace-events-y += hw/isa/trace-events
+trace-events-y += hw/mem/trace-events
 trace-events-y += hw/i386/trace-events
 trace-events-y += hw/9pfs/trace-events
 trace-events-y += hw/ppc/trace-events
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 35125b7..d803d3e 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -1116,7 +1116,6 @@
         gdbserver_start (gdbstub_port);
         gdb_handlesig(cpu, 0);
     }
-    trace_init_vcpu_events();
     cpu_loop(env);
     /* never exits */
     return 0;
diff --git a/hw/i386/trace-events b/hw/i386/trace-events
index 1938b98..d2b4973 100644
--- a/hw/i386/trace-events
+++ b/hw/i386/trace-events
@@ -7,10 +7,6 @@
 xen_pv_mmio_read(uint64_t addr) "WARNING: read from Xen PV Device MMIO space (address %"PRIx64")"
 xen_pv_mmio_write(uint64_t addr) "WARNING: write to Xen PV Device MMIO space (address %"PRIx64")"
 
-# hw/i386/pc.c
-mhp_pc_dimm_assigned_slot(int slot) "%d"
-mhp_pc_dimm_assigned_address(uint64_t addr) "0x%"PRIx64
-
 # hw/i386/x86-iommu.c
 x86_iommu_iec_notify(bool global, uint32_t index, uint32_t mask) "Notify IEC invalidation: global=%d index=%" PRIu32 " mask=%" PRIu32
 
diff --git a/hw/mem/trace-events b/hw/mem/trace-events
new file mode 100644
index 0000000..323c3c1
--- /dev/null
+++ b/hw/mem/trace-events
@@ -0,0 +1,5 @@
+# See docs/trace-events.txt for syntax documentation.
+
+# hw/mem/pc-dimm.c
+mhp_pc_dimm_assigned_slot(int slot) "%d"
+mhp_pc_dimm_assigned_address(uint64_t addr) "0x%"PRIx64
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 55184d3..8756cef 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -14,3 +14,8 @@
 virtio_rng_pushed(void *rng, size_t len) "rng %p: %zd bytes pushed"
 virtio_rng_request(void *rng, size_t size, unsigned quota) "rng %p: %zd bytes requested, %u bytes quota left"
 
+# hw/virtio/virtio-balloon.c
+virtio_balloon_handle_output(const char *name, uint64_t gpa) "section name: %s gpa: %"PRIx64
+virtio_balloon_get_config(uint32_t num_pages, uint32_t actual) "num_pages: %d actual: %d"
+virtio_balloon_set_config(uint32_t actual, uint32_t oldactual) "actual: %d oldactual: %d"
+virtio_balloon_to_target(uint64_t target, uint32_t num_pages) "balloon target: %"PRIx64" num_pages: %d"
diff --git a/io/trace-events b/io/trace-events
index d064665..e31b596 100644
--- a/io/trace-events
+++ b/io/trace-events
@@ -1,11 +1,5 @@
 # See docs/tracing.txt for syntax documentation.
 
-# io/buffer.c
-buffer_resize(const char *buf, size_t olen, size_t len) "%s: old %zd, new %zd"
-buffer_move_empty(const char *buf, size_t len, const char *from) "%s: %zd bytes from %s"
-buffer_move(const char *buf, size_t len, const char *from) "%s: %zd bytes from %s"
-buffer_free(const char *buf, size_t len) "%s: capacity %zd"
-
 # io/task.c
 qio_task_new(void *task, void *source, void *func, void *opaque) "Task new task=%p source=%p func=%p opaque=%p"
 qio_task_complete(void *task) "Task complete task=%p"
diff --git a/linux-user/main.c b/linux-user/main.c
index c8f8573..9e4b430 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -4748,7 +4748,6 @@
         }
         gdb_handlesig(cpu, 0);
     }
-    trace_init_vcpu_events();
     cpu_loop(env);
     /* never exits */
     return 0;
diff --git a/qom/cpu.c b/qom/cpu.c
index f783b5a..484c493 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -29,6 +29,7 @@
 #include "qemu/error-report.h"
 #include "sysemu/sysemu.h"
 #include "hw/qdev-properties.h"
+#include "trace.h"
 
 bool cpu_exists(int64_t id)
 {
@@ -245,6 +246,8 @@
     if (klass->reset != NULL) {
         (*klass->reset)(cpu);
     }
+
+    trace_guest_cpu_reset(cpu);
 }
 
 static void cpu_common_reset(CPUState *cpu)
@@ -333,6 +336,9 @@
         cpu_synchronize_post_init(cpu);
         cpu_resume(cpu);
     }
+
+    /* NOTE: latest generic point where the cpu is fully realized */
+    trace_init_vcpu(cpu);
 }
 
 static void cpu_common_initfn(Object *obj)
diff --git a/stubs/trace-control.c b/stubs/trace-control.c
index 2dfcd9f..f765a02 100644
--- a/stubs/trace-control.c
+++ b/stubs/trace-control.c
@@ -44,3 +44,9 @@
     /* should never be called on non-target binaries */
     abort();
 }
+
+void trace_init_vcpu(CPUState *vcpu)
+{
+    /* should never be called on non-target binaries */
+    abort();
+}
diff --git a/trace-events b/trace-events
index 1cb9d37..1a4e092 100644
--- a/trace-events
+++ b/trace-events
@@ -37,10 +37,6 @@
 # balloon.c
 # Since requests are raised via monitor, not many tracepoints are needed.
 balloon_event(void *opaque, unsigned long addr) "opaque %p addr %lu"
-virtio_balloon_handle_output(const char *name, uint64_t gpa) "section name: %s gpa: %"PRIx64
-virtio_balloon_get_config(uint32_t num_pages, uint32_t actual) "num_pages: %d actual: %d"
-virtio_balloon_set_config(uint32_t actual, uint32_t oldactual) "actual: %d oldactual: %d"
-virtio_balloon_to_target(uint64_t target, uint32_t num_pages) "balloon target: %"PRIx64" num_pages: %d"
 
 # vl.c
 vm_state_notify(int running, int reason) "running %d reason %d"
@@ -83,19 +79,6 @@
 xen_remap_bucket(uint64_t index) "index %#"PRIx64
 xen_map_cache_return(void* ptr) "%p"
 
-# qemu-coroutine.c
-qemu_coroutine_enter(void *from, void *to, void *opaque) "from %p to %p opaque %p"
-qemu_coroutine_yield(void *from, void *to) "from %p to %p"
-qemu_coroutine_terminate(void *co) "self %p"
-
-# qemu-coroutine-lock.c
-qemu_co_queue_run_restart(void *co) "co %p"
-qemu_co_queue_next(void *nxt) "next %p"
-qemu_co_mutex_lock_entry(void *mutex, void *self) "mutex %p self %p"
-qemu_co_mutex_lock_return(void *mutex, void *self) "mutex %p self %p"
-qemu_co_mutex_unlock_entry(void *mutex, void *self) "mutex %p self %p"
-qemu_co_mutex_unlock_return(void *mutex, void *self) "mutex %p self %p"
-
 # monitor.c
 handle_qmp_command(void *mon, const char *cmd_name) "mon %p cmd_name \"%s\""
 monitor_protocol_event_handler(uint32_t event, void *qdict) "event=%d data=%p"
@@ -157,6 +140,19 @@
 
 ### Guest events, keep at bottom
 
+
+## vCPU
+
+# Hot-plug a new virtual (guest) CPU
+#
+# Targets: all
+vcpu guest_cpu_enter(void)
+
+# Reset the state of a virtual (guest) CPU
+#
+# Targets: all
+vcpu guest_cpu_reset(void)
+
 # @vaddr: Access' virtual address.
 # @info : Access' information (see below).
 #
@@ -173,6 +169,7 @@
 #     bool    store      : 1; /* wheter it's a store operation */
 # };
 #
+# Mode: user, softmmu
 # Targets: TCG(all)
 disable vcpu tcg guest_mem_before(TCGv vaddr, uint8_t info) "info=%d", "vaddr=0x%016"PRIx64" info=%d"
 
@@ -181,6 +178,7 @@
 #
 # Start executing a guest system call in syscall emulation mode.
 #
+# Mode: user
 # Targets: TCG(all)
 disable vcpu guest_user_syscall(uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8) "num=0x%016"PRIx64" arg1=0x%016"PRIx64" arg2=0x%016"PRIx64" arg3=0x%016"PRIx64" arg4=0x%016"PRIx64" arg5=0x%016"PRIx64" arg6=0x%016"PRIx64" arg7=0x%016"PRIx64" arg8=0x%016"PRIx64
 
@@ -189,5 +187,6 @@
 #
 # Finish executing a guest system call in syscall emulation mode.
 #
+# Mode: user
 # Targets: TCG(all)
 disable vcpu guest_user_syscall_ret(uint64_t num, uint64_t ret) "num=0x%016"PRIx64" ret=0x%016"PRIx64
diff --git a/trace/control-target.c b/trace/control-target.c
index 72081e2..52fcce5 100644
--- a/trace/control-target.c
+++ b/trace/control-target.c
@@ -9,6 +9,7 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
+#include "trace.h"
 #include "trace/control.h"
 #include "translate-all.h"
 
@@ -81,3 +82,42 @@
         }
     }
 }
+
+static bool adding_first_cpu(void)
+{
+    CPUState *cpu;
+    size_t count = 0;
+    CPU_FOREACH(cpu) {
+        count++;
+        if (count > 1) {
+            return false;
+        }
+    }
+    return true;
+}
+
+void trace_init_vcpu(CPUState *vcpu)
+{
+    TraceEvent *ev = NULL;
+
+    while ((ev = trace_event_pattern("*", ev)) != NULL) {
+        if (trace_event_is_vcpu(ev) &&
+            trace_event_get_state_static(ev) &&
+            trace_event_get_state_dynamic(ev)) {
+            TraceEventID id = trace_event_get_id(ev);
+            if (adding_first_cpu()) {
+                /* check preconditions */
+                assert(trace_events_dstate[id] == 1);
+                /* disable early-init state ... */
+                trace_events_dstate[id] = 0;
+                trace_events_enabled_count--;
+                /* ... and properly re-enable */
+                trace_event_set_vcpu_state_dynamic(vcpu, ev, true);
+            } else {
+                trace_event_set_vcpu_state_dynamic(vcpu, ev, true);
+            }
+        }
+    }
+
+    trace_guest_cpu_enter(vcpu);
+}
diff --git a/trace/control.c b/trace/control.c
index 05d85ac..10b3e9b 100644
--- a/trace/control.c
+++ b/trace/control.c
@@ -269,22 +269,3 @@
 
     return trace_file;
 }
-
-void trace_init_vcpu_events(void)
-{
-    TraceEvent *ev = NULL;
-    while ((ev = trace_event_pattern("*", ev)) != NULL) {
-        if (trace_event_is_vcpu(ev) &&
-            trace_event_get_state_static(ev) &&
-            trace_event_get_state_dynamic(ev)) {
-            TraceEventID id = trace_event_get_id(ev);
-            /* check preconditions */
-            assert(trace_events_dstate[id] == 1);
-            /* disable early-init state ... */
-            trace_events_dstate[id] = 0;
-            trace_events_enabled_count--;
-            /* ... and properly re-enable */
-            trace_event_set_state_dynamic(ev, true);
-        }
-    }
-}
diff --git a/trace/control.h b/trace/control.h
index 27a16fc..a22d112 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -239,6 +239,14 @@
 void trace_init_file(const char *file);
 
 /**
+ * trace_init_vcpu:
+ * @vcpu: Added vCPU.
+ *
+ * Set initial dynamic event state for a hot-plugged vCPU.
+ */
+void trace_init_vcpu(CPUState *vcpu);
+
+/**
  * trace_list_events:
  *
  * List all available events.
@@ -269,17 +277,6 @@
  */
 char *trace_opt_parse(const char *optarg);
 
-/**
- * trace_init_vcpu_events:
- *
- * Re-synchronize initial event state with vCPUs (which can be created after
- * trace_init_events()).
- *
- * Precondition: event states won't be changed between trace_enable_events() and
- * trace_init_vcpu_events() (e.g., through QMP).
- */
-void trace_init_vcpu_events(void);
-
 
 #include "trace/control-internal.h"
 
diff --git a/util/trace-events b/util/trace-events
index 747e6ba..ed06aee 100644
--- a/util/trace-events
+++ b/util/trace-events
@@ -1,5 +1,24 @@
 # See docs/tracing.txt for syntax documentation.
 
+# util/buffer.c
+buffer_resize(const char *buf, size_t olen, size_t len) "%s: old %zd, new %zd"
+buffer_move_empty(const char *buf, size_t len, const char *from) "%s: %zd bytes from %s"
+buffer_move(const char *buf, size_t len, const char *from) "%s: %zd bytes from %s"
+buffer_free(const char *buf, size_t len) "%s: capacity %zd"
+
+# util/qemu-coroutine.c
+qemu_coroutine_enter(void *from, void *to, void *opaque) "from %p to %p opaque %p"
+qemu_coroutine_yield(void *from, void *to) "from %p to %p"
+qemu_coroutine_terminate(void *co) "self %p"
+
+# util/qemu-coroutine-lock.c
+qemu_co_queue_run_restart(void *co) "co %p"
+qemu_co_queue_next(void *nxt) "next %p"
+qemu_co_mutex_lock_entry(void *mutex, void *self) "mutex %p self %p"
+qemu_co_mutex_lock_return(void *mutex, void *self) "mutex %p self %p"
+qemu_co_mutex_unlock_entry(void *mutex, void *self) "mutex %p self %p"
+qemu_co_mutex_unlock_return(void *mutex, void *self) "mutex %p self %p"
+
 # util/oslib-win32.c
 # util/oslib-posix.c
 qemu_memalign(size_t alignment, size_t size, void *ptr) "alignment %zu size %zu ptr %p"
diff --git a/vl.c b/vl.c
index ab0349b..f3abd99 100644
--- a/vl.c
+++ b/vl.c
@@ -4660,7 +4660,6 @@
 
     os_setup_post();
 
-    trace_init_vcpu_events();
     main_loop();
     replay_disable_events();
     iothread_stop_all();