[PATCH v8 3/6] target/arm/cpu64: Mitigate migration failures due to spurious TCR_EL1, PIRE0_EL1 and PIR_EL1

Eric Auger posted 6 patches 1 month, 1 week ago
There is a newer version of this series
[PATCH v8 3/6] target/arm/cpu64: Mitigate migration failures due to spurious TCR_EL1, PIRE0_EL1 and PIR_EL1
Posted by Eric Auger 1 month, 1 week ago
Before linux v6.13 those registers were erroneously unconditionally
exposed and this was fixed by commits:
- 0fcb4eea5345 ("KVM: arm64: Hide TCR2_EL1 from userspace when
                 disabled for guests")
- a68cddbe47ef ("KVM: arm64: Hide S1PIE registers from userspace
                 when disabled for guests")
in v6.13.

This means if we migrate from an old kernel host to a >= 6.13 kernel
host, migration currently fails.

Declare cpreg migration tolerance for those registers.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 target/arm/cpu64.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index d6feba220e8..4cfddc6e8c0 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -810,6 +810,31 @@ static void aarch64_a53_initfn(Object *obj)
     define_cortex_a72_a57_a53_cp_reginfo(cpu);
 }
 
+static void kvm_arm_set_cpreg_mig_tolerances(ARMCPU *cpu)
+{
+    /*
+     * Registers that may be in the incoming stream and not exposed
+     * on the destination
+     */
+
+    /*
+     * TCR_EL1 was erroneously unconditionnally exposed before linux v6.13.
+     * See commit 0fcb4eea5345 ("KVM: arm64: Hide TCR2_EL1 from userspace
+     * when disabled for guests")
+     */
+    arm_register_cpreg_mig_tolerance(cpu, ARM64_SYS_REG(3, 0, 2, 0, 3),
+                                     0, 0, ToleranceNotOnBothEnds);
+    /*
+     * PIRE0_EL1 and PIR_EL1 were erroneously unconditionnally exposed
+     * before linux v6.13. See commit a68cddbe47ef ("KVM: arm64: Hide
+     * S1PIE registers from userspace when disabled for guests")
+     */
+    arm_register_cpreg_mig_tolerance(cpu, ARM64_SYS_REG(3, 0, 10, 2, 2),
+                                     0, 0, ToleranceNotOnBothEnds);
+    arm_register_cpreg_mig_tolerance(cpu, ARM64_SYS_REG(3, 0, 10, 2, 3),
+                                     0, 0, ToleranceNotOnBothEnds);
+}
+
 static void aarch64_host_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
@@ -822,6 +847,7 @@ static void aarch64_host_initfn(Object *obj)
 #endif
 
 #if defined(CONFIG_KVM)
+    kvm_arm_set_cpreg_mig_tolerances(cpu);
     kvm_arm_set_cpu_features_from_host(cpu);
     aarch64_add_sve_properties(obj);
 #elif defined(CONFIG_HVF)
-- 
2.53.0


Re: [PATCH v8 3/6] target/arm/cpu64: Mitigate migration failures due to spurious TCR_EL1, PIRE0_EL1 and PIR_EL1
Posted by Sebastian Ott 1 month ago
On Wed, 4 Mar 2026, Eric Auger wrote:

> Before linux v6.13 those registers were erroneously unconditionally
> exposed and this was fixed by commits:
> - 0fcb4eea5345 ("KVM: arm64: Hide TCR2_EL1 from userspace when
>                 disabled for guests")
> - a68cddbe47ef ("KVM: arm64: Hide S1PIE registers from userspace
>                 when disabled for guests")
> in v6.13.
>
> This means if we migrate from an old kernel host to a >= 6.13 kernel
> host, migration currently fails.
>
> Declare cpreg migration tolerance for those registers.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>

Reviewed-by: Sebastian Ott <sebott@redhat.com>



> ---
> target/arm/cpu64.c | 26 ++++++++++++++++++++++++++
> 1 file changed, 26 insertions(+)
>
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index d6feba220e8..4cfddc6e8c0 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -810,6 +810,31 @@ static void aarch64_a53_initfn(Object *obj)
>     define_cortex_a72_a57_a53_cp_reginfo(cpu);
> }
>
> +static void kvm_arm_set_cpreg_mig_tolerances(ARMCPU *cpu)
> +{
> +    /*
> +     * Registers that may be in the incoming stream and not exposed
> +     * on the destination
> +     */
> +
> +    /*
> +     * TCR_EL1 was erroneously unconditionnally exposed before linux v6.13.
> +     * See commit 0fcb4eea5345 ("KVM: arm64: Hide TCR2_EL1 from userspace
> +     * when disabled for guests")
> +     */
> +    arm_register_cpreg_mig_tolerance(cpu, ARM64_SYS_REG(3, 0, 2, 0, 3),
> +                                     0, 0, ToleranceNotOnBothEnds);
> +    /*
> +     * PIRE0_EL1 and PIR_EL1 were erroneously unconditionnally exposed
> +     * before linux v6.13. See commit a68cddbe47ef ("KVM: arm64: Hide
> +     * S1PIE registers from userspace when disabled for guests")
> +     */
> +    arm_register_cpreg_mig_tolerance(cpu, ARM64_SYS_REG(3, 0, 10, 2, 2),
> +                                     0, 0, ToleranceNotOnBothEnds);
> +    arm_register_cpreg_mig_tolerance(cpu, ARM64_SYS_REG(3, 0, 10, 2, 3),
> +                                     0, 0, ToleranceNotOnBothEnds);
> +}
> +
> static void aarch64_host_initfn(Object *obj)
> {
>     ARMCPU *cpu = ARM_CPU(obj);
> @@ -822,6 +847,7 @@ static void aarch64_host_initfn(Object *obj)
> #endif
>
> #if defined(CONFIG_KVM)
> +    kvm_arm_set_cpreg_mig_tolerances(cpu);
>     kvm_arm_set_cpu_features_from_host(cpu);
>     aarch64_add_sve_properties(obj);
> #elif defined(CONFIG_HVF)
> -- 
> 2.53.0
>
>