qemu/plugins/api-system.c
<<
>>
Prefs
   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
  13#include "qemu/osdep.h"
  14#include "qemu/main-loop.h"
  15#include "qapi/error.h"
  16#include "migration/blocker.h"
  17#include "hw/boards.h"
  18#include "qemu/plugin-memory.h"
  19#include "qemu/plugin.h"
  20
  21/*
  22 * In system mode we cannot trace the binary being executed so the
  23 * helpers all return NULL/0.
  24 */
  25const char *qemu_plugin_path_to_binary(void)
  26{
  27    return NULL;
  28}
  29
  30uint64_t qemu_plugin_start_code(void)
  31{
  32    return 0;
  33}
  34
  35uint64_t qemu_plugin_end_code(void)
  36{
  37    return 0;
  38}
  39
  40uint64_t qemu_plugin_entry_code(void)
  41{
  42    return 0;
  43}
  44
  45/*
  46 * Virtual Memory queries
  47 */
  48
  49static __thread struct qemu_plugin_hwaddr hwaddr_info;
  50
  51struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
  52                                                  uint64_t vaddr)
  53{
  54    CPUState *cpu = current_cpu;
  55    unsigned int mmu_idx = get_mmuidx(info);
  56    enum qemu_plugin_mem_rw rw = get_plugin_meminfo_rw(info);
  57    hwaddr_info.is_store = (rw & QEMU_PLUGIN_MEM_W) != 0;
  58
  59    assert(mmu_idx < NB_MMU_MODES);
  60
  61    if (!tlb_plugin_lookup(cpu, vaddr, mmu_idx,
  62                           hwaddr_info.is_store, &hwaddr_info)) {
  63        error_report("invalid use of qemu_plugin_get_hwaddr");
  64        return NULL;
  65    }
  66
  67    return &hwaddr_info;
  68}
  69
  70bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr)
  71{
  72    return haddr->is_io;
  73}
  74
  75uint64_t qemu_plugin_hwaddr_phys_addr(const struct qemu_plugin_hwaddr *haddr)
  76{
  77    if (haddr) {
  78        return haddr->phys_addr;
  79    }
  80    return 0;
  81}
  82
  83const char *qemu_plugin_hwaddr_device_name(const struct qemu_plugin_hwaddr *h)
  84{
  85    if (h && h->is_io) {
  86        MemoryRegion *mr = h->mr;
  87        if (!mr->name) {
  88            unsigned maddr = (uintptr_t)mr;
  89            g_autofree char *temp = g_strdup_printf("anon%08x", maddr);
  90            return g_intern_string(temp);
  91        } else {
  92            return g_intern_string(mr->name);
  93        }
  94    } else {
  95        return g_intern_static_string("RAM");
  96    }
  97}
  98
  99/*
 100 * Time control
 101 */
 102static bool has_control;
 103static Error *migration_blocker;
 104
 105const void *qemu_plugin_request_time_control(void)
 106{
 107    if (!has_control) {
 108        has_control = true;
 109        error_setg(&migration_blocker,
 110                   "TCG plugin time control does not support migration");
 111        migrate_add_blocker(&migration_blocker, NULL);
 112        return &has_control;
 113    }
 114    return NULL;
 115}
 116
 117static void advance_virtual_time__async(CPUState *cpu, run_on_cpu_data data)
 118{
 119    int64_t new_time = data.host_ulong;
 120    qemu_clock_advance_virtual_time(new_time);
 121}
 122
 123void qemu_plugin_update_ns(const void *handle, int64_t new_time)
 124{
 125    if (handle == &has_control) {
 126        /* Need to execute out of cpu_exec, so bql can be locked. */
 127        async_run_on_cpu(current_cpu,
 128                         advance_virtual_time__async,
 129                         RUN_ON_CPU_HOST_ULONG(new_time));
 130    }
 131}
 132