On Tue, Nov 18 2025, Eric Auger <[email protected]> wrote:

> More recent kernels sometimes expose new registers in an
> unconditionnal manner. This situation breaks backward migration
> as qemu notices there are more registers in the input stream
> than supported on the destination host. This leads to a
> "failed to load cpu:cpreg_vmstate_array_len" error.
>
> A good example is the introduction of KVM_REG_ARM_VENDOR_HYP_BMAP_2
> pseudo FW register in v6.16 by commit C0000e58c74e (“KVM: arm64:
> Introduce KVM_REG_ARM_VENDOR_HYP_BMAP_2”). Trying to do backward
> migration from a host kernel that features the commit to a destination
> host that doesn't, fail with above error.
>
> Currently QEMU is not using that feature so ignoring this latter
> is not a problem. An easy way to fix the migration issue is to teach
> qemu we don't care about that register and we can simply ignore it
> when syncing its state during migration.
>
> This patch introduces an array of such hidden registers. Soon it will
> be settable through an array property.
>
> If hidden, the register is moved out of the array of cpreg which is
> built in kvm_arm_init_cpreg_list(). That way their state won't be
> synced.
>
> Signed-off-by: Eric Auger <[email protected]>
>
> ---
>
> v1 -> v2:
> - Move the property in a separate patch
> - improve the commit msg
> - change the trace point to just print info in
>   kvm_arm_init_cpreg_list()
> - improve comment in cpu.h (Connie)
> ---
>  target/arm/cpu.h        | 23 +++++++++++++++++++++++
>  target/arm/kvm.c        | 12 +++++++++++-
>  target/arm/trace-events |  2 ++
>  3 files changed, 36 insertions(+), 1 deletion(-)
>
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 077b0cce5b..0a283940be 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -1044,6 +1044,18 @@ struct ArchCPU {
>      /* KVM steal time */
>      OnOffAuto kvm_steal_time;
>  
> +    /*
> +     * Register indexes that must be hidden. Although normally
> +     * supported (defined in TCG description or exposed by KVM) they are
> +     * willingly hidden for migration sake. This may be used to allow
> +     * backward migration to older versions that do implement a specific
> +     * feature. With KVM acceleration the indexes are the ones described
> +     * in linux/Documentation/virt/kvm/api.rst. With TCG, this is the TCG
> +     * sysreg index.
> +     */

Hmm... what about

"Array of register indexes that need to be hidden to allow migration in
certain cases, i.e. when a register is exposed in KVM or defined in TCG
but not actually used in QEMU. For the KVM case, the indexes are as
described in Linux Documentation/virt/kvm/api.rst. For TCG, the indexes
are the TCG sysreg indexes."

> +    uint64_t *hidden_regs;
> +    uint32_t nr_hidden_regs;
> +
>      /* Uniprocessor system with MP extensions */
>      bool mp_is_up;
>  

Otherwise, LGTM.


Reply via email to