api-system.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * QEMU Plugin API - System specific implementations
  3. *
  4. * This provides the APIs that have a specific system implementation
  5. * or are only relevant to system-mode.
  6. *
  7. * Copyright (C) 2017, Emilio G. Cota <cota@braap.org>
  8. * Copyright (C) 2019-2025, Linaro
  9. *
  10. * SPDX-License-Identifier: GPL-2.0-or-later
  11. */
  12. #include "qemu/osdep.h"
  13. #include "qemu/main-loop.h"
  14. #include "qapi/error.h"
  15. #include "migration/blocker.h"
  16. #include "hw/boards.h"
  17. #include "qemu/plugin-memory.h"
  18. #include "qemu/plugin.h"
  19. /*
  20. * In system mode we cannot trace the binary being executed so the
  21. * helpers all return NULL/0.
  22. */
  23. const char *qemu_plugin_path_to_binary(void)
  24. {
  25. return NULL;
  26. }
  27. uint64_t qemu_plugin_start_code(void)
  28. {
  29. return 0;
  30. }
  31. uint64_t qemu_plugin_end_code(void)
  32. {
  33. return 0;
  34. }
  35. uint64_t qemu_plugin_entry_code(void)
  36. {
  37. return 0;
  38. }
  39. /*
  40. * Virtual Memory queries
  41. */
  42. static __thread struct qemu_plugin_hwaddr hwaddr_info;
  43. struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
  44. uint64_t vaddr)
  45. {
  46. CPUState *cpu = current_cpu;
  47. unsigned int mmu_idx = get_mmuidx(info);
  48. enum qemu_plugin_mem_rw rw = get_plugin_meminfo_rw(info);
  49. hwaddr_info.is_store = (rw & QEMU_PLUGIN_MEM_W) != 0;
  50. assert(mmu_idx < NB_MMU_MODES);
  51. if (!tlb_plugin_lookup(cpu, vaddr, mmu_idx,
  52. hwaddr_info.is_store, &hwaddr_info)) {
  53. error_report("invalid use of qemu_plugin_get_hwaddr");
  54. return NULL;
  55. }
  56. return &hwaddr_info;
  57. }
  58. bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr)
  59. {
  60. return haddr->is_io;
  61. }
  62. uint64_t qemu_plugin_hwaddr_phys_addr(const struct qemu_plugin_hwaddr *haddr)
  63. {
  64. if (haddr) {
  65. return haddr->phys_addr;
  66. }
  67. return 0;
  68. }
  69. const char *qemu_plugin_hwaddr_device_name(const struct qemu_plugin_hwaddr *h)
  70. {
  71. if (h && h->is_io) {
  72. MemoryRegion *mr = h->mr;
  73. if (!mr->name) {
  74. unsigned maddr = (uintptr_t)mr;
  75. g_autofree char *temp = g_strdup_printf("anon%08x", maddr);
  76. return g_intern_string(temp);
  77. } else {
  78. return g_intern_string(mr->name);
  79. }
  80. } else {
  81. return g_intern_static_string("RAM");
  82. }
  83. }
  84. /*
  85. * Time control
  86. */
  87. static bool has_control;
  88. static Error *migration_blocker;
  89. const void *qemu_plugin_request_time_control(void)
  90. {
  91. if (!has_control) {
  92. has_control = true;
  93. error_setg(&migration_blocker,
  94. "TCG plugin time control does not support migration");
  95. migrate_add_blocker(&migration_blocker, NULL);
  96. return &has_control;
  97. }
  98. return NULL;
  99. }
  100. static void advance_virtual_time__async(CPUState *cpu, run_on_cpu_data data)
  101. {
  102. int64_t new_time = data.host_ulong;
  103. qemu_clock_advance_virtual_time(new_time);
  104. }
  105. void qemu_plugin_update_ns(const void *handle, int64_t new_time)
  106. {
  107. if (handle == &has_control) {
  108. /* Need to execute out of cpu_exec, so bql can be locked. */
  109. async_run_on_cpu(current_cpu,
  110. advance_virtual_time__async,
  111. RUN_ON_CPU_HOST_ULONG(new_time));
  112. }
  113. }