On Mon, 21 Jul 2025, Cornelia Huck wrote:
If we fail migration because of a mismatch of some registers between
source and destination, the error message is not very informative:

qemu-system-aarch64: error while loading state for instance 0x0 ofdevice 'cpu'
qemu-system-aarch64: Failed to put registers after init: Invalid argument

At least try to give the user a hint which registers had a problem,
even if they cannot really do anything about it right now.

Sample output:

Could not set register op0:3 op1:0 crn:0 crm:0 op2:0 to c00fac31 (is 413fd0c1)

We could be even more helpful once we support writable ID registers,
at which point the user might actually be able to configure something
that is migratable.

That message will be even more helpful once we have the stuff in place
to actually print a reg name here (and be able to change the values for
the guest) - but I agree this would already be a great improvement over
the current message!


Suggested-by: Eric Auger <eric.au...@redhat.com>
Signed-off-by: Cornelia Huck <coh...@redhat.com>
---

Notes:
- This currently prints the list of failing registers for every call to
 write_list_to_kvmstate(), in particular for every cpu -- we might want
 to reduce that.
- If the macros aren't too ugly (or we manage to improve them), there
 might be other places where they could be useful.

---
target/arm/kvm.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)

diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 667234485547..ac6502e0c78f 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -900,6 +900,24 @@ bool write_kvmstate_to_list(ARMCPU *cpu)
    return ok;
}

+/* pretty-print a KVM register */
+#define CP_REG_ARM64_SYSREG_OP(_reg, _op)                       \
+    ((uint8_t)((_reg & CP_REG_ARM64_SYSREG_ ## _op ## _MASK) >> \
+               CP_REG_ARM64_SYSREG_ ## _op ## _SHIFT))
+
+#define PRI_CP_REG_ARM64_SYSREG(_reg)                    \
+    ({                                                   \
+        char _out[32];                                   \
+        snprintf(_out, sizeof(_out),                     \
+                 "op0:%d op1:%d crn:%d crm:%d op2:%d",   \
+                 CP_REG_ARM64_SYSREG_OP(_reg, OP0),      \
+                 CP_REG_ARM64_SYSREG_OP(_reg, OP1),      \
+                 CP_REG_ARM64_SYSREG_OP(_reg, CRN),      \
+                 CP_REG_ARM64_SYSREG_OP(_reg, CRM),      \
+                 CP_REG_ARM64_SYSREG_OP(_reg, OP2));     \
+        _out;                                            \
+    })

Gcc correctly complains about a dangling pointer here.

Sebastian


Reply via email to