aboutsummaryrefslogtreecommitdiff
path: root/target/ppc
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2023-08-08 14:19:52 +1000
committerCédric Le Goater <clg@kaod.org>2023-09-06 11:19:33 +0200
commit578912ad7312ececb9a88b4c38d406dda640346d (patch)
treef08269af71a20f92513f771879c312fa08f8ffea /target/ppc
parentfebb71d543a8f747b2f8aaf0182d0a385c6a02c3 (diff)
downloadqemu-578912ad7312ececb9a88b4c38d406dda640346d.zip
qemu-578912ad7312ececb9a88b4c38d406dda640346d.tar.gz
qemu-578912ad7312ececb9a88b4c38d406dda640346d.tar.bz2
target/ppc: Migrate DECR SPR
TCG does not maintain the DEC reigster in the SPR array, so it does get migrated. TCG also needs to re-start the decrementer timer on the destination machine. Load and store the decrementer into the SPR when migrating. This works for the level-triggered (book3s) decrementer, and should be compatible with existing KVM machines that do keep the DEC value there. This fixes lost decrementer interrupt on migration that can cause hangs, as well as other problems including record-replay bugs. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Cédric Le Goater <clg@kaod.org>
Diffstat (limited to 'target/ppc')
-rw-r--r--target/ppc/machine.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/target/ppc/machine.c b/target/ppc/machine.c
index 07ca184..3265338 100644
--- a/target/ppc/machine.c
+++ b/target/ppc/machine.c
@@ -208,6 +208,14 @@ static int cpu_pre_save(void *opaque)
/* Used to retain migration compatibility for pre 6.0 for 601 machines. */
env->hflags_compat_nmsr = 0;
+ if (tcg_enabled()) {
+ /*
+ * TCG does not maintain the DECR spr (unlike KVM) so have to save
+ * it here.
+ */
+ env->spr[SPR_DECR] = cpu_ppc_load_decr(env);
+ }
+
return 0;
}
@@ -318,6 +326,12 @@ static int cpu_post_load(void *opaque, int version_id)
ppc_update_ciabr(env);
ppc_update_daw0(env);
#endif
+ /*
+ * TCG needs to re-start the decrementer timer and/or raise the
+ * interrupt. This works for level-triggered decrementer. Edge
+ * triggered types (including HDEC) would need to carry more state.
+ */
+ cpu_ppc_store_decr(env, env->spr[SPR_DECR]);
pmu_mmcr01_updated(env);
}