The debug migration state does not include mcontext. Change to using
a new sdtrig vmstate format that allows for all architectural state
if mcontext != 0.
This means a machine is sometimes-migratable, which on second
thoughts is probably bad. Is there a better way to do this, or could
we just break compat and move to the new vmstate?
Not yet signed off.
---
target/riscv/machine.c | 58 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 57 insertions(+), 1 deletion(-)
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index fdd5e8b67b..23a5f60d2a 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -221,8 +221,10 @@ static const VMStateDescription vmstate_kvmtimer = {
static bool debug_needed(void *opaque)
{
RISCVCPU *cpu = opaque;
+ CPURISCVState *env = &cpu->env;
- return cpu->cfg.debug;
+ return cpu->cfg.debug &&
+ env->sdtrig_state.mcontext == 0;
}
static int debug_pre_save(void *opaque)
@@ -273,6 +275,59 @@ static const VMStateDescription vmstate_debug = {
}
};
+/*
+ * This is a newer version of the debug (sdtrig) state, required
+ * to migrate hcontext/mcontext.
+ */
+static bool sdtrig_needed(void *opaque)
+{
+ RISCVCPU *cpu = opaque;
+ CPURISCVState *env = &cpu->env;
+
+ return cpu->cfg.debug &&
+ env->sdtrig_state.mcontext != 0;
+}
+
+static int sdtrig_post_load(void *opaque, int version_id)
+{
+ RISCVCPU *cpu = opaque;
+ CPURISCVState *env = &cpu->env;
+
+ riscv_cpu_debug_post_load(env);
+
+ return 0;
+}
+
+static const VMStateDescription vmstate_sdtrig_trigger = {
+ .name = "cpu/sdtrig/trigger",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINTTL(tdata1, SdtrigTrigger),
+ VMSTATE_UINTTL(tdata2, SdtrigTrigger),
+ VMSTATE_UINTTL(tdata3, SdtrigTrigger),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static const VMStateDescription vmstate_sdtrig = {
+ .name = "cpu/sdtrig",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = sdtrig_needed,
+ .post_load = sdtrig_post_load,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINTTL(env.sdtrig_state.trigger_cur, RISCVCPU),
+ VMSTATE_UINTTL(env.sdtrig_state.tcontrol, RISCVCPU),
+ VMSTATE_UINTTL(env.sdtrig_state.mcontext, RISCVCPU),
+ VMSTATE_UINTTL(env.sdtrig_state.scontext, RISCVCPU),
+ VMSTATE_STRUCT_ARRAY(env.sdtrig_state.triggers, RISCVCPU,
+ RV_MAX_SDTRIG_TRIGGERS,
+ 0, vmstate_sdtrig_trigger, SdtrigTrigger),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static int riscv_cpu_post_load(void *opaque, int version_id)
{
RISCVCPU *cpu = opaque;
@@ -514,6 +569,7 @@ const VMStateDescription vmstate_riscv_cpu = {
#endif
&vmstate_envcfg,
&vmstate_debug,
+ &vmstate_sdtrig,
&vmstate_smstateen,
&vmstate_jvt,
&vmstate_elp,
--
2.51.0