#include "hw/core/sysemu-cpu-ops.h"
#include "exec/address-spaces.h"
#endif
+#include "sysemu/cpus.h"
#include "sysemu/tcg.h"
-#include "sysemu/kvm.h"
-#include "sysemu/replay.h"
+#include "exec/replay-core.h"
#include "exec/cpu-common.h"
#include "exec/exec-all.h"
+#include "exec/tb-flush.h"
#include "exec/translate-all.h"
#include "exec/log.h"
#include "hw/core/accel-cpu.h"
#include "trace/trace-root.h"
#include "qemu/accel.h"
+#include "qemu/plugin.h"
uintptr_t qemu_host_page_size;
intptr_t qemu_host_page_mask;
vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
}
#endif
+
+ /* Call the plugin hook before clearing cpu->cpu_index in cpu_list_remove */
if (tcg_enabled()) {
- tcg_exec_unrealizefn(cpu);
+ qemu_plugin_vcpu_exit_hook(cpu);
}
cpu_list_remove(cpu);
+ /*
+ * Now that the vCPU has been removed from the RCU list, we can call
+ * tcg_exec_unrealizefn, which may free fields using call_rcu.
+ */
+ if (tcg_enabled()) {
+ tcg_exec_unrealizefn(cpu);
+ }
}
/*
return cpu_type;
}
-void list_cpus(const char *optarg)
+void list_cpus(void)
{
/* XXX: implement xxx_cpu_list for targets that still miss it */
#if defined(cpu_list)
}
#if defined(CONFIG_USER_ONLY)
-void tb_invalidate_phys_addr(target_ulong addr)
+void tb_invalidate_phys_addr(hwaddr addr)
{
mmap_lock();
tb_invalidate_phys_page(addr);
}
#endif
-/* Add a breakpoint. */
-int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags,
- CPUBreakpoint **breakpoint)
-{
- CPUClass *cc = CPU_GET_CLASS(cpu);
- CPUBreakpoint *bp;
-
- if (cc->gdb_adjust_breakpoint) {
- pc = cc->gdb_adjust_breakpoint(cpu, pc);
- }
-
- bp = g_malloc(sizeof(*bp));
-
- bp->pc = pc;
- bp->flags = flags;
-
- /* keep all GDB-injected breakpoints in front */
- if (flags & BP_GDB) {
- QTAILQ_INSERT_HEAD(&cpu->breakpoints, bp, entry);
- } else {
- QTAILQ_INSERT_TAIL(&cpu->breakpoints, bp, entry);
- }
-
- if (breakpoint) {
- *breakpoint = bp;
- }
-
- trace_breakpoint_insert(cpu->cpu_index, pc, flags);
- return 0;
-}
-
-/* Remove a specific breakpoint. */
-int cpu_breakpoint_remove(CPUState *cpu, vaddr pc, int flags)
-{
- CPUClass *cc = CPU_GET_CLASS(cpu);
- CPUBreakpoint *bp;
-
- if (cc->gdb_adjust_breakpoint) {
- pc = cc->gdb_adjust_breakpoint(cpu, pc);
- }
-
- QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
- if (bp->pc == pc && bp->flags == flags) {
- cpu_breakpoint_remove_by_ref(cpu, bp);
- return 0;
- }
- }
- return -ENOENT;
-}
-
-/* Remove a specific breakpoint by reference. */
-void cpu_breakpoint_remove_by_ref(CPUState *cpu, CPUBreakpoint *bp)
-{
- QTAILQ_REMOVE(&cpu->breakpoints, bp, entry);
-
- trace_breakpoint_remove(cpu->cpu_index, bp->pc, bp->flags);
- g_free(bp);
-}
-
-/* Remove all matching breakpoints. */
-void cpu_breakpoint_remove_all(CPUState *cpu, int mask)
-{
- CPUBreakpoint *bp, *next;
-
- QTAILQ_FOREACH_SAFE(bp, &cpu->breakpoints, entry, next) {
- if (bp->flags & mask) {
- cpu_breakpoint_remove_by_ref(cpu, bp);
- }
- }
-}
-
/* enable or disable single step mode. EXCP_DEBUG is returned by the
CPU loop after each instruction */
void cpu_single_step(CPUState *cpu, int enabled)
{
if (cpu->singlestep_enabled != enabled) {
cpu->singlestep_enabled = enabled;
- if (kvm_enabled()) {
- kvm_update_guest_debug(cpu, 0);
+
+#if !defined(CONFIG_USER_ONLY)
+ const AccelOpsClass *ops = cpus_get_accel();
+ if (ops->update_guest_debug) {
+ ops->update_guest_debug(cpu);
}
+#endif
+
trace_breakpoint_singlestep(cpu->cpu_index, enabled);
}
}
#endif
}
+const char *target_name(void)
+{
+ return TARGET_NAME;
+}
+
void page_size_init(void)
{
/* NOTE: we can always suppose that qemu_host_page_size >=