Migrate the host LVZ controls, guest CSR and TLB banks, and restore the active VM level, guest timer and interrupt request after loading state.
Signed-off-by: SignKirigami <[email protected]> Signed-off-by: Hengyu Yu <[email protected]> --- target/loongarch/machine.c | 111 ++++++++++++++++++++++++++++++++++++- 1 file changed, 110 insertions(+), 1 deletion(-) diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c index 931a5ca5ba..2bf2475748 100644 --- a/target/loongarch/machine.c +++ b/target/loongarch/machine.c @@ -7,6 +7,7 @@ #include "qemu/osdep.h" #include "cpu.h" +#include "internals.h" #include "migration/vmstate.h" #include "system/tcg.h" #include "vec.h" @@ -200,18 +201,125 @@ static const VMStateDescription vmstate_tlb = { .minimum_version_id = 0, .needed = tlb_needed, .fields = (const VMStateField[]) { - VMSTATE_STRUCT_ARRAY(env.tlb, LoongArchCPU, LOONGARCH_TLB_MAX, + VMSTATE_STRUCT_ARRAY(env.sys_states[0].tlb, LoongArchCPU, + LOONGARCH_TLB_MAX, 0, vmstate_tlb_entry, LoongArchTLB), VMSTATE_END_OF_LIST() } }; + +static const VMStateDescription vmstate_lvz_sys = { + .name = "cpu/lvz-sys", + .version_id = 1, + .minimum_version_id = 1, + .fields = (const VMStateField[]) { + VMSTATE_UINT64(CSR_CRMD, CPUSysState), + VMSTATE_UINT64(CSR_PRMD, CPUSysState), + VMSTATE_UINT64(CSR_EUEN, CPUSysState), + VMSTATE_UINT64(CSR_MISC, CPUSysState), + VMSTATE_UINT64(CSR_ECFG, CPUSysState), + VMSTATE_UINT64(CSR_ESTAT, CPUSysState), + VMSTATE_UINT64(CSR_ERA, CPUSysState), + VMSTATE_UINT64(CSR_BADV, CPUSysState), + VMSTATE_UINT64(CSR_BADI, CPUSysState), + VMSTATE_UINT64(CSR_EENTRY, CPUSysState), + VMSTATE_UINT64(CSR_TLBIDX, CPUSysState), + VMSTATE_UINT64(CSR_TLBEHI, CPUSysState), + VMSTATE_UINT64(CSR_TLBELO0, CPUSysState), + VMSTATE_UINT64(CSR_TLBELO1, CPUSysState), + VMSTATE_UINT64(CSR_ASID, CPUSysState), + VMSTATE_UINT64(CSR_PGDL, CPUSysState), + VMSTATE_UINT64(CSR_PGDH, CPUSysState), + VMSTATE_UINT64(CSR_PGD, CPUSysState), + VMSTATE_UINT64(CSR_PWCL, CPUSysState), + VMSTATE_UINT64(CSR_PWCH, CPUSysState), + VMSTATE_UINT64(CSR_STLBPS, CPUSysState), + VMSTATE_UINT64(CSR_RVACFG, CPUSysState), + VMSTATE_UINT64(CSR_CPUID, CPUSysState), + VMSTATE_UINT64(CSR_PRCFG1, CPUSysState), + VMSTATE_UINT64(CSR_PRCFG2, CPUSysState), + VMSTATE_UINT64(CSR_PRCFG3, CPUSysState), + VMSTATE_UINT64_ARRAY(CSR_SAVE, CPUSysState, 16), + VMSTATE_UINT64(CSR_TID, CPUSysState), + VMSTATE_UINT64(CSR_TCFG, CPUSysState), + VMSTATE_UINT64(CSR_TVAL, CPUSysState), + VMSTATE_UINT64(CSR_CNTC, CPUSysState), + VMSTATE_UINT64(CSR_TICLR, CPUSysState), + VMSTATE_UINT64(CSR_LLBCTL, CPUSysState), + VMSTATE_UINT64(CSR_IMPCTL1, CPUSysState), + VMSTATE_UINT64(CSR_IMPCTL2, CPUSysState), + VMSTATE_UINT64(CSR_TLBRENTRY, CPUSysState), + VMSTATE_UINT64(CSR_TLBRBADV, CPUSysState), + VMSTATE_UINT64(CSR_TLBRERA, CPUSysState), + VMSTATE_UINT64(CSR_TLBRSAVE, CPUSysState), + VMSTATE_UINT64(CSR_TLBRELO0, CPUSysState), + VMSTATE_UINT64(CSR_TLBRELO1, CPUSysState), + VMSTATE_UINT64(CSR_TLBREHI, CPUSysState), + VMSTATE_UINT64(CSR_TLBRPRMD, CPUSysState), + VMSTATE_UINT64(CSR_MERRCTL, CPUSysState), + VMSTATE_UINT64(CSR_MERRINFO1, CPUSysState), + VMSTATE_UINT64(CSR_MERRINFO2, CPUSysState), + VMSTATE_UINT64(CSR_MERRENTRY, CPUSysState), + VMSTATE_UINT64(CSR_MERRERA, CPUSysState), + VMSTATE_UINT64(CSR_MERRSAVE, CPUSysState), + VMSTATE_UINT64(CSR_CTAG, CPUSysState), + VMSTATE_UINT64_ARRAY(CSR_DMW, CPUSysState, 4), + VMSTATE_UINT64(CSR_DBG, CPUSysState), + VMSTATE_UINT64(CSR_DERA, CPUSysState), + VMSTATE_UINT64(CSR_DSAVE, CPUSysState), + VMSTATE_UINT64(CSR_GSTAT, CPUSysState), + VMSTATE_UINT64(CSR_GCFG, CPUSysState), + VMSTATE_UINT64(CSR_GINTC, CPUSysState), + VMSTATE_UINT64(CSR_GCNTC, CPUSysState), + VMSTATE_UINT64(CSR_GTLBC, CPUSysState), + VMSTATE_END_OF_LIST() + }, +}; + +static bool lvz_needed(void *opaque) +{ + LoongArchCPU *cpu = opaque; + + return FIELD_EX64(cpu->env.cpucfg[2], CPUCFG2, LVZ); +} + +static const VMStateDescription vmstate_lvz = { + .name = "cpu/lvz", + .version_id = 1, + .minimum_version_id = 1, + .needed = lvz_needed, + .fields = (const VMStateField[]) { + VMSTATE_UINT64(env.sys_states[0].CSR_GSTAT, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_GCFG, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_GINTC, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_GCNTC, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_GTLBC, LoongArchCPU), + VMSTATE_STRUCT(env.sys_states[1], LoongArchCPU, 0, + vmstate_lvz_sys, CPUSysState), + VMSTATE_STRUCT_ARRAY(env.sys_states[1].tlb, LoongArchCPU, + LOONGARCH_TLB_MAX, + 0, vmstate_tlb_entry, LoongArchTLB), + VMSTATE_END_OF_LIST() + }, +}; #endif +static int loongarch_cpu_post_load(void *opaque, int version_id) +{ + LoongArchCPU *cpu = opaque; + CPULoongArchState *env = &cpu->env; + CPUSysState *host = get_sys(env, LOONGARCH_VM_LEVEL_HOST); + bool guest = FIELD_EX64(host->CSR_GSTAT, CSR_GSTAT, VM); + set_sys(env, guest); + return 0; +} + /* LoongArch CPU state */ const VMStateDescription vmstate_loongarch_cpu = { .name = "cpu", .version_id = 4, .minimum_version_id = 4, + .post_load = loongarch_cpu_post_load, .fields = (const VMStateField[]) { VMSTATE_UINT64_ARRAY(env.gpr, LoongArchCPU, 32), VMSTATE_UINT64(env.pc, LoongArchCPU), @@ -285,6 +393,7 @@ const VMStateDescription vmstate_loongarch_cpu = { &vmstate_lasx, #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY) &vmstate_tlb, + &vmstate_lvz, #endif &vmstate_lbt, &vmstate_msgint, -- 2.55.0
