X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=cpu.c;h=1c948d1161d2468ab09c142e55fdc8fd805a4ce9;hb=7d1d6a0c1996963c50dfc62e037284225d985d59;hp=2a09b05205dd76696a440c955dc7c5b8cbbba09e;hpb=344744e148e6e865f5a57e745b02a87e5ea534ad;p=mirror_qemu.git diff --git a/cpu.c b/cpu.c index 2a09b05205..1c948d1161 100644 --- a/cpu.c +++ b/cpu.c @@ -31,16 +31,18 @@ #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; @@ -134,15 +136,23 @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp) /* cache the cpu class for the hotpath */ cpu->cc = CPU_GET_CLASS(cpu); - cpu_list_add(cpu); if (!accel_cpu_realizefn(cpu, errp)) { return; } + /* NB: errp parameter is unused currently */ if (tcg_enabled()) { tcg_exec_realizefn(cpu, errp); } + /* Wait until cpu initialization complete before exposing cpu. */ + cpu_list_add(cpu); + + /* Plugin initialization must wait until cpu_index assigned. */ + if (tcg_enabled()) { + qemu_plugin_vcpu_init_hook(cpu); + } + #ifdef CONFIG_USER_ONLY assert(qdev_get_vmsd(DEVICE(cpu)) == NULL || qdev_get_vmsd(DEVICE(cpu))->unmigratable); @@ -168,11 +178,20 @@ void cpu_exec_unrealizefn(CPUState *cpu) 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); + } } /* @@ -265,7 +284,7 @@ const char *parse_cpu_option(const char *cpu_option) 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) @@ -274,7 +293,7 @@ void list_cpus(const char *optarg) } #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); @@ -302,86 +321,20 @@ void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs) } #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); } } @@ -474,6 +427,11 @@ bool target_words_bigendian(void) #endif } +const char *target_name(void) +{ + return TARGET_NAME; +} + void page_size_init(void) { /* NOTE: we can always suppose that qemu_host_page_size >=