From: "Denis V. Lunev" <den@openvz.org>
To: andrey.drobyshev@virtuozzo.com
Cc: svt-core@virtuozzo.com, den@openvz.org
Subject: [PATCH hci-8.0/hci-8.1] i386: hide la57 at fresh start on vz machine types up to vz10.0.0 #VSTOR-152405
Date: Thu, 29 Oct 2026 18:42:21 +0100 [thread overview]
Message-ID: <20261029174221.1068858-1-den@openvz.org> (raw)
From: Denis V. Lunev <den@openvz.org>
The vz10 OVMF enables 5-level paging whenever the CPU has la57, so on
AMD EPYC 9004/9005 hosts with "-cpu host" Windows boots its LA57
kernel. That kernel bugchecks with UNSUPPORTED_PROCESSOR on the Intel
only ARCH_CAPABILITIES MSR, which pc-q35-vz10.0.0 and older still show
to AMD guests (x-arch-cap-always-on). There is no IDT yet, so the guest
triple-faults and reboots in a loop (ASUP-3871). The vz9 OVMF never
used 5-level paging, so these guests did not see this before.
Add x-no-la57-on-start and turn it on in pc_vz_10_0_compat, which
covers vz10.0.0 and every older vz machine type. On a fresh start a
"-cpu host" guest loses la57 unless la57=on is given explicitly. The
bit is reported in filtered-features, so libvirt writes la57=off into
the live definition and migration, save and snapshots carry it.
An incoming QEMU keeps la57: a guest from an older node may already run
with CR4.LA57 set. A hotplugged vCPU follows the boot vCPUs. Named CPU
models are not touched, la57 is part of their definition.
Signed-off-by: Denis V. Lunev <den@openvz.org>
---
The patch applies to hci-8.0 without changes; the base given below is
hci-dev, on top of "i386: keep CPU features of guests from older nodes
on vz machine types".
Customer case ASUP-3871, bug VSTOR-152405. New VMs get vz10.0.0 only
because nova pins it instead of using the q35 alias; that is
VSTOR-152413. pc-q35-vz10.1.0 already hides ARCH_CAPABILITIES on AMD and
is not touched here.
Testing, hci-8.0 build, bg-sdc2-e19-07 (EPYC 9355, VHI 8.0.0 packages):
- -cpu host, fresh start: la57 hidden and listed in
unavailable-features on vz10.0.0 and vz9.2.0; kept with la57=on,
on vz10.1.0 and with EPYC-Genoa.
- live migration from stock qemu-kvm 10.1.0-20.vz10.16 to the patched
binary: completes, la57 kept on the destination.
- vCPU hotplug follows the boot vCPU, after a fresh start and after an
incoming migration.
- Windows Server 2025 GA ISO (26100.1742) with the nova command line of
the customer VM, pc-q35-vz10.0.0, -cpu host and the Hyper-V
enlightenments: OVMF stays in 4-level paging and Setup starts. Stock
qemu-kvm triple-faults there with bugcheck 0x5D (MSR 0x10a).
- Not tested: libvirt writing la57=off into the live XML and carrying
it to the destination. That follows from virCPUx86UpdateLive for
host-passthrough with check='none' and does not depend on the libvirt
relaxations dropped in libvirt.ovz PR 392.
hw/i386/pc.c | 5 +++++
hw/i386/pc_piix.c | 2 +-
hw/i386/pc_q35.c | 2 +-
include/hw/i386/pc.h | 3 +++
target/i386/cpu.c | 27 +++++++++++++++++++++++++++
target/i386/cpu.h | 6 ++++++
6 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 9b6b51bd5f7..2834982dab4 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -548,6 +548,11 @@ GlobalProperty pc_vz_compat[] = {
};
const size_t pc_vz_compat_len = G_N_ELEMENTS(pc_vz_compat);
+GlobalProperty pc_vz_10_0_compat[] = {
+ { TYPE_X86_CPU, "x-no-la57-on-start", "on" },
+};
+const size_t pc_vz_10_0_compat_len = G_N_ELEMENTS(pc_vz_10_0_compat);
+
GlobalProperty pc_vz_9_2_compat[] = {
{ TYPE_X86_CPU, "x-tsx-compat", "on" },
{ TYPE_X86_CPU, "x-spec-ctrl-compat", "on" },
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index b1b595078eb..ab29ea0cd12 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -1057,7 +1057,7 @@ DEFINE_I440FX_RHEL_MACHINE(7, 2, 0);
/* maj min mic basemt isdefault */
#define VZ_PC_MT(X) \
X(10, 1, 0, MT_VER_SYM(10, 0, 0), true) \
- X(10, 0, 0, MT_VER_SYM(10, 0, 0), false) \
+ X(10, 0, 0, MT_VER_SYM(10, 0, 0), false, pc_vz_10_0_compat) \
X(7, 16, 0, MT_VER_SYM(7, 6, 0), false, pc_vz_9_2_compat, \
hw_compat_vz_9_1, \
hw_compat_vz_7_16, \
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 019239bec6a..51539f22399 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -973,7 +973,7 @@ DEFINE_Q35_RHEL_MACHINE(7, 3, 0);
/* maj min mic basemt isdefault */
#define VZ_Q35_MT(X) \
X(10, 1, 0, MT_VER_SYM(10, 2, 0), true) \
- X(10, 0, 0, MT_VER_SYM(10, 0, 0), false) \
+ X(10, 0, 0, MT_VER_SYM(10, 0, 0), false, pc_vz_10_0_compat) \
X(9, 2, 0, MT_VER_SYM(9, 6, 0), false, pc_vz_9_2_compat) \
X(9, 1, 0, MT_VER_SYM(9, 4, 0), false, hw_compat_vz_9_1) \
X(9, 0, 0, MT_VER_SYM(9, 2, 0), false) \
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index bd73426644e..021b139b872 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -364,6 +364,9 @@ extern const size_t pc_rhel_7_2_compat_len;
extern GlobalProperty pc_vz_compat[];
extern const size_t pc_vz_compat_len;
+extern GlobalProperty pc_vz_10_0_compat[];
+extern const size_t pc_vz_10_0_compat_len;
+
extern GlobalProperty pc_vz_9_2_compat[];
extern const size_t pc_vz_9_2_compat_len;
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 29e7b4b7e15..8d2ce279a72 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -40,6 +40,7 @@
#ifndef CONFIG_USER_ONLY
#include "confidential-guest.h"
#include "system/reset.h"
+#include "system/runstate.h"
#include "qapi/qapi-commands-machine.h"
#include "system/address-spaces.h"
#include "hw/boards.h"
@@ -9107,6 +9108,27 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
}
}
+/*
+ * Reported as filtered, so that libvirt records la57=off in the live
+ * definition and passes it on to migration, save and snapshots.
+ */
+static bool x86_cpu_hide_la57(X86CPU *cpu)
+{
+ CPUX86State *env = &cpu->env;
+
+ if (!cpu->no_la57_on_start || !X86_CPU_GET_CLASS(cpu)->max_features ||
+ !kvm_enabled() ||
+ !(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_LA57) ||
+ (env->user_features[FEAT_7_0_ECX] & CPUID_7_0_ECX_LA57)) {
+ return false;
+ }
+ if (DEVICE(cpu)->hotplugged) {
+ return first_cpu && !(X86_CPU(first_cpu)->env.features[FEAT_7_0_ECX] &
+ CPUID_7_0_ECX_LA57);
+ }
+ return !runstate_check(RUN_STATE_INMIGRATE);
+}
+
/* Requested features that a vz compat property keeps despite the host */
static uint64_t x86_cpu_compat_kept_features(X86CPU *cpu, FeatureWord w)
{
@@ -9404,6 +9426,10 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
}
}
+ if (x86_cpu_hide_la57(cpu)) {
+ mark_unavailable_features(cpu, FEAT_7_0_ECX, CPUID_7_0_ECX_LA57, NULL);
+ }
+
/* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
* CPUID[1].EDX.
*/
@@ -10120,6 +10146,7 @@ static const Property x86_cpu_properties[] = {
bus_lock_detect_compat, false),
DEFINE_PROP_BOOL("x-v-vmsave-vmload-compat", X86CPU,
v_vmsave_vmload_compat, false),
+ DEFINE_PROP_BOOL("x-no-la57-on-start", X86CPU, no_la57_on_start, false),
DEFINE_PROP_BOOL("x-svm-features-compat", X86CPU,
svm_features_compat, false),
};
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 97e38013e46..5c1a692aca3 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2342,6 +2342,12 @@ struct ArchCPU {
bool v_vmsave_vmload_compat;
bool svm_features_compat;
+ /*
+ * Virtuozzo machine types up to vz10.0.0: hide la57 from "-cpu host"
+ * when the VM starts fresh, keep it on incoming migration.
+ */
+ bool no_la57_on_start;
+
/* Number of physical address bits supported */
uint32_t phys_bits;
base-commit: 02f55118bcb0533ce4c6544458c30803d96bea4a
--
2.53.0
next reply other threads:[~2026-10-29 17:42 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-29 17:42 Denis V. Lunev [this message]
2026-10-29 17:46 ` no-reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261029174221.1068858-1-den@openvz.org \
--to=den@openvz.org \
--cc=andrey.drobyshev@virtuozzo.com \
--cc=svt-core@virtuozzo.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.