mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'accel-cpus-20250309' of https://github.com/philmd/qemu into staging
Generic CPUs / accelerators patch queue - Reduce "exec/tb-flush.h" inclusion on linux-user - Consider alignment in bsd-user's mmap_find_vma() - Unify MMAP common user emulation API - Simplify cpu-target.c further - Prefer cached CpuClass over CPU_GET_CLASS() macro - Restrict CPU has_work() handlers to system emulation - Consolidate core exec/vCPU section in MAINTAINERS # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmfN1NgACgkQ4+MsLN6t # wN6BghAAr5WBteo7OiNRyTA0Ilg+nOcTf6Re08CgWf/3TIMljEPq8o/tLQOxiFke # AMktDlvYTyg4BWa5UdAKLpj7N7eyHcXrqv95A6Lg/xoGdlbqfYIpyX7/5h0pV70f # z8WUj2/YMpoyXxvvAjw4YtUqHIWZhSTIBsFqJ6jALl6T7fouo8y++AWn/L+zY4tO # /qqC6djJwufphPJWm2NvG+nvf+T60C+4JUc8CkjYQsyL3K3HpoAgzrgb/6VRtHob # nKfORPboKEVSE1Z52GnmM9eMsZjbWOz9bkEN69yfRbHHQNuvsicok+V59PnWWDYd # JX6cC5ukJUJlgYDKOj2jCg9OouoV4mRYRqYYWPtE8WkGLoeJu4mV1AEkVB7h3lTA # BtUu4ohsrk/krfyB89apu8SqDPya6F4TDqJpGmAqlAG2UWJwrECuJV82uTDZql0R # MqnCUYb7OQBkdb9CoqFi47jTYlqgdVLKekS8udXLCaqWggki8Nb1GVQ09LFyv3NF # JlQVNNQG3D2V7JIDd2aXgr4PmhmV2oPv+HYxW+SPxU2qDHIU93krkKyi0TRk0mSC # sWvJYBJcwbXlnMD5clad1bTLZrK5Csl5WkX8I0d0feqeRPSXC2YBTwL2/GgzT8qF # n/2dxB3Lf+1LUl6KAv3kT9lONtqic0J9oBBcPUjVog2ikAD7+Vo= # =TZua # -----END PGP SIGNATURE----- # gpg: Signature made Mon 10 Mar 2025 01:50:16 HKT # gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE # gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full] # Primary key fingerprint: FAAB E75E 1291 7221 DCFD 6BB2 E3E3 2C2C DEAD C0DE * tag 'accel-cpus-20250309' of https://github.com/philmd/qemu: (38 commits) MAINTAINERS: Consolidate core exec/vCPU handling section cpus: Remove CPUClass::has_work() handler target/xtensa: Move has_work() from CPUClass to SysemuCPUOps target/tricore: Move has_work() from CPUClass to SysemuCPUOps target/sparc: Move has_work() from CPUClass to SysemuCPUOps target/sh4: Move has_work() from CPUClass to SysemuCPUOps target/s390x: Move has_work() from CPUClass to SysemuCPUOps target/s390x: Restrict I/O handler installers to system emulation target/rx: Move has_work() from CPUClass to SysemuCPUOps target/riscv: Move has_work() from CPUClass to SysemuCPUOps target/ppc: Move has_work() from CPUClass to SysemuCPUOps target/openrisc: Move has_work() from CPUClass to SysemuCPUOps target/mips: Move has_work() from CPUClass to SysemuCPUOps target/microblaze: Move has_work() from CPUClass to SysemuCPUOps target/m68k: Move has_work() from CPUClass to SysemuCPUOps target/loongarch: Move has_work() from CPUClass to SysemuCPUOps target/i386: Move has_work() from CPUClass to SysemuCPUOps target/hppa: Move has_work() from CPUClass to SysemuCPUOps target/hexagon: Remove CPUClass:has_work() handler target/avr: Move has_work() from CPUClass to SysemuCPUOps ... Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
+7
-7
@@ -152,10 +152,7 @@ Overall TCG CPUs
|
||||
M: Richard Henderson <richard.henderson@linaro.org>
|
||||
R: Paolo Bonzini <pbonzini@redhat.com>
|
||||
S: Maintained
|
||||
F: system/cpus.c
|
||||
F: system/watchpoint.c
|
||||
F: cpu-common.c
|
||||
F: cpu-target.c
|
||||
F: page-vary-target.c
|
||||
F: page-vary-common.c
|
||||
F: accel/tcg/
|
||||
@@ -165,15 +162,11 @@ F: util/cacheflush.c
|
||||
F: scripts/decodetree.py
|
||||
F: docs/devel/decodetree.rst
|
||||
F: docs/devel/tcg*
|
||||
F: include/exec/cpu*.h
|
||||
F: include/exec/exec-all.h
|
||||
F: include/exec/tb-flush.h
|
||||
F: include/exec/target_long.h
|
||||
F: include/exec/helper*.h
|
||||
F: include/exec/helper*.h.inc
|
||||
F: include/exec/helper-info.c.inc
|
||||
F: include/exec/page-protection.h
|
||||
F: include/system/cpus.h
|
||||
F: include/system/tcg.h
|
||||
F: include/accel/tcg/cpu-ops.h
|
||||
F: host/include/*/host/cpuinfo.h
|
||||
@@ -497,12 +490,19 @@ Overall
|
||||
M: Richard Henderson <richard.henderson@linaro.org>
|
||||
R: Paolo Bonzini <pbonzini@redhat.com>
|
||||
S: Maintained
|
||||
F: include/exec/cpu*.h
|
||||
F: include/exec/exec-all.h
|
||||
F: include/exec/target_long.h
|
||||
F: include/qemu/accel.h
|
||||
F: include/system/accel-*.h
|
||||
F: include/system/cpus.h
|
||||
F: include/accel/accel-cpu-target.h
|
||||
F: accel/accel-*.c
|
||||
F: accel/Makefile.objs
|
||||
F: accel/stubs/Makefile.objs
|
||||
F: cpu-common.c
|
||||
F: cpu-target.c
|
||||
F: system/cpus.c
|
||||
|
||||
Apple Silicon HVF CPUs
|
||||
M: Alexander Graf <agraf@csgraf.de>
|
||||
|
||||
@@ -113,22 +113,20 @@ void accel_init_interfaces(AccelClass *ac)
|
||||
|
||||
void accel_cpu_instance_init(CPUState *cpu)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
|
||||
if (cc->accel_cpu && cc->accel_cpu->cpu_instance_init) {
|
||||
cc->accel_cpu->cpu_instance_init(cpu);
|
||||
if (cpu->cc->accel_cpu && cpu->cc->accel_cpu->cpu_instance_init) {
|
||||
cpu->cc->accel_cpu->cpu_instance_init(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
bool accel_cpu_common_realize(CPUState *cpu, Error **errp)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
AccelState *accel = current_accel();
|
||||
AccelClass *acc = ACCEL_GET_CLASS(accel);
|
||||
|
||||
/* target specific realization */
|
||||
if (cc->accel_cpu && cc->accel_cpu->cpu_target_realize
|
||||
&& !cc->accel_cpu->cpu_target_realize(cpu, errp)) {
|
||||
if (cpu->cc->accel_cpu
|
||||
&& cpu->cc->accel_cpu->cpu_target_realize
|
||||
&& !cpu->cc->accel_cpu->cpu_target_realize(cpu, errp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -121,10 +121,9 @@ static inline int xlat_gdb_type(CPUState *cpu, int gdbtype)
|
||||
[GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
|
||||
};
|
||||
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
int cputype = xlat[gdbtype];
|
||||
|
||||
if (cc->gdb_stop_before_watchpoint) {
|
||||
if (cpu->cc->gdb_stop_before_watchpoint) {
|
||||
cputype |= BP_STOP_BEFORE_ACCESS;
|
||||
}
|
||||
return cputype;
|
||||
|
||||
@@ -630,7 +630,7 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
|
||||
* to account for the re-execution of the branch.
|
||||
*/
|
||||
n = 1;
|
||||
cc = CPU_GET_CLASS(cpu);
|
||||
cc = cpu->cc;
|
||||
if (cc->tcg_ops->io_recompile_replay_branch &&
|
||||
cc->tcg_ops->io_recompile_replay_branch(cpu, tb)) {
|
||||
cpu->neg.icount_decr.u16.low++;
|
||||
|
||||
@@ -68,7 +68,6 @@ int cpu_watchpoint_address_matches(CPUState *cpu, vaddr addr, vaddr len)
|
||||
void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
|
||||
MemTxAttrs attrs, int flags, uintptr_t ra)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
CPUWatchpoint *wp;
|
||||
|
||||
assert(tcg_enabled());
|
||||
@@ -84,9 +83,9 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
|
||||
return;
|
||||
}
|
||||
|
||||
if (cc->tcg_ops->adjust_watchpoint_address) {
|
||||
if (cpu->cc->tcg_ops->adjust_watchpoint_address) {
|
||||
/* this is currently used only by ARM BE32 */
|
||||
addr = cc->tcg_ops->adjust_watchpoint_address(cpu, addr, len);
|
||||
addr = cpu->cc->tcg_ops->adjust_watchpoint_address(cpu, addr, len);
|
||||
}
|
||||
|
||||
assert((flags & ~BP_MEM_ACCESS) == 0);
|
||||
@@ -118,8 +117,8 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
|
||||
wp->hitattrs = attrs;
|
||||
|
||||
if (wp->flags & BP_CPU
|
||||
&& cc->tcg_ops->debug_check_watchpoint
|
||||
&& !cc->tcg_ops->debug_check_watchpoint(cpu, wp)) {
|
||||
&& cpu->cc->tcg_ops->debug_check_watchpoint
|
||||
&& !cpu->cc->tcg_ops->debug_check_watchpoint(cpu, wp)) {
|
||||
wp->flags &= ~BP_WATCHPOINT_HIT;
|
||||
continue;
|
||||
}
|
||||
|
||||
+3
-1
@@ -370,9 +370,11 @@ static inline abi_long do_bsd_shmat(int shmid, abi_ulong shmaddr, int shmflg)
|
||||
if (shmaddr) {
|
||||
host_raddr = shmat(shmid, (void *)g2h_untagged(shmaddr), shmflg);
|
||||
} else {
|
||||
abi_ulong alignment;
|
||||
abi_ulong mmap_start;
|
||||
|
||||
mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
|
||||
alignment = 0; /* alignment above page size not required */
|
||||
mmap_start = mmap_find_vma(0, shm_info.shm_segsz, alignment);
|
||||
|
||||
if (mmap_start == -1) {
|
||||
return -TARGET_ENOMEM;
|
||||
|
||||
+5
-12
@@ -275,8 +275,7 @@ static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size,
|
||||
* It must be called with mmap_lock() held.
|
||||
* Return -1 if error.
|
||||
*/
|
||||
static abi_ulong mmap_find_vma_aligned(abi_ulong start, abi_ulong size,
|
||||
abi_ulong alignment)
|
||||
abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong alignment)
|
||||
{
|
||||
void *ptr, *prev;
|
||||
abi_ulong addr;
|
||||
@@ -395,11 +394,6 @@ static abi_ulong mmap_find_vma_aligned(abi_ulong start, abi_ulong size,
|
||||
}
|
||||
}
|
||||
|
||||
abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
|
||||
{
|
||||
return mmap_find_vma_aligned(start, size, 0);
|
||||
}
|
||||
|
||||
/* NOTE: all the constants are the HOST ones */
|
||||
abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
|
||||
int flags, int fd, off_t offset)
|
||||
@@ -489,13 +483,12 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
|
||||
* before we truncate the length for mapping files below.
|
||||
*/
|
||||
if (!(flags & MAP_FIXED)) {
|
||||
abi_ulong alignment;
|
||||
|
||||
host_len = len + offset - host_offset;
|
||||
host_len = HOST_PAGE_ALIGN(host_len);
|
||||
if ((flags & MAP_ALIGNMENT_MASK) != 0)
|
||||
start = mmap_find_vma_aligned(real_start, host_len,
|
||||
(flags & MAP_ALIGNMENT_MASK) >> MAP_ALIGNMENT_SHIFT);
|
||||
else
|
||||
start = mmap_find_vma(real_start, host_len);
|
||||
alignment = (flags & MAP_ALIGNMENT_MASK) >> MAP_ALIGNMENT_SHIFT;
|
||||
start = mmap_find_vma(real_start, host_len, alignment);
|
||||
if (start == (abi_ulong)-1) {
|
||||
errno = ENOMEM;
|
||||
goto fail;
|
||||
|
||||
+1
-11
@@ -32,6 +32,7 @@
|
||||
extern char **environ;
|
||||
|
||||
#include "user/thunk.h"
|
||||
#include "user/mmap.h"
|
||||
#include "target_arch.h"
|
||||
#include "syscall_defs.h"
|
||||
#include "target_syscall.h"
|
||||
@@ -233,19 +234,8 @@ void print_taken_signal(int target_signum, const target_siginfo_t *tinfo);
|
||||
extern int do_strace;
|
||||
|
||||
/* mmap.c */
|
||||
int target_mprotect(abi_ulong start, abi_ulong len, int prot);
|
||||
abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
|
||||
int flags, int fd, off_t offset);
|
||||
int target_munmap(abi_ulong start, abi_ulong len);
|
||||
abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
|
||||
abi_ulong new_size, unsigned long flags,
|
||||
abi_ulong new_addr);
|
||||
int target_msync(abi_ulong start, abi_ulong len, int flags);
|
||||
extern abi_ulong mmap_next_start;
|
||||
abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size);
|
||||
void mmap_reserve(abi_ulong start, abi_ulong size);
|
||||
void TSA_NO_TSA mmap_fork_start(void);
|
||||
void TSA_NO_TSA mmap_fork_end(int child);
|
||||
|
||||
/* main.c */
|
||||
extern char qemu_proc_pathname[];
|
||||
|
||||
+2
-2
@@ -1034,7 +1034,7 @@ void process_pending_signals(CPUArchState *env)
|
||||
void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr,
|
||||
MMUAccessType access_type, bool maperr, uintptr_t ra)
|
||||
{
|
||||
const TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
|
||||
const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
|
||||
|
||||
if (tcg_ops->record_sigsegv) {
|
||||
tcg_ops->record_sigsegv(cpu, addr, access_type, maperr, ra);
|
||||
@@ -1050,7 +1050,7 @@ void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr,
|
||||
void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr,
|
||||
MMUAccessType access_type, uintptr_t ra)
|
||||
{
|
||||
const TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
|
||||
const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
|
||||
|
||||
if (tcg_ops->record_sigbus) {
|
||||
tcg_ops->record_sigbus(cpu, addr, access_type, ra);
|
||||
|
||||
+4
-6
@@ -388,11 +388,10 @@ void process_queued_cpu_work(CPUState *cpu)
|
||||
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);
|
||||
if (cpu->cc->gdb_adjust_breakpoint) {
|
||||
pc = cpu->cc->gdb_adjust_breakpoint(cpu, pc);
|
||||
}
|
||||
|
||||
bp = g_malloc(sizeof(*bp));
|
||||
@@ -418,11 +417,10 @@ int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags,
|
||||
/* 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);
|
||||
if (cpu->cc->gdb_adjust_breakpoint) {
|
||||
pc = cpu->cc->gdb_adjust_breakpoint(cpu, pc);
|
||||
}
|
||||
|
||||
QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
|
||||
|
||||
-146
@@ -21,159 +21,13 @@
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/qemu-print.h"
|
||||
#include "migration/vmstate.h"
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
#include "hw/core/sysemu-cpu-ops.h"
|
||||
#endif
|
||||
#include "system/accel-ops.h"
|
||||
#include "system/cpus.h"
|
||||
#include "system/tcg.h"
|
||||
#include "exec/tswap.h"
|
||||
#include "exec/replay-core.h"
|
||||
#include "exec/cpu-common.h"
|
||||
#include "exec/cputlb.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "exec/tb-flush.h"
|
||||
#include "exec/log.h"
|
||||
#include "accel/accel-cpu-target.h"
|
||||
#include "trace/trace-root.h"
|
||||
#include "qemu/accel.h"
|
||||
#include "hw/core/cpu.h"
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static int cpu_common_post_load(void *opaque, int version_id)
|
||||
{
|
||||
if (tcg_enabled()) {
|
||||
CPUState *cpu = opaque;
|
||||
|
||||
/*
|
||||
* 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the
|
||||
* version_id is increased.
|
||||
*/
|
||||
cpu->interrupt_request &= ~0x01;
|
||||
|
||||
tlb_flush(cpu);
|
||||
|
||||
/*
|
||||
* loadvm has just updated the content of RAM, bypassing the
|
||||
* usual mechanisms that ensure we flush TBs for writes to
|
||||
* memory we've translated code from. So we must flush all TBs,
|
||||
* which will now be stale.
|
||||
*/
|
||||
tb_flush(cpu);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpu_common_pre_load(void *opaque)
|
||||
{
|
||||
CPUState *cpu = opaque;
|
||||
|
||||
cpu->exception_index = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool cpu_common_exception_index_needed(void *opaque)
|
||||
{
|
||||
CPUState *cpu = opaque;
|
||||
|
||||
return tcg_enabled() && cpu->exception_index != -1;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_cpu_common_exception_index = {
|
||||
.name = "cpu_common/exception_index",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.needed = cpu_common_exception_index_needed,
|
||||
.fields = (const VMStateField[]) {
|
||||
VMSTATE_INT32(exception_index, CPUState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static bool cpu_common_crash_occurred_needed(void *opaque)
|
||||
{
|
||||
CPUState *cpu = opaque;
|
||||
|
||||
return cpu->crash_occurred;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_cpu_common_crash_occurred = {
|
||||
.name = "cpu_common/crash_occurred",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.needed = cpu_common_crash_occurred_needed,
|
||||
.fields = (const VMStateField[]) {
|
||||
VMSTATE_BOOL(crash_occurred, CPUState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
const VMStateDescription vmstate_cpu_common = {
|
||||
.name = "cpu_common",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.pre_load = cpu_common_pre_load,
|
||||
.post_load = cpu_common_post_load,
|
||||
.fields = (const VMStateField[]) {
|
||||
VMSTATE_UINT32(halted, CPUState),
|
||||
VMSTATE_UINT32(interrupt_request, CPUState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
.subsections = (const VMStateDescription * const []) {
|
||||
&vmstate_cpu_common_exception_index,
|
||||
&vmstate_cpu_common_crash_occurred,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
bool cpu_exec_realizefn(CPUState *cpu, Error **errp)
|
||||
{
|
||||
if (!accel_cpu_common_realize(cpu, errp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Wait until cpu initialization complete before exposing cpu. */
|
||||
cpu_list_add(cpu);
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
assert(qdev_get_vmsd(DEVICE(cpu)) == NULL ||
|
||||
qdev_get_vmsd(DEVICE(cpu))->unmigratable);
|
||||
#else
|
||||
if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
|
||||
vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu);
|
||||
}
|
||||
if (cpu->cc->sysemu_ops->legacy_vmsd != NULL) {
|
||||
vmstate_register(NULL, cpu->cpu_index, cpu->cc->sysemu_ops->legacy_vmsd, cpu);
|
||||
}
|
||||
#endif /* CONFIG_USER_ONLY */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void cpu_exec_unrealizefn(CPUState *cpu)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
|
||||
if (cc->sysemu_ops->legacy_vmsd != NULL) {
|
||||
vmstate_unregister(NULL, cc->sysemu_ops->legacy_vmsd, cpu);
|
||||
}
|
||||
if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
|
||||
vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
|
||||
}
|
||||
#endif
|
||||
|
||||
cpu_list_remove(cpu);
|
||||
/*
|
||||
* Now that the vCPU has been removed from the RCU list, we can call
|
||||
* accel_cpu_common_unrealize, which may free fields using call_rcu.
|
||||
*/
|
||||
accel_cpu_common_unrealize(cpu);
|
||||
}
|
||||
|
||||
char *cpu_model_from_type(const char *typename)
|
||||
{
|
||||
|
||||
@@ -62,9 +62,8 @@ void disas_initialize_debug_target(CPUDebug *s, CPUState *cpu)
|
||||
s->info.print_address_func = print_address;
|
||||
s->info.endian = BFD_ENDIAN_UNKNOWN;
|
||||
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
if (cc->disas_set_info) {
|
||||
cc->disas_set_info(cpu, &s->info);
|
||||
if (cpu->cc->disas_set_info) {
|
||||
cpu->cc->disas_set_info(cpu, &s->info);
|
||||
g_assert(s->info.endian != BFD_ENDIAN_UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-17
@@ -354,7 +354,6 @@ static const char *get_feature_xml(const char *p, const char **newp,
|
||||
GDBProcess *process)
|
||||
{
|
||||
CPUState *cpu = gdb_get_first_cpu_in_process(process);
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
GDBRegisterState *r;
|
||||
size_t len;
|
||||
|
||||
@@ -377,11 +376,11 @@ static const char *get_feature_xml(const char *p, const char **newp,
|
||||
"<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
|
||||
"<target>"));
|
||||
|
||||
if (cc->gdb_arch_name) {
|
||||
if (cpu->cc->gdb_arch_name) {
|
||||
g_ptr_array_add(
|
||||
xml,
|
||||
g_markup_printf_escaped("<architecture>%s</architecture>",
|
||||
cc->gdb_arch_name(cpu)));
|
||||
cpu->cc->gdb_arch_name(cpu)));
|
||||
}
|
||||
for (guint i = 0; i < cpu->gdb_regs->len; i++) {
|
||||
r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i);
|
||||
@@ -520,11 +519,10 @@ GArray *gdb_get_register_list(CPUState *cpu)
|
||||
|
||||
int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
GDBRegisterState *r;
|
||||
|
||||
if (reg < cc->gdb_num_core_regs) {
|
||||
return cc->gdb_read_register(cpu, buf, reg);
|
||||
if (reg < cpu->cc->gdb_num_core_regs) {
|
||||
return cpu->cc->gdb_read_register(cpu, buf, reg);
|
||||
}
|
||||
|
||||
for (guint i = 0; i < cpu->gdb_regs->len; i++) {
|
||||
@@ -538,11 +536,10 @@ int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
|
||||
|
||||
static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
GDBRegisterState *r;
|
||||
|
||||
if (reg < cc->gdb_num_core_regs) {
|
||||
return cc->gdb_write_register(cpu, mem_buf, reg);
|
||||
if (reg < cpu->cc->gdb_num_core_regs) {
|
||||
return cpu->cc->gdb_write_register(cpu, mem_buf, reg);
|
||||
}
|
||||
|
||||
for (guint i = 0; i < cpu->gdb_regs->len; i++) {
|
||||
@@ -570,7 +567,7 @@ static void gdb_register_feature(CPUState *cpu, int base_reg,
|
||||
|
||||
void gdb_init_cpu(CPUState *cpu)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
CPUClass *cc = cpu->cc;
|
||||
const GDBFeature *feature;
|
||||
|
||||
cpu->gdb_regs = g_array_new(false, false, sizeof(GDBRegisterState));
|
||||
@@ -1646,11 +1643,8 @@ void gdb_extend_qsupported_features(char *qflags)
|
||||
|
||||
static void handle_query_supported(GArray *params, void *user_ctx)
|
||||
{
|
||||
CPUClass *cc;
|
||||
|
||||
g_string_printf(gdbserver_state.str_buf, "PacketSize=%x", MAX_PACKET_LENGTH);
|
||||
cc = CPU_GET_CLASS(first_cpu);
|
||||
if (cc->gdb_core_xml_file) {
|
||||
if (first_cpu->cc->gdb_core_xml_file) {
|
||||
g_string_append(gdbserver_state.str_buf, ";qXfer:features:read+");
|
||||
}
|
||||
|
||||
@@ -1697,7 +1691,6 @@ static void handle_query_supported(GArray *params, void *user_ctx)
|
||||
static void handle_query_xfer_features(GArray *params, void *user_ctx)
|
||||
{
|
||||
GDBProcess *process;
|
||||
CPUClass *cc;
|
||||
unsigned long len, total_len, addr;
|
||||
const char *xml;
|
||||
const char *p;
|
||||
@@ -1708,8 +1701,7 @@ static void handle_query_xfer_features(GArray *params, void *user_ctx)
|
||||
}
|
||||
|
||||
process = gdb_get_cpu_process(gdbserver_state.g_cpu);
|
||||
cc = CPU_GET_CLASS(gdbserver_state.g_cpu);
|
||||
if (!cc->gdb_core_xml_file) {
|
||||
if (!gdbserver_state.g_cpu->cc->gdb_core_xml_file) {
|
||||
gdb_put_packet("");
|
||||
return;
|
||||
}
|
||||
|
||||
+2
-5
@@ -456,8 +456,6 @@ static int phy_memory_mode;
|
||||
int gdb_target_memory_rw_debug(CPUState *cpu, hwaddr addr,
|
||||
uint8_t *buf, int len, bool is_write)
|
||||
{
|
||||
CPUClass *cc;
|
||||
|
||||
if (phy_memory_mode) {
|
||||
if (is_write) {
|
||||
cpu_physical_memory_write(addr, buf, len);
|
||||
@@ -467,9 +465,8 @@ int gdb_target_memory_rw_debug(CPUState *cpu, hwaddr addr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
cc = CPU_GET_CLASS(cpu);
|
||||
if (cc->memory_rw_debug) {
|
||||
return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
|
||||
if (cpu->cc->memory_rw_debug) {
|
||||
return cpu->cc->memory_rw_debug(cpu, addr, buf, len, is_write);
|
||||
}
|
||||
|
||||
return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
|
||||
|
||||
@@ -233,10 +233,8 @@ void gdb_handle_query_offsets(GArray *params, void *user_ctx)
|
||||
static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
|
||||
uint8_t *buf, int len, bool is_write)
|
||||
{
|
||||
CPUClass *cc;
|
||||
cc = CPU_GET_CLASS(cpu);
|
||||
if (cc->memory_rw_debug) {
|
||||
return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
|
||||
if (cpu->cc->memory_rw_debug) {
|
||||
return cpu->cc->memory_rw_debug(cpu, addr, buf, len, is_write);
|
||||
}
|
||||
return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
|
||||
}
|
||||
|
||||
+2
-5
@@ -743,11 +743,8 @@ int gdb_continue_partial(char *newstates)
|
||||
int gdb_target_memory_rw_debug(CPUState *cpu, hwaddr addr,
|
||||
uint8_t *buf, int len, bool is_write)
|
||||
{
|
||||
CPUClass *cc;
|
||||
|
||||
cc = CPU_GET_CLASS(cpu);
|
||||
if (cc->memory_rw_debug) {
|
||||
return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
|
||||
if (cpu->cc->memory_rw_debug) {
|
||||
return cpu->cc->memory_rw_debug(cpu, addr, buf, len, is_write);
|
||||
}
|
||||
return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
|
||||
}
|
||||
|
||||
+2
-2
@@ -235,8 +235,8 @@ void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
|
||||
|
||||
static AcpiCpuStatus *get_cpu_status(CPUHotplugState *cpu_st, DeviceState *dev)
|
||||
{
|
||||
CPUClass *k = CPU_GET_CLASS(dev);
|
||||
uint64_t cpu_arch_id = k->get_arch_id(CPU(dev));
|
||||
CPUState *cpu = CPU(dev);
|
||||
uint64_t cpu_arch_id = cpu->cc->get_arch_id(cpu);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < cpu_st->dev_count; i++) {
|
||||
|
||||
@@ -62,10 +62,9 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
|
||||
static void acpi_set_cpu_present_bit(AcpiCpuHotplug *g, CPUState *cpu,
|
||||
bool *swtchd_to_modern)
|
||||
{
|
||||
CPUClass *k = CPU_GET_CLASS(cpu);
|
||||
int64_t cpu_id;
|
||||
|
||||
cpu_id = k->get_arch_id(cpu);
|
||||
cpu_id = cpu->cc->get_arch_id(cpu);
|
||||
if ((cpu_id / 8) >= ACPI_GPE_PROC_LEN) {
|
||||
object_property_set_bool(g->device, "cpu-hotplug-legacy", false,
|
||||
&error_abort);
|
||||
|
||||
+32
-15
@@ -40,9 +40,7 @@ CPUState *cpu_by_arch_id(int64_t id)
|
||||
CPUState *cpu;
|
||||
|
||||
CPU_FOREACH(cpu) {
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
|
||||
if (cc->get_arch_id(cpu) == id) {
|
||||
if (cpu->cc->get_arch_id(cpu) == id) {
|
||||
return cpu;
|
||||
}
|
||||
}
|
||||
@@ -101,11 +99,9 @@ static int cpu_common_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg)
|
||||
|
||||
void cpu_dump_state(CPUState *cpu, FILE *f, int flags)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
|
||||
if (cc->dump_state) {
|
||||
if (cpu->cc->dump_state) {
|
||||
cpu_synchronize_state(cpu);
|
||||
cc->dump_state(cpu, f, flags);
|
||||
cpu->cc->dump_state(cpu, f, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,11 +115,10 @@ void cpu_reset(CPUState *cpu)
|
||||
static void cpu_common_reset_hold(Object *obj, ResetType type)
|
||||
{
|
||||
CPUState *cpu = CPU(obj);
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
|
||||
if (qemu_loglevel_mask(CPU_LOG_RESET)) {
|
||||
qemu_log("CPU Reset (CPU %d)\n", cpu->cpu_index);
|
||||
log_cpu_state(cpu, cc->reset_dump_flags);
|
||||
log_cpu_state(cpu, cpu->cc->reset_dump_flags);
|
||||
}
|
||||
|
||||
cpu->interrupt_request = 0;
|
||||
@@ -139,11 +134,6 @@ static void cpu_common_reset_hold(Object *obj, ResetType type)
|
||||
cpu_exec_reset_hold(cpu);
|
||||
}
|
||||
|
||||
static bool cpu_common_has_work(CPUState *cs)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model)
|
||||
{
|
||||
ObjectClass *oc;
|
||||
@@ -193,6 +183,20 @@ static void cpu_common_parse_features(const char *typename, char *features,
|
||||
}
|
||||
}
|
||||
|
||||
bool cpu_exec_realizefn(CPUState *cpu, Error **errp)
|
||||
{
|
||||
if (!accel_cpu_common_realize(cpu, errp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Wait until cpu initialization complete before exposing cpu. */
|
||||
cpu_list_add(cpu);
|
||||
|
||||
cpu_vmstate_register(cpu);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void cpu_common_realizefn(DeviceState *dev, Error **errp)
|
||||
{
|
||||
CPUState *cpu = CPU(dev);
|
||||
@@ -234,10 +238,24 @@ static void cpu_common_unrealizefn(DeviceState *dev)
|
||||
cpu_exec_unrealizefn(cpu);
|
||||
}
|
||||
|
||||
void cpu_exec_unrealizefn(CPUState *cpu)
|
||||
{
|
||||
cpu_vmstate_unregister(cpu);
|
||||
|
||||
cpu_list_remove(cpu);
|
||||
/*
|
||||
* Now that the vCPU has been removed from the RCU list, we can call
|
||||
* accel_cpu_common_unrealize, which may free fields using call_rcu.
|
||||
*/
|
||||
accel_cpu_common_unrealize(cpu);
|
||||
}
|
||||
|
||||
static void cpu_common_initfn(Object *obj)
|
||||
{
|
||||
CPUState *cpu = CPU(obj);
|
||||
|
||||
cpu_exec_class_post_init(CPU_GET_CLASS(obj));
|
||||
|
||||
/* cache the cpu class for the hotpath */
|
||||
cpu->cc = CPU_GET_CLASS(cpu);
|
||||
|
||||
@@ -310,7 +328,6 @@ static void cpu_common_class_init(ObjectClass *klass, void *data)
|
||||
|
||||
k->parse_features = cpu_common_parse_features;
|
||||
k->get_arch_id = cpu_common_get_arch_id;
|
||||
k->has_work = cpu_common_has_work;
|
||||
k->gdb_read_register = cpu_common_gdb_read_register;
|
||||
k->gdb_write_register = cpu_common_gdb_write_register;
|
||||
set_bit(DEVICE_CATEGORY_CPU, dc->categories);
|
||||
|
||||
+144
-35
@@ -21,18 +21,25 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "exec/cputlb.h"
|
||||
#include "exec/memory.h"
|
||||
#include "exec/tb-flush.h"
|
||||
#include "exec/tswap.h"
|
||||
#include "hw/qdev-core.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/core/sysemu-cpu-ops.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "system/tcg.h"
|
||||
|
||||
bool cpu_has_work(CPUState *cpu)
|
||||
{
|
||||
return cpu->cc->sysemu_ops->has_work(cpu);
|
||||
}
|
||||
|
||||
bool cpu_paging_enabled(const CPUState *cpu)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
|
||||
if (cc->sysemu_ops->get_paging_enabled) {
|
||||
return cc->sysemu_ops->get_paging_enabled(cpu);
|
||||
if (cpu->cc->sysemu_ops->get_paging_enabled) {
|
||||
return cpu->cc->sysemu_ops->get_paging_enabled(cpu);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -41,10 +48,8 @@ bool cpu_paging_enabled(const CPUState *cpu)
|
||||
bool cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
|
||||
Error **errp)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
|
||||
if (cc->sysemu_ops->get_memory_mapping) {
|
||||
return cc->sysemu_ops->get_memory_mapping(cpu, list, errp);
|
||||
if (cpu->cc->sysemu_ops->get_memory_mapping) {
|
||||
return cpu->cc->sysemu_ops->get_memory_mapping(cpu, list, errp);
|
||||
}
|
||||
|
||||
error_setg(errp, "Obtaining memory mappings is unsupported on this CPU.");
|
||||
@@ -54,15 +59,15 @@ bool cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
|
||||
hwaddr cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
|
||||
MemTxAttrs *attrs)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
hwaddr paddr;
|
||||
|
||||
if (cc->sysemu_ops->get_phys_page_attrs_debug) {
|
||||
paddr = cc->sysemu_ops->get_phys_page_attrs_debug(cpu, addr, attrs);
|
||||
if (cpu->cc->sysemu_ops->get_phys_page_attrs_debug) {
|
||||
paddr = cpu->cc->sysemu_ops->get_phys_page_attrs_debug(cpu, addr,
|
||||
attrs);
|
||||
} else {
|
||||
/* Fallback for CPUs which don't implement the _attrs_ hook */
|
||||
*attrs = MEMTXATTRS_UNSPECIFIED;
|
||||
paddr = cc->sysemu_ops->get_phys_page_debug(cpu, addr);
|
||||
paddr = cpu->cc->sysemu_ops->get_phys_page_debug(cpu, addr);
|
||||
}
|
||||
/* Indicate that this is a debug access. */
|
||||
attrs->debug = 1;
|
||||
@@ -90,64 +95,53 @@ int cpu_asidx_from_attrs(CPUState *cpu, MemTxAttrs attrs)
|
||||
int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
|
||||
void *opaque)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
|
||||
if (!cc->sysemu_ops->write_elf32_qemunote) {
|
||||
if (!cpu->cc->sysemu_ops->write_elf32_qemunote) {
|
||||
return 0;
|
||||
}
|
||||
return (*cc->sysemu_ops->write_elf32_qemunote)(f, cpu, opaque);
|
||||
return (*cpu->cc->sysemu_ops->write_elf32_qemunote)(f, cpu, opaque);
|
||||
}
|
||||
|
||||
int cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cpu,
|
||||
int cpuid, void *opaque)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
|
||||
if (!cc->sysemu_ops->write_elf32_note) {
|
||||
if (!cpu->cc->sysemu_ops->write_elf32_note) {
|
||||
return -1;
|
||||
}
|
||||
return (*cc->sysemu_ops->write_elf32_note)(f, cpu, cpuid, opaque);
|
||||
return (*cpu->cc->sysemu_ops->write_elf32_note)(f, cpu, cpuid, opaque);
|
||||
}
|
||||
|
||||
int cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
|
||||
void *opaque)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
|
||||
if (!cc->sysemu_ops->write_elf64_qemunote) {
|
||||
if (!cpu->cc->sysemu_ops->write_elf64_qemunote) {
|
||||
return 0;
|
||||
}
|
||||
return (*cc->sysemu_ops->write_elf64_qemunote)(f, cpu, opaque);
|
||||
return (*cpu->cc->sysemu_ops->write_elf64_qemunote)(f, cpu, opaque);
|
||||
}
|
||||
|
||||
int cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu,
|
||||
int cpuid, void *opaque)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
|
||||
if (!cc->sysemu_ops->write_elf64_note) {
|
||||
if (!cpu->cc->sysemu_ops->write_elf64_note) {
|
||||
return -1;
|
||||
}
|
||||
return (*cc->sysemu_ops->write_elf64_note)(f, cpu, cpuid, opaque);
|
||||
return (*cpu->cc->sysemu_ops->write_elf64_note)(f, cpu, cpuid, opaque);
|
||||
}
|
||||
|
||||
bool cpu_virtio_is_big_endian(CPUState *cpu)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
|
||||
if (cc->sysemu_ops->virtio_is_big_endian) {
|
||||
return cc->sysemu_ops->virtio_is_big_endian(cpu);
|
||||
if (cpu->cc->sysemu_ops->virtio_is_big_endian) {
|
||||
return cpu->cc->sysemu_ops->virtio_is_big_endian(cpu);
|
||||
}
|
||||
return target_words_bigendian();
|
||||
}
|
||||
|
||||
GuestPanicInformation *cpu_get_crash_info(CPUState *cpu)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
GuestPanicInformation *res = NULL;
|
||||
|
||||
if (cc->sysemu_ops->get_crash_info) {
|
||||
res = cc->sysemu_ops->get_crash_info(cpu);
|
||||
if (cpu->cc->sysemu_ops->get_crash_info) {
|
||||
res = cpu->cc->sysemu_ops->get_crash_info(cpu);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -189,8 +183,123 @@ void cpu_class_init_props(DeviceClass *dc)
|
||||
device_class_set_props(dc, cpu_system_props);
|
||||
}
|
||||
|
||||
void cpu_exec_class_post_init(CPUClass *cc)
|
||||
{
|
||||
/* Check mandatory SysemuCPUOps handlers */
|
||||
g_assert(cc->sysemu_ops->has_work);
|
||||
}
|
||||
|
||||
void cpu_exec_initfn(CPUState *cpu)
|
||||
{
|
||||
cpu->memory = get_system_memory();
|
||||
object_ref(OBJECT(cpu->memory));
|
||||
}
|
||||
|
||||
static int cpu_common_post_load(void *opaque, int version_id)
|
||||
{
|
||||
if (tcg_enabled()) {
|
||||
CPUState *cpu = opaque;
|
||||
|
||||
/*
|
||||
* 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the
|
||||
* version_id is increased.
|
||||
*/
|
||||
cpu->interrupt_request &= ~0x01;
|
||||
|
||||
tlb_flush(cpu);
|
||||
|
||||
/*
|
||||
* loadvm has just updated the content of RAM, bypassing the
|
||||
* usual mechanisms that ensure we flush TBs for writes to
|
||||
* memory we've translated code from. So we must flush all TBs,
|
||||
* which will now be stale.
|
||||
*/
|
||||
tb_flush(cpu);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpu_common_pre_load(void *opaque)
|
||||
{
|
||||
CPUState *cpu = opaque;
|
||||
|
||||
cpu->exception_index = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool cpu_common_exception_index_needed(void *opaque)
|
||||
{
|
||||
CPUState *cpu = opaque;
|
||||
|
||||
return tcg_enabled() && cpu->exception_index != -1;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_cpu_common_exception_index = {
|
||||
.name = "cpu_common/exception_index",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.needed = cpu_common_exception_index_needed,
|
||||
.fields = (const VMStateField[]) {
|
||||
VMSTATE_INT32(exception_index, CPUState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static bool cpu_common_crash_occurred_needed(void *opaque)
|
||||
{
|
||||
CPUState *cpu = opaque;
|
||||
|
||||
return cpu->crash_occurred;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_cpu_common_crash_occurred = {
|
||||
.name = "cpu_common/crash_occurred",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.needed = cpu_common_crash_occurred_needed,
|
||||
.fields = (const VMStateField[]) {
|
||||
VMSTATE_BOOL(crash_occurred, CPUState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
const VMStateDescription vmstate_cpu_common = {
|
||||
.name = "cpu_common",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.pre_load = cpu_common_pre_load,
|
||||
.post_load = cpu_common_post_load,
|
||||
.fields = (const VMStateField[]) {
|
||||
VMSTATE_UINT32(halted, CPUState),
|
||||
VMSTATE_UINT32(interrupt_request, CPUState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
.subsections = (const VMStateDescription * const []) {
|
||||
&vmstate_cpu_common_exception_index,
|
||||
&vmstate_cpu_common_crash_occurred,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
void cpu_vmstate_register(CPUState *cpu)
|
||||
{
|
||||
if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
|
||||
vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu);
|
||||
}
|
||||
if (cpu->cc->sysemu_ops->legacy_vmsd != NULL) {
|
||||
vmstate_register(NULL, cpu->cpu_index,
|
||||
cpu->cc->sysemu_ops->legacy_vmsd, cpu);
|
||||
}
|
||||
}
|
||||
|
||||
void cpu_vmstate_unregister(CPUState *cpu)
|
||||
{
|
||||
if (cpu->cc->sysemu_ops->legacy_vmsd != NULL) {
|
||||
vmstate_unregister(NULL, cpu->cc->sysemu_ops->legacy_vmsd, cpu);
|
||||
}
|
||||
if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
|
||||
vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user