2
0

control-target.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Interface for configuring and controlling the state of tracing events.
  3. *
  4. * Copyright (C) 2014-2016 Lluís Vilanova <vilanova@ac.upc.edu>
  5. *
  6. * This work is licensed under the terms of the GNU GPL, version 2 or later.
  7. * See the COPYING file in the top-level directory.
  8. */
  9. #include "qemu/osdep.h"
  10. #include "cpu.h"
  11. #include "trace-root.h"
  12. #include "trace/control.h"
  13. #include "translate-all.h"
  14. void trace_event_set_state_dynamic_init(TraceEvent *ev, bool state)
  15. {
  16. bool state_pre;
  17. assert(trace_event_get_state_static(ev));
  18. /*
  19. * We ignore the "vcpu" property here, since no vCPUs have been created
  20. * yet. Then dstate can only be 1 or 0.
  21. */
  22. state_pre = *ev->dstate;
  23. if (state_pre != state) {
  24. if (state) {
  25. trace_events_enabled_count++;
  26. *ev->dstate = 1;
  27. } else {
  28. trace_events_enabled_count--;
  29. *ev->dstate = 0;
  30. }
  31. }
  32. }
  33. void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
  34. {
  35. CPUState *vcpu;
  36. assert(trace_event_get_state_static(ev));
  37. if (trace_event_is_vcpu(ev)) {
  38. CPU_FOREACH(vcpu) {
  39. trace_event_set_vcpu_state_dynamic(vcpu, ev, state);
  40. }
  41. } else {
  42. /* Without the "vcpu" property, dstate can only be 1 or 0 */
  43. bool state_pre = *ev->dstate;
  44. if (state_pre != state) {
  45. if (state) {
  46. trace_events_enabled_count++;
  47. *ev->dstate = 1;
  48. } else {
  49. trace_events_enabled_count--;
  50. *ev->dstate = 0;
  51. }
  52. }
  53. }
  54. }
  55. void trace_event_set_vcpu_state_dynamic(CPUState *vcpu,
  56. TraceEvent *ev, bool state)
  57. {
  58. uint32_t vcpu_id;
  59. bool state_pre;
  60. assert(trace_event_get_state_static(ev));
  61. assert(trace_event_is_vcpu(ev));
  62. vcpu_id = trace_event_get_vcpu_id(ev);
  63. state_pre = test_bit(vcpu_id, vcpu->trace_dstate);
  64. if (state_pre != state) {
  65. if (state) {
  66. trace_events_enabled_count++;
  67. set_bit(vcpu_id, vcpu->trace_dstate);
  68. (*ev->dstate)++;
  69. } else {
  70. trace_events_enabled_count--;
  71. clear_bit(vcpu_id, vcpu->trace_dstate);
  72. (*ev->dstate)--;
  73. }
  74. }
  75. }
  76. static bool adding_first_cpu1(void)
  77. {
  78. CPUState *cpu;
  79. size_t count = 0;
  80. CPU_FOREACH(cpu) {
  81. count++;
  82. if (count > 1) {
  83. return false;
  84. }
  85. }
  86. return true;
  87. }
  88. static bool adding_first_cpu(void)
  89. {
  90. bool res;
  91. cpu_list_lock();
  92. res = adding_first_cpu1();
  93. cpu_list_unlock();
  94. return res;
  95. }
  96. void trace_init_vcpu(CPUState *vcpu)
  97. {
  98. TraceEventIter iter;
  99. TraceEvent *ev;
  100. trace_event_iter_init(&iter, NULL);
  101. while ((ev = trace_event_iter_next(&iter)) != NULL) {
  102. if (trace_event_is_vcpu(ev) &&
  103. trace_event_get_state_static(ev) &&
  104. trace_event_get_state_dynamic(ev)) {
  105. if (adding_first_cpu()) {
  106. /* check preconditions */
  107. assert(*ev->dstate == 1);
  108. /* disable early-init state ... */
  109. *ev->dstate = 0;
  110. trace_events_enabled_count--;
  111. /* ... and properly re-enable */
  112. trace_event_set_vcpu_state_dynamic(vcpu, ev, true);
  113. } else {
  114. trace_event_set_vcpu_state_dynamic(vcpu, ev, true);
  115. }
  116. }
  117. }
  118. trace_guest_cpu_enter(vcpu);
  119. }