diff --git a/bsd-user/main.c b/bsd-user/main.c index 0fb08e405d5f976929a33c3a330de97a782659e1..f58bb435795262f6dc53104aa914400bbd08cba2 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -1133,7 +1133,6 @@ int main(int argc, char **argv) gdbserver_start (gdbstub_port); gdb_handlesig(cpu, 0); } - trace_init_vcpu_events(); cpu_loop(env); /* never exits */ return 0; diff --git a/linux-user/main.c b/linux-user/main.c index 8daebe076705e5292957ce4d75ee75129a226a31..424f2b6f7b8343b4d5d2da976ee61ad710d95d70 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -4800,7 +4800,6 @@ int main(int argc, char **argv, char **envp) } 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 f783b5a6bd68e45d8fd00b5ee437d8b829e3c97a..f87fffabd12e3c93ed702948bcb83387f6d8d6de 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -333,6 +333,9 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp) 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 2dfcd9fb2bd706c07d2c51d89961e6f945675343..f765a02018890c8df5996232ce9b6dcead23fc4c 100644 --- a/stubs/trace-control.c +++ b/stubs/trace-control.c @@ -44,3 +44,9 @@ void trace_event_set_vcpu_state_dynamic(CPUState *vcpu, /* 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/control-target.c b/trace/control-target.c index 72081e2a34f7df1b5a8e2bba495bba0c1957b831..3b7d99b44cf831815be88abb0d825484356939c5 100644 --- a/trace/control-target.c +++ b/trace/control-target.c @@ -81,3 +81,40 @@ void trace_event_set_vcpu_state_dynamic(CPUState *vcpu, } } } + +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); + } + } + } +} diff --git a/trace/control.c b/trace/control.c index 05d85accbd7c82b9bae1a638796704600d906857..10b3e9babad6365636c0ec4747a666eaa1ee8a65 100644 --- a/trace/control.c +++ b/trace/control.c @@ -269,22 +269,3 @@ char *trace_opt_parse(const char *optarg) 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 27a16fc955704c6ce91486819b6d9d39418056e6..a22d11242e0fb211c36ac9135b9d66ad77b70391 100644 --- a/trace/control.h +++ b/trace/control.h @@ -238,6 +238,14 @@ bool trace_init_backends(void); */ 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: * @@ -269,17 +277,6 @@ extern QemuOptsList qemu_trace_opts; */ 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/vl.c b/vl.c index eafda8d737310db0efe2dd91926877183d27f94a..04fc1725f3293950ed585847c94b0a28c30444d5 100644 --- a/vl.c +++ b/vl.c @@ -4658,7 +4658,6 @@ int main(int argc, char **argv, char **envp) os_setup_post(); - trace_init_vcpu_events(); main_loop(); replay_disable_events(); iothread_stop_all();