Prior to v10.1, if requested by user, arch-capabilities is always on
despite the fact that CPUID advertises it to be off/unvailable.
this causes a migration issue for VMs that are run on a machine
without arch-capabilities and expect this feature to be present
on the destination host with QEMU 10.1.
This commit add a compatibility property to restore the legacy
behavior for all machines with version prior to 10.1
Signed-off-by: Hector Cao <hector.cao@canonical.com>
---
hw/core/machine.c | 1 +
migration/migration.h | 12 ++++++++++++
migration/options.c | 3 +++
target/i386/kvm/kvm.c | 5 ++++-
4 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 38c949c4f2..8ad5d79cb3 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -45,6 +45,7 @@ GlobalProperty hw_compat_10_0[] = {
{ "vfio-pci", "x-migration-load-config-after-iter", "off" },
{ "ramfb", "use-legacy-x86-rom", "true"},
{ "vfio-pci-nohotplug", "use-legacy-x86-rom", "true" },
+ { "migration", "arch-cap-always-on", "true" },
};
const size_t hw_compat_10_0_len = G_N_ELEMENTS(hw_compat_10_0);
diff --git a/migration/migration.h b/migration/migration.h
index 01329bf824..5124ff3636 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -510,6 +510,18 @@ struct MigrationState {
bool rdma_migration;
GSource *hup_source;
+
+ /*
+ * This variable allows to keep the backward compatibility with QEMU (<10.1)
+ * on the arch-capabilities detection.
+ * With the commit d3a2413 (since 10.1), the arch-capabilities feature is gated
+ * with the CPUID bit (CPUID_7_0_EDX_ARCH_CAPABILITIES) instead of being always
+ * enabled when user requests for it. this new behavior breaks migration of VMs
+ * created and run with older QEMU on machines without IA32_ARCH_CAPABILITIES MSR,
+ * those VMs might have arch-capabilities enabled and break when migrating
+ * to a host with QEMU 10.1 with error : missing feature arch-capabilities
+ */
+ bool arch_cap_always_on;
};
void migrate_set_state(MigrationStatus *state, MigrationStatus old_state,
diff --git a/migration/options.c b/migration/options.c
index 4e923a2e07..3a80dba9c5 100644
--- a/migration/options.c
+++ b/migration/options.c
@@ -203,6 +203,9 @@ const Property migration_properties[] = {
MIGRATION_CAPABILITY_SWITCHOVER_ACK),
DEFINE_PROP_MIG_CAP("x-dirty-limit", MIGRATION_CAPABILITY_DIRTY_LIMIT),
DEFINE_PROP_MIG_CAP("mapped-ram", MIGRATION_CAPABILITY_MAPPED_RAM),
+
+ DEFINE_PROP_BOOL("arch-cap-always-on", MigrationState,
+ arch_cap_always_on, false),
};
const size_t migration_properties_count = ARRAY_SIZE(migration_properties);
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 306430a052..e2ec4e6de5 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -42,6 +42,7 @@
#include "xen-emu.h"
#include "hyperv.h"
#include "hyperv-proto.h"
+#include "migration/migration.h"
#include "gdbstub/enums.h"
#include "qemu/host-utils.h"
@@ -438,6 +439,7 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
uint32_t ret = 0;
uint32_t cpuid_1_edx, unused;
uint64_t bitmask;
+ MigrationState *ms = migrate_get_current();
cpuid = get_supported_cpuid(s);
@@ -508,7 +510,8 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
* mcahines at all, do not show the fake ARCH_CAPABILITIES MSR that
* KVM sets up.
*/
- if (!has_msr_arch_capabs || !(edx & CPUID_7_0_EDX_ARCH_CAPABILITIES)) {
+ if (!has_msr_arch_capabs
+ || (!(edx & CPUID_7_0_EDX_ARCH_CAPABILITIES) && (!ms->arch_cap_always_on))) {
ret &= ~CPUID_7_0_EDX_ARCH_CAPABILITIES;
}
} else if (function == 7 && index == 1 && reg == R_EAX) {
--
2.45.2
CC Paolo as maintainer On Wed, Sep 10, 2025 at 01:57:32PM +0200, Hector Cao wrote: > Prior to v10.1, if requested by user, arch-capabilities is always on > despite the fact that CPUID advertises it to be off/unvailable. > this causes a migration issue for VMs that are run on a machine > without arch-capabilities and expect this feature to be present > on the destination host with QEMU 10.1. > > This commit add a compatibility property to restore the legacy > behavior for all machines with version prior to 10.1 > Can you add a 'Fixes: <hash>' line to refer to the orignial commit in 10.1 that introduced the regression. > Signed-off-by: Hector Cao <hector.cao@canonical.com> > --- > hw/core/machine.c | 1 + > migration/migration.h | 12 ++++++++++++ > migration/options.c | 3 +++ > target/i386/kvm/kvm.c | 5 ++++- > 4 files changed, 20 insertions(+), 1 deletion(-) > > diff --git a/hw/core/machine.c b/hw/core/machine.c > index 38c949c4f2..8ad5d79cb3 100644 > --- a/hw/core/machine.c > +++ b/hw/core/machine.c > @@ -45,6 +45,7 @@ GlobalProperty hw_compat_10_0[] = { > { "vfio-pci", "x-migration-load-config-after-iter", "off" }, > { "ramfb", "use-legacy-x86-rom", "true"}, > { "vfio-pci-nohotplug", "use-legacy-x86-rom", "true" }, > + { "migration", "arch-cap-always-on", "true" }, > }; > const size_t hw_compat_10_0_len = G_N_ELEMENTS(hw_compat_10_0); > > diff --git a/migration/migration.h b/migration/migration.h > index 01329bf824..5124ff3636 100644 > --- a/migration/migration.h > +++ b/migration/migration.h > @@ -510,6 +510,18 @@ struct MigrationState { > bool rdma_migration; > > GSource *hup_source; > + > + /* > + * This variable allows to keep the backward compatibility with QEMU (<10.1) > + * on the arch-capabilities detection. > + * With the commit d3a2413 (since 10.1), the arch-capabilities feature is gated > + * with the CPUID bit (CPUID_7_0_EDX_ARCH_CAPABILITIES) instead of being always > + * enabled when user requests for it. this new behavior breaks migration of VMs > + * created and run with older QEMU on machines without IA32_ARCH_CAPABILITIES MSR, > + * those VMs might have arch-capabilities enabled and break when migrating > + * to a host with QEMU 10.1 with error : missing feature arch-capabilities > + */ > + bool arch_cap_always_on; > }; > > void migrate_set_state(MigrationStatus *state, MigrationStatus old_state, > diff --git a/migration/options.c b/migration/options.c > index 4e923a2e07..3a80dba9c5 100644 > --- a/migration/options.c > +++ b/migration/options.c > @@ -203,6 +203,9 @@ const Property migration_properties[] = { > MIGRATION_CAPABILITY_SWITCHOVER_ACK), > DEFINE_PROP_MIG_CAP("x-dirty-limit", MIGRATION_CAPABILITY_DIRTY_LIMIT), > DEFINE_PROP_MIG_CAP("mapped-ram", MIGRATION_CAPABILITY_MAPPED_RAM), > + > + DEFINE_PROP_BOOL("arch-cap-always-on", MigrationState, > + arch_cap_always_on, false), > }; > const size_t migration_properties_count = ARRAY_SIZE(migration_properties); > > diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c > index 306430a052..e2ec4e6de5 100644 > --- a/target/i386/kvm/kvm.c > +++ b/target/i386/kvm/kvm.c > @@ -42,6 +42,7 @@ > #include "xen-emu.h" > #include "hyperv.h" > #include "hyperv-proto.h" > +#include "migration/migration.h" > > #include "gdbstub/enums.h" > #include "qemu/host-utils.h" > @@ -438,6 +439,7 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function, > uint32_t ret = 0; > uint32_t cpuid_1_edx, unused; > uint64_t bitmask; > + MigrationState *ms = migrate_get_current(); > > cpuid = get_supported_cpuid(s); > > @@ -508,7 +510,8 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function, > * mcahines at all, do not show the fake ARCH_CAPABILITIES MSR that > * KVM sets up. > */ > - if (!has_msr_arch_capabs || !(edx & CPUID_7_0_EDX_ARCH_CAPABILITIES)) { > + if (!has_msr_arch_capabs > + || (!(edx & CPUID_7_0_EDX_ARCH_CAPABILITIES) && (!ms->arch_cap_always_on))) { > ret &= ~CPUID_7_0_EDX_ARCH_CAPABILITIES; > } > } else if (function == 7 && index == 1 && reg == R_EAX) { > -- > 2.45.2 > > With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
On Tue, Sep 16, 2025 at 10:13 AM Daniel P. Berrangé <berrange@redhat.com> wrote: > CC Paolo as maintainer > > On Wed, Sep 10, 2025 at 01:57:32PM +0200, Hector Cao wrote: > > Prior to v10.1, if requested by user, arch-capabilities is always on > > despite the fact that CPUID advertises it to be off/unvailable. > > this causes a migration issue for VMs that are run on a machine > > without arch-capabilities and expect this feature to be present > > on the destination host with QEMU 10.1. > > > > This commit add a compatibility property to restore the legacy > > behavior for all machines with version prior to 10.1 > > > > Can you add a 'Fixes: <hash>' line to refer to the orignial > commit in 10.1 that introduced the regression. > Thanks Daniel for the feedback, Since this patch is a PoC at the moment, I will submit the final one later once I have enough feedback Here is the line I will add to this patch header: Fixes: d3a2413 > > > Signed-off-by: Hector Cao <hector.cao@canonical.com> > > --- > > hw/core/machine.c | 1 + > > migration/migration.h | 12 ++++++++++++ > > migration/options.c | 3 +++ > > target/i386/kvm/kvm.c | 5 ++++- > > 4 files changed, 20 insertions(+), 1 deletion(-) > > > > diff --git a/hw/core/machine.c b/hw/core/machine.c > > index 38c949c4f2..8ad5d79cb3 100644 > > --- a/hw/core/machine.c > > +++ b/hw/core/machine.c > > @@ -45,6 +45,7 @@ GlobalProperty hw_compat_10_0[] = { > > { "vfio-pci", "x-migration-load-config-after-iter", "off" }, > > { "ramfb", "use-legacy-x86-rom", "true"}, > > { "vfio-pci-nohotplug", "use-legacy-x86-rom", "true" }, > > + { "migration", "arch-cap-always-on", "true" }, > > }; > > const size_t hw_compat_10_0_len = G_N_ELEMENTS(hw_compat_10_0); > > > > diff --git a/migration/migration.h b/migration/migration.h > > index 01329bf824..5124ff3636 100644 > > --- a/migration/migration.h > > +++ b/migration/migration.h > > @@ -510,6 +510,18 @@ struct MigrationState { > > bool rdma_migration; > > > > GSource *hup_source; > > + > > + /* > > + * This variable allows to keep the backward compatibility with > QEMU (<10.1) > > + * on the arch-capabilities detection. > > + * With the commit d3a2413 (since 10.1), the arch-capabilities > feature is gated > > + * with the CPUID bit (CPUID_7_0_EDX_ARCH_CAPABILITIES) instead of > being always > > + * enabled when user requests for it. this new behavior breaks > migration of VMs > > + * created and run with older QEMU on machines without > IA32_ARCH_CAPABILITIES MSR, > > + * those VMs might have arch-capabilities enabled and break when > migrating > > + * to a host with QEMU 10.1 with error : missing feature > arch-capabilities > > + */ > > + bool arch_cap_always_on; > > }; > > > > void migrate_set_state(MigrationStatus *state, MigrationStatus > old_state, > > diff --git a/migration/options.c b/migration/options.c > > index 4e923a2e07..3a80dba9c5 100644 > > --- a/migration/options.c > > +++ b/migration/options.c > > @@ -203,6 +203,9 @@ const Property migration_properties[] = { > > MIGRATION_CAPABILITY_SWITCHOVER_ACK), > > DEFINE_PROP_MIG_CAP("x-dirty-limit", > MIGRATION_CAPABILITY_DIRTY_LIMIT), > > DEFINE_PROP_MIG_CAP("mapped-ram", MIGRATION_CAPABILITY_MAPPED_RAM), > > + > > + DEFINE_PROP_BOOL("arch-cap-always-on", MigrationState, > > + arch_cap_always_on, false), > > }; > > const size_t migration_properties_count = > ARRAY_SIZE(migration_properties); > > > > diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c > > index 306430a052..e2ec4e6de5 100644 > > --- a/target/i386/kvm/kvm.c > > +++ b/target/i386/kvm/kvm.c > > @@ -42,6 +42,7 @@ > > #include "xen-emu.h" > > #include "hyperv.h" > > #include "hyperv-proto.h" > > +#include "migration/migration.h" > > > > #include "gdbstub/enums.h" > > #include "qemu/host-utils.h" > > @@ -438,6 +439,7 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, > uint32_t function, > > uint32_t ret = 0; > > uint32_t cpuid_1_edx, unused; > > uint64_t bitmask; > > + MigrationState *ms = migrate_get_current(); > > > > cpuid = get_supported_cpuid(s); > > > > @@ -508,7 +510,8 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, > uint32_t function, > > * mcahines at all, do not show the fake ARCH_CAPABILITIES MSR > that > > * KVM sets up. > > */ > > - if (!has_msr_arch_capabs || !(edx & > CPUID_7_0_EDX_ARCH_CAPABILITIES)) { > > + if (!has_msr_arch_capabs > > + || (!(edx & CPUID_7_0_EDX_ARCH_CAPABILITIES) && > (!ms->arch_cap_always_on))) { > > ret &= ~CPUID_7_0_EDX_ARCH_CAPABILITIES; > > } > > } else if (function == 7 && index == 1 && reg == R_EAX) { > > -- > > 2.45.2 > > > > > > With regards, > Daniel > -- > |: https://berrange.com -o- > https://www.flickr.com/photos/dberrange :| > |: https://libvirt.org -o- > https://fstop138.berrange.com :| > |: https://entangle-photo.org -o- > https://www.instagram.com/dberrange :| > > -- Hector CAO Software Engineer – Server Team / Virtualization hector.cao@canonical.com https://launc <https://launchpad.net/~hectorcao>hpad.net/~hectorcao <https://launchpad.net/~hectorcao> <https://launchpad.net/~hectorcao>
On Tue, Sep 16, 2025 at 10:29 AM Hector Cao <hector.cao@canonical.com> wrote: > > > On Tue, Sep 16, 2025 at 10:13 AM Daniel P. Berrangé <berrange@redhat.com> > wrote: > >> CC Paolo as maintainer >> >> On Wed, Sep 10, 2025 at 01:57:32PM +0200, Hector Cao wrote: >> > Prior to v10.1, if requested by user, arch-capabilities is always on >> > despite the fact that CPUID advertises it to be off/unvailable. >> > this causes a migration issue for VMs that are run on a machine >> > without arch-capabilities and expect this feature to be present >> > on the destination host with QEMU 10.1. >> > >> > This commit add a compatibility property to restore the legacy >> > behavior for all machines with version prior to 10.1 >> > >> >> Can you add a 'Fixes: <hash>' line to refer to the orignial >> commit in 10.1 that introduced the regression. >> > > Thanks Daniel for the feedback, > > Since this patch is a PoC at the moment, I will submit the final one > later once I have enough feedback > > Here is the line I will add to this patch header: > > Fixes: d3a2413 > Hi Paolo, Daniel and qemu-dev’s, Sorry to bother you with pings over and over on this .. But to help you understand, the Ubuntu 25.10 release is soon to happen in 2.5 weeks. And while it is already too late to fix 10.1 before being released it is our chance to still fix what we will ship with Ubuntu 25.10. Tomorrow (24th Sept) is the day we need to decide if we will pick the proposed patch for Ubuntu 25.10 or leave it broken, not being able to migrate to it from older Ubuntu/Qemu releases, or any other path forward. Therefore once more, if there could be some reaction, your judgement of the overall situation or your assumptions how this will eventually conclude - any of that will help us to decide for Ubuntu. We have been expecting more of a discussion - in fact we mostly rushed to get something for discussion out and not spend a long time on every line to be in final form. So far the feedback has been great but mostly useful small process suggestions. As Hector said these will be done when doing the non-RFC submission. But maybe we mis-interpreted the lack of discussion as being dormant, while you actually have been ok except for these mechanical things? I’ll ask Hector to resubmit as non-RFC today. > > >> >> > Signed-off-by: Hector Cao <hector.cao@canonical.com> >> > --- >> > hw/core/machine.c | 1 + >> > migration/migration.h | 12 ++++++++++++ >> > migration/options.c | 3 +++ >> > target/i386/kvm/kvm.c | 5 ++++- >> > 4 files changed, 20 insertions(+), 1 deletion(-) >> > >> > diff --git a/hw/core/machine.c b/hw/core/machine.c >> > index 38c949c4f2..8ad5d79cb3 100644 >> > --- a/hw/core/machine.c >> > +++ b/hw/core/machine.c >> > @@ -45,6 +45,7 @@ GlobalProperty hw_compat_10_0[] = { >> > { "vfio-pci", "x-migration-load-config-after-iter", "off" }, >> > { "ramfb", "use-legacy-x86-rom", "true"}, >> > { "vfio-pci-nohotplug", "use-legacy-x86-rom", "true" }, >> > + { "migration", "arch-cap-always-on", "true" }, >> > }; >> > const size_t hw_compat_10_0_len = G_N_ELEMENTS(hw_compat_10_0); >> > >> > diff --git a/migration/migration.h b/migration/migration.h >> > index 01329bf824..5124ff3636 100644 >> > --- a/migration/migration.h >> > +++ b/migration/migration.h >> > @@ -510,6 +510,18 @@ struct MigrationState { >> > bool rdma_migration; >> > >> > GSource *hup_source; >> > + >> > + /* >> > + * This variable allows to keep the backward compatibility with >> QEMU (<10.1) >> > + * on the arch-capabilities detection. >> > + * With the commit d3a2413 (since 10.1), the arch-capabilities >> feature is gated >> > + * with the CPUID bit (CPUID_7_0_EDX_ARCH_CAPABILITIES) instead of >> being always >> > + * enabled when user requests for it. this new behavior breaks >> migration of VMs >> > + * created and run with older QEMU on machines without >> IA32_ARCH_CAPABILITIES MSR, >> > + * those VMs might have arch-capabilities enabled and break when >> migrating >> > + * to a host with QEMU 10.1 with error : missing feature >> arch-capabilities >> > + */ >> > + bool arch_cap_always_on; >> > }; >> > >> > void migrate_set_state(MigrationStatus *state, MigrationStatus >> old_state, >> > diff --git a/migration/options.c b/migration/options.c >> > index 4e923a2e07..3a80dba9c5 100644 >> > --- a/migration/options.c >> > +++ b/migration/options.c >> > @@ -203,6 +203,9 @@ const Property migration_properties[] = { >> > MIGRATION_CAPABILITY_SWITCHOVER_ACK), >> > DEFINE_PROP_MIG_CAP("x-dirty-limit", >> MIGRATION_CAPABILITY_DIRTY_LIMIT), >> > DEFINE_PROP_MIG_CAP("mapped-ram", MIGRATION_CAPABILITY_MAPPED_RAM), >> > + >> > + DEFINE_PROP_BOOL("arch-cap-always-on", MigrationState, >> > + arch_cap_always_on, false), >> > }; >> > const size_t migration_properties_count = >> ARRAY_SIZE(migration_properties); >> > >> > diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c >> > index 306430a052..e2ec4e6de5 100644 >> > --- a/target/i386/kvm/kvm.c >> > +++ b/target/i386/kvm/kvm.c >> > @@ -42,6 +42,7 @@ >> > #include "xen-emu.h" >> > #include "hyperv.h" >> > #include "hyperv-proto.h" >> > +#include "migration/migration.h" >> > >> > #include "gdbstub/enums.h" >> > #include "qemu/host-utils.h" >> > @@ -438,6 +439,7 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, >> uint32_t function, >> > uint32_t ret = 0; >> > uint32_t cpuid_1_edx, unused; >> > uint64_t bitmask; >> > + MigrationState *ms = migrate_get_current(); >> > >> > cpuid = get_supported_cpuid(s); >> > >> > @@ -508,7 +510,8 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, >> uint32_t function, >> > * mcahines at all, do not show the fake ARCH_CAPABILITIES MSR >> that >> > * KVM sets up. >> > */ >> > - if (!has_msr_arch_capabs || !(edx & >> CPUID_7_0_EDX_ARCH_CAPABILITIES)) { >> > + if (!has_msr_arch_capabs >> > + || (!(edx & CPUID_7_0_EDX_ARCH_CAPABILITIES) && >> (!ms->arch_cap_always_on))) { >> > ret &= ~CPUID_7_0_EDX_ARCH_CAPABILITIES; >> > } >> > } else if (function == 7 && index == 1 && reg == R_EAX) { >> > -- >> > 2.45.2 >> > >> > >> >> With regards, >> Daniel >> -- >> |: https://berrange.com -o- >> https://www.flickr.com/photos/dberrange :| >> |: https://libvirt.org -o- >> https://fstop138.berrange.com :| >> |: https://entangle-photo.org -o- >> https://www.instagram.com/dberrange :| >> >> > > -- > Hector CAO > Software Engineer – Server Team / Virtualization > hector.cao@canonical.com > https://launc <https://launchpad.net/~hectorcao>hpad.net/~hectorcao > <https://launchpad.net/~hectorcao> > > <https://launchpad.net/~hectorcao> > -- Christian Ehrhardt Director of Engineering, Ubuntu Server Canonical Ltd
© 2016 - 2025 Red Hat, Inc.