We introduce a datatype for a tolerance with respect to a given
cpreg migration issue. The tolerance applies to a given cpreg kvm index,
and can be of different types:
- ToleranceNotOnBothEnds (cpreg index is allowed to be only on one end)
- ToleranceDiffInMask (value differences are allowed only within a mask)
- ToleranceFieldLT (incoming field value must be less than a given value)
- ToleranceFieldGT (incoming field value must be greater than a given value)
A QLIST of such tolerances can be populated using a new helper:
arm_register_cpreg_mig_tolerance() and arm_cpu_cpreg_has_mig_tolerance()
allows to check whether a tolerance exists for a given kvm index.
callers for those helpers will be introduced in subsequent patches.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
target/arm/cpu.h | 32 +++++++++++++++++++++
target/arm/cpu.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 107 insertions(+)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 657ff4ab20b..9dcc838f611 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -843,6 +843,21 @@ struct ARMELChangeHook {
QLIST_ENTRY(ARMELChangeHook) node;
};
+typedef enum {
+ ToleranceNotOnBothEnds,
+ ToleranceDiffInMask,
+ ToleranceFieldLT,
+ ToleranceFieldGT,
+} ARMCPUCPREGMigToleranceType;
+
+typedef struct ARMCPUCPREGMigTolerance {
+ uint64_t kvmidx;
+ uint64_t mask;
+ uint64_t value;
+ ARMCPUCPREGMigToleranceType type;
+ QLIST_ENTRY(ARMCPUCPREGMigTolerance) node;
+} ARMCPUCPREGMigTolerance;
+
/* These values map onto the return values for
* QEMU_PSCI_0_2_FN_AFFINITY_INFO */
typedef enum ARMPSCIState {
@@ -1139,6 +1154,7 @@ struct ArchCPU {
QLIST_HEAD(, ARMELChangeHook) pre_el_change_hooks;
QLIST_HEAD(, ARMELChangeHook) el_change_hooks;
+ QLIST_HEAD(, ARMCPUCPREGMigTolerance) cpreg_mig_tolerances;
int32_t node_id; /* NUMA node this CPU belongs to */
@@ -2632,6 +2648,22 @@ void arm_register_pre_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook, void
*opaque);
+/**
+ * arm_register_cpreg_mig_tolerance:
+ * Register a migration tolerance wrt one given cpreg identified by its
+ * @kvmidx. Only one tolerance can be registered by kvm reg idx.
+ */
+void arm_register_cpreg_mig_tolerance(ARMCPU *cpu, uint64_t kvmidx,
+ uint64_t mask, uint64_t value,
+ ARMCPUCPREGMigToleranceType type);
+
+/**
+ * arm_cpu_cpreg_has_mig_tolerance:
+ * Check whether a tolerance of type @type exists for a given @kvmidx
+ */
+bool arm_cpu_cpreg_has_mig_tolerance(ARMCPU *cpu, uint64_t kvmidx,
+ uint64_t vmstate_value, uint64_t local_value,
+ ARMCPUCPREGMigToleranceType type);
/**
* arm_rebuild_hflags:
* Rebuild the cached TBFLAGS for arbitrary changed processor state.
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 7e3e84b4bbb..1c499d1b15c 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -181,6 +181,75 @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
QLIST_INSERT_HEAD(&cpu->el_change_hooks, entry, node);
}
+void arm_register_cpreg_mig_tolerance(ARMCPU *cpu, uint64_t kvmidx,
+ uint64_t mask, uint64_t value,
+ ARMCPUCPREGMigToleranceType type)
+{
+ ARMCPUCPREGMigTolerance *t, *entry;
+
+ /* make sure the kvmidx has not tolerance already registered */
+ QLIST_FOREACH(t, &cpu->cpreg_mig_tolerances, node) {
+ if (t->kvmidx == kvmidx) {
+ g_assert_not_reached();
+ }
+ }
+ entry = g_new0(ARMCPUCPREGMigTolerance, 1);
+
+ entry->kvmidx = kvmidx;
+ entry->mask = mask;
+ entry->value = value;
+ entry->type = type;
+
+ QLIST_INSERT_HEAD(&cpu->cpreg_mig_tolerances, entry, node);
+}
+
+bool arm_cpu_cpreg_has_mig_tolerance(ARMCPU *cpu, uint64_t kvmidx,
+ uint64_t vmstate_value, uint64_t local_value,
+ ARMCPUCPREGMigToleranceType type)
+{
+ ARMCPUCPREGMigTolerance *t;
+ uint64_t diff, diff_outside_mask, field;
+ bool found = false;
+
+ QLIST_FOREACH(t, &cpu->cpreg_mig_tolerances, node) {
+ if (t->kvmidx == kvmidx) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ return false;
+ }
+
+ /* we found one tolerance associated to the @kvmidx */
+
+ if (type == ToleranceNotOnBothEnds) {
+ return true;
+ }
+
+ /* Need to check mask */
+ diff = vmstate_value ^ local_value;
+ diff_outside_mask = diff & ~t->mask;
+
+ if (diff_outside_mask) {
+ /* there are differences outside of the mask */
+ return false;
+ }
+ if (type == ToleranceDiffInMask) {
+ /* differences only in the field, tolerance granted */
+ return true;
+ }
+ /* need to compare field value against authorized ones */
+ field = vmstate_value & t->mask;
+ if (type == ToleranceFieldLT && (field < t->value)) {
+ return true;
+ }
+ if (type == ToleranceFieldGT && (field > t->value)) {
+ return true;
+ }
+ return false;
+}
+
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
{
/* Reset a single ARMCPRegInfo register */
@@ -1106,6 +1175,7 @@ static void arm_cpu_initfn(Object *obj)
QLIST_INIT(&cpu->pre_el_change_hooks);
QLIST_INIT(&cpu->el_change_hooks);
+ QLIST_INIT(&cpu->cpreg_mig_tolerances);
#ifdef CONFIG_USER_ONLY
# ifdef TARGET_AARCH64
@@ -1550,6 +1620,7 @@ static void arm_cpu_finalizefn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
ARMELChangeHook *hook, *next;
+ ARMCPUCPREGMigTolerance *t, *n;
g_hash_table_destroy(cpu->cp_regs);
@@ -1561,6 +1632,10 @@ static void arm_cpu_finalizefn(Object *obj)
QLIST_REMOVE(hook, node);
g_free(hook);
}
+ QLIST_FOREACH_SAFE(t, &cpu->cpreg_mig_tolerances, node, n) {
+ QLIST_REMOVE(t, node);
+ g_free(t);
+ }
#ifndef CONFIG_USER_ONLY
if (cpu->pmu_timer) {
timer_free(cpu->pmu_timer);
--
2.53.0
On Wed, 4 Mar 2026, Eric Auger wrote:
> We introduce a datatype for a tolerance with respect to a given
> cpreg migration issue. The tolerance applies to a given cpreg kvm index,
> and can be of different types:
> - ToleranceNotOnBothEnds (cpreg index is allowed to be only on one end)
^
available/present?
> - ToleranceDiffInMask (value differences are allowed only within a mask)
> - ToleranceFieldLT (incoming field value must be less than a given value)
> - ToleranceFieldGT (incoming field value must be greater than a given value)
>
> A QLIST of such tolerances can be populated using a new helper:
> arm_register_cpreg_mig_tolerance() and arm_cpu_cpreg_has_mig_tolerance()
> allows to check whether a tolerance exists for a given kvm index.
>
> callers for those helpers will be introduced in subsequent patches.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
> target/arm/cpu.h | 32 +++++++++++++++++++++
> target/arm/cpu.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 107 insertions(+)
>
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 657ff4ab20b..9dcc838f611 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -843,6 +843,21 @@ struct ARMELChangeHook {
> QLIST_ENTRY(ARMELChangeHook) node;
> };
>
> +typedef enum {
> + ToleranceNotOnBothEnds,
> + ToleranceDiffInMask,
> + ToleranceFieldLT,
> + ToleranceFieldGT,
> +} ARMCPUCPREGMigToleranceType;
> +
> +typedef struct ARMCPUCPREGMigTolerance {
> + uint64_t kvmidx;
> + uint64_t mask;
> + uint64_t value;
> + ARMCPUCPREGMigToleranceType type;
> + QLIST_ENTRY(ARMCPUCPREGMigTolerance) node;
> +} ARMCPUCPREGMigTolerance;
> +
> /* These values map onto the return values for
> * QEMU_PSCI_0_2_FN_AFFINITY_INFO */
> typedef enum ARMPSCIState {
> @@ -1139,6 +1154,7 @@ struct ArchCPU {
>
> QLIST_HEAD(, ARMELChangeHook) pre_el_change_hooks;
> QLIST_HEAD(, ARMELChangeHook) el_change_hooks;
> + QLIST_HEAD(, ARMCPUCPREGMigTolerance) cpreg_mig_tolerances;
>
> int32_t node_id; /* NUMA node this CPU belongs to */
>
> @@ -2632,6 +2648,22 @@ void arm_register_pre_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
> void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook, void
> *opaque);
>
> +/**
> + * arm_register_cpreg_mig_tolerance:
> + * Register a migration tolerance wrt one given cpreg identified by its
> + * @kvmidx. Only one tolerance can be registered by kvm reg idx.
> + */
> +void arm_register_cpreg_mig_tolerance(ARMCPU *cpu, uint64_t kvmidx,
> + uint64_t mask, uint64_t value,
> + ARMCPUCPREGMigToleranceType type);
> +
> +/**
> + * arm_cpu_cpreg_has_mig_tolerance:
> + * Check whether a tolerance of type @type exists for a given @kvmidx
> + */
This function does more than the name and description suggests - it not
only checks if the tolerance exists but also if it applies..
arm_cpu_cpreg_mig_tolerated ?
> +bool arm_cpu_cpreg_has_mig_tolerance(ARMCPU *cpu, uint64_t kvmidx,
> + uint64_t vmstate_value, uint64_t local_value,
> + ARMCPUCPREGMigToleranceType type);
> /**
> * arm_rebuild_hflags:
> * Rebuild the cached TBFLAGS for arbitrary changed processor state.
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index 7e3e84b4bbb..1c499d1b15c 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -181,6 +181,75 @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
> QLIST_INSERT_HEAD(&cpu->el_change_hooks, entry, node);
> }
>
> +void arm_register_cpreg_mig_tolerance(ARMCPU *cpu, uint64_t kvmidx,
> + uint64_t mask, uint64_t value,
> + ARMCPUCPREGMigToleranceType type)
> +{
> + ARMCPUCPREGMigTolerance *t, *entry;
> +
> + /* make sure the kvmidx has not tolerance already registered */
> + QLIST_FOREACH(t, &cpu->cpreg_mig_tolerances, node) {
> + if (t->kvmidx == kvmidx) {
> + g_assert_not_reached();
> + }
> + }
> + entry = g_new0(ARMCPUCPREGMigTolerance, 1);
> +
> + entry->kvmidx = kvmidx;
> + entry->mask = mask;
> + entry->value = value;
> + entry->type = type;
> +
> + QLIST_INSERT_HEAD(&cpu->cpreg_mig_tolerances, entry, node);
> +}
> +
> +bool arm_cpu_cpreg_has_mig_tolerance(ARMCPU *cpu, uint64_t kvmidx,
> + uint64_t vmstate_value, uint64_t local_value,
> + ARMCPUCPREGMigToleranceType type)
> +{
> + ARMCPUCPREGMigTolerance *t;
> + uint64_t diff, diff_outside_mask, field;
> + bool found = false;
> +
> + QLIST_FOREACH(t, &cpu->cpreg_mig_tolerances, node) {
> + if (t->kvmidx == kvmidx) {
> + found = true;
> + break;
> + }
> + }
> + if (!found) {
> + return false;
> + }
> +
> + /* we found one tolerance associated to the @kvmidx */
> +
> + if (type == ToleranceNotOnBothEnds) {
This should use t->type and type can be removed as an argument.
> + return true;
> + }
> +
> + /* Need to check mask */
> + diff = vmstate_value ^ local_value;
> + diff_outside_mask = diff & ~t->mask;
> +
> + if (diff_outside_mask) {
> + /* there are differences outside of the mask */
> + return false;
> + }
> + if (type == ToleranceDiffInMask) {
> + /* differences only in the field, tolerance granted */
> + return true;
> + }
> + /* need to compare field value against authorized ones */
> + field = vmstate_value & t->mask;
> + if (type == ToleranceFieldLT && (field < t->value)) {
> + return true;
> + }
> + if (type == ToleranceFieldGT && (field > t->value)) {
> + return true;
> + }
Ah, so this is only compared with a static value not with the local_value.
Would there be a need for a more sophisticated check than
ToleranceDiffInMask?
We could instead of having the type per ARMCPUCPREGMigTolerance register a
callback that makes the decision. The 4 types would be 4 pre-defined
callbacks and if a user needs something more sophisticated it can create
a custom callback.
But yea, that's just an idea - not sure if we'll ever need something like
this..
> + return false;
> +}
> +
> static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
> {
> /* Reset a single ARMCPRegInfo register */
> @@ -1106,6 +1175,7 @@ static void arm_cpu_initfn(Object *obj)
>
> QLIST_INIT(&cpu->pre_el_change_hooks);
> QLIST_INIT(&cpu->el_change_hooks);
> + QLIST_INIT(&cpu->cpreg_mig_tolerances);
>
> #ifdef CONFIG_USER_ONLY
> # ifdef TARGET_AARCH64
> @@ -1550,6 +1620,7 @@ static void arm_cpu_finalizefn(Object *obj)
> {
> ARMCPU *cpu = ARM_CPU(obj);
> ARMELChangeHook *hook, *next;
> + ARMCPUCPREGMigTolerance *t, *n;
>
> g_hash_table_destroy(cpu->cp_regs);
>
> @@ -1561,6 +1632,10 @@ static void arm_cpu_finalizefn(Object *obj)
> QLIST_REMOVE(hook, node);
> g_free(hook);
> }
> + QLIST_FOREACH_SAFE(t, &cpu->cpreg_mig_tolerances, node, n) {
> + QLIST_REMOVE(t, node);
> + g_free(t);
> + }
> #ifndef CONFIG_USER_ONLY
> if (cpu->pmu_timer) {
> timer_free(cpu->pmu_timer);
> --
> 2.53.0
>
>
Reviewed-by: Sebastian Ott <sebott@redhat.com>
Hi Sebastian,
On 3/6/26 11:28 AM, Sebastian Ott wrote:
> On Wed, 4 Mar 2026, Eric Auger wrote:
>> We introduce a datatype for a tolerance with respect to a given
>> cpreg migration issue. The tolerance applies to a given cpreg kvm index,
>> and can be of different types:
>> - ToleranceNotOnBothEnds (cpreg index is allowed to be only on one end)
> ^
> available/present?
>
>> - ToleranceDiffInMask (value differences are allowed only within a mask)
>> - ToleranceFieldLT (incoming field value must be less than a given
>> value)
>> - ToleranceFieldGT (incoming field value must be greater than a given
>> value)
>>
>> A QLIST of such tolerances can be populated using a new helper:
>> arm_register_cpreg_mig_tolerance() and arm_cpu_cpreg_has_mig_tolerance()
>> allows to check whether a tolerance exists for a given kvm index.
>>
>> callers for those helpers will be introduced in subsequent patches.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> ---
>> target/arm/cpu.h | 32 +++++++++++++++++++++
>> target/arm/cpu.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 107 insertions(+)
>>
>> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
>> index 657ff4ab20b..9dcc838f611 100644
>> --- a/target/arm/cpu.h
>> +++ b/target/arm/cpu.h
>> @@ -843,6 +843,21 @@ struct ARMELChangeHook {
>> QLIST_ENTRY(ARMELChangeHook) node;
>> };
>>
>> +typedef enum {
>> + ToleranceNotOnBothEnds,
>> + ToleranceDiffInMask,
>> + ToleranceFieldLT,
>> + ToleranceFieldGT,
>> +} ARMCPUCPREGMigToleranceType;
>> +
>> +typedef struct ARMCPUCPREGMigTolerance {
>> + uint64_t kvmidx;
>> + uint64_t mask;
>> + uint64_t value;
>> + ARMCPUCPREGMigToleranceType type;
>> + QLIST_ENTRY(ARMCPUCPREGMigTolerance) node;
>> +} ARMCPUCPREGMigTolerance;
>> +
>> /* These values map onto the return values for
>> * QEMU_PSCI_0_2_FN_AFFINITY_INFO */
>> typedef enum ARMPSCIState {
>> @@ -1139,6 +1154,7 @@ struct ArchCPU {
>>
>> QLIST_HEAD(, ARMELChangeHook) pre_el_change_hooks;
>> QLIST_HEAD(, ARMELChangeHook) el_change_hooks;
>> + QLIST_HEAD(, ARMCPUCPREGMigTolerance) cpreg_mig_tolerances;
>>
>> int32_t node_id; /* NUMA node this CPU belongs to */
>>
>> @@ -2632,6 +2648,22 @@ void arm_register_pre_el_change_hook(ARMCPU
>> *cpu, ARMELChangeHookFn *hook,
>> void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn
>> *hook, void
>> *opaque);
>>
>> +/**
>> + * arm_register_cpreg_mig_tolerance:
>> + * Register a migration tolerance wrt one given cpreg identified by its
>> + * @kvmidx. Only one tolerance can be registered by kvm reg idx.
>> + */
>> +void arm_register_cpreg_mig_tolerance(ARMCPU *cpu, uint64_t kvmidx,
>> + uint64_t mask, uint64_t value,
>> + ARMCPUCPREGMigToleranceType
>> type);
>> +
>> +/**
>> + * arm_cpu_cpreg_has_mig_tolerance:
>> + * Check whether a tolerance of type @type exists for a given @kvmidx
>> + */
>
> This function does more than the name and description suggests - it not
> only checks if the tolerance exists but also if it applies..
>
> arm_cpu_cpreg_mig_tolerated ?
Well it is supposed to really check a tolerance exists (and thus
applies), of a given type, for a given kvmidx.
But I admit the check of ->type versus type is missing below.
>
>> +bool arm_cpu_cpreg_has_mig_tolerance(ARMCPU *cpu, uint64_t kvmidx,
>> + uint64_t vmstate_value,
>> uint64_t local_value,
>> + ARMCPUCPREGMigToleranceType type);
>> /**
>> * arm_rebuild_hflags:
>> * Rebuild the cached TBFLAGS for arbitrary changed processor state.
>> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
>> index 7e3e84b4bbb..1c499d1b15c 100644
>> --- a/target/arm/cpu.c
>> +++ b/target/arm/cpu.c
>> @@ -181,6 +181,75 @@ void arm_register_el_change_hook(ARMCPU *cpu,
>> ARMELChangeHookFn *hook,
>> QLIST_INSERT_HEAD(&cpu->el_change_hooks, entry, node);
>> }
>>
>> +void arm_register_cpreg_mig_tolerance(ARMCPU *cpu, uint64_t kvmidx,
>> + uint64_t mask, uint64_t value,
>> + ARMCPUCPREGMigToleranceType type)
>> +{
>> + ARMCPUCPREGMigTolerance *t, *entry;
>> +
>> + /* make sure the kvmidx has not tolerance already registered */
>> + QLIST_FOREACH(t, &cpu->cpreg_mig_tolerances, node) {
>> + if (t->kvmidx == kvmidx) {
>> + g_assert_not_reached();
>> + }
>> + }
>> + entry = g_new0(ARMCPUCPREGMigTolerance, 1);
>> +
>> + entry->kvmidx = kvmidx;
>> + entry->mask = mask;
>> + entry->value = value;
>> + entry->type = type;
>> +
>> + QLIST_INSERT_HEAD(&cpu->cpreg_mig_tolerances, entry, node);
>> +}
>> +
>> +bool arm_cpu_cpreg_has_mig_tolerance(ARMCPU *cpu, uint64_t kvmidx,
>> + uint64_t vmstate_value,
>> uint64_t local_value,
>> + ARMCPUCPREGMigToleranceType type)
>> +{
>> + ARMCPUCPREGMigTolerance *t;
>> + uint64_t diff, diff_outside_mask, field;
>> + bool found = false;
>> +
>> + QLIST_FOREACH(t, &cpu->cpreg_mig_tolerances, node) {
>> + if (t->kvmidx == kvmidx) {
>> + found = true;
>> + break;
>> + }
>> + }
>> + if (!found) {
>> + return false;
>> + }
>> +
>> + /* we found one tolerance associated to the @kvmidx */
>> +
>> + if (type == ToleranceNotOnBothEnds) {
>
> This should use t->type and type can be removed as an argument.
Actually if we found a tolerance registered for this regidx, I should
test the @type matches the registered tolerance once. This is missing.
>
>> + return true;
>> + }
>> +
>> + /* Need to check mask */
>> + diff = vmstate_value ^ local_value;
>> + diff_outside_mask = diff & ~t->mask;
>> +
>> + if (diff_outside_mask) {
>> + /* there are differences outside of the mask */
>> + return false;
>> + }
>> + if (type == ToleranceDiffInMask) {
>> + /* differences only in the field, tolerance granted */
>> + return true;
>> + }
>> + /* need to compare field value against authorized ones */
>> + field = vmstate_value & t->mask;
>> + if (type == ToleranceFieldLT && (field < t->value)) {
>> + return true;
>> + }
>> + if (type == ToleranceFieldGT && (field > t->value)) {
>> + return true;
>> + }
>
> Ah, so this is only compared with a static value not with the
> local_value.
> Would there be a need for a more sophisticated check than
> ToleranceDiffInMask?
>
> We could instead of having the type per ARMCPUCPREGMigTolerance
> register a
> callback that makes the decision. The 4 types would be 4 pre-defined
> callbacks and if a user needs something more sophisticated it can create
> a custom callback.
The goal is to tolerate some differences in a fields versus a given
static value. For instance if we know a field value was corrected in the
kernel.
This we have no example of such usage, it is a bit difficult to provide
a comprehensive infra. Maybe I should even remove that code until we get
the need.
>
> But yea, that's just an idea - not sure if we'll ever need something like
> this..
>
>> + return false;
>> +}
>> +
>> static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
>> {
>> /* Reset a single ARMCPRegInfo register */
>> @@ -1106,6 +1175,7 @@ static void arm_cpu_initfn(Object *obj)
>>
>> QLIST_INIT(&cpu->pre_el_change_hooks);
>> QLIST_INIT(&cpu->el_change_hooks);
>> + QLIST_INIT(&cpu->cpreg_mig_tolerances);
>>
>> #ifdef CONFIG_USER_ONLY
>> # ifdef TARGET_AARCH64
>> @@ -1550,6 +1620,7 @@ static void arm_cpu_finalizefn(Object *obj)
>> {
>> ARMCPU *cpu = ARM_CPU(obj);
>> ARMELChangeHook *hook, *next;
>> + ARMCPUCPREGMigTolerance *t, *n;
>>
>> g_hash_table_destroy(cpu->cp_regs);
>>
>> @@ -1561,6 +1632,10 @@ static void arm_cpu_finalizefn(Object *obj)
>> QLIST_REMOVE(hook, node);
>> g_free(hook);
>> }
>> + QLIST_FOREACH_SAFE(t, &cpu->cpreg_mig_tolerances, node, n) {
>> + QLIST_REMOVE(t, node);
>> + g_free(t);
>> + }
>> #ifndef CONFIG_USER_ONLY
>> if (cpu->pmu_timer) {
>> timer_free(cpu->pmu_timer);
>> --
>> 2.53.0
>>
>>
>
> Reviewed-by: Sebastian Ott <sebott@redhat.com>
>
Thank you for the review
Eric
© 2016 - 2026 Red Hat, Inc.