All Virtuozzo development lists (kernel + QEMU)
 help / color / mirror / Atom feed
* [Devel] [PATCH hci-8.0/hci-8.1 0/6] i386: keep CPU features of guests from older nodes on vz machine types #VSTOR-152264
@ 2026-10-29  9:56 Denis V. Lunev
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 1/6] i386/pc: raise the limit of compat arrays per Virtuozzo machine type to four #VSTOR-152264 Denis V. Lunev
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Denis V. Lunev @ 2026-10-29  9:56 UTC (permalink / raw)
  To: andrey.zhadchenko; +Cc: devel

A guest started on an older node can have a CPU feature that the
destination host no longer offers: TSX disabled by microcode, a newer
kernel that stops offering spec-ctrl or bus-lock-detect on AMD, or SVM
leaf features that QEMU 2.12 on Vz7 kept with svm off. QEMU filters the
feature on the destination, and libvirt refuses the live migration,
restore or snapshot revert:

  guest CPU doesn't match specification: missing features: hle,rtm

The guest read its CPUID at boot, so the bit has to stay until the guest
restarts.

Until now libvirt relaxed the check, in three places that behave
differently. One of them crashes libvirtd on the destination of any
migration of a host-passthrough VM with a vz7 machine type
(VSTOR-152247). This series keeps the bits in QEMU instead: one
x-...-compat X86CPU property per feature, all turned on by a new
pc_vz_9_2_compat on vz9.2.0 and every older vz machine type. Those are
the types every guest started before 8.0 runs. vz10.x types and -cpu
host expansion stay strict. A property keeps a bit only when the CPU
model or the command line asks for it and the host condition in the
commit message holds; KVM ignores CPUID bits it does not support.

Patch 1 lets a row of the vz machine type tables name a fourth compat
array, which the i440fx vz7.16.0 row needs. Patches 2 to 6 add one
property each:

  2  hle, rtm                      PSBM-149402 (field: VSTOR-75689,
                                   VSTOR-105458)
  3  spec-ctrl, AMD                VSTOR-151770
  4  bus-lock-detect, AMD          VSTOR-152291
  5  v-vmsave-vmload, AMD          code review, nested guests on Zen 4
                                   client parts, no field report
  6  SVM leaf features, svm off    PSBM-144630

The same patches apply to hci-8.0 and hci-8.1 without changes; the
base given below is hci-dev. On 8.0 they also fix the migration on
their own: hci-8.0 libvirt keeps its relaxations, and they no longer
see a filtered bit. That covers bus-lock-detect (VSTOR-152291), which
hci-8.0 libvirt does not relax. The vz7 CPU fixup there still runs on
migration (with the NULL check from VSTOR-152247) and forces npt and
nrip-save off, which the guest does not see, because leaf 0x8000000a
is hidden without svm. Only the destination needs the new qemu-kvm:
the compat acts when the incoming QEMU process starts.

On hci-dev the libvirt side drops its relaxations and the qemu.d hooks
in libvirt.ovz pr/den-VSTOR-152247-drop-vz-cpu-relaxations. It needs
this series in qemu-kvm first.

Testing:
- dev-cl04, EPYC 7443P: a saved guest whose migration cookie CPU was
  rewritten to the shape of a Vz7 host-model guest
  (svm=off,npt=on,nrip-save=on, plus spec-ctrl) fails to restore
  without the series with "missing features: npt,nrip-save" and
  "missing features: spec-ctrl". With it the guest restores, the
  features stay on and filtered-features is empty. Stock 8.1 libvirt,
  which carries the same relaxations as hci-8.0, restores it with no
  warning as well.
- sqvm2-1015, Broadwell without TSX: the VSTOR-75689 guest CPU fails
  with "missing features: hle,rtm" without the series and keeps hle
  and rtm with it.
- sqvm2-1013 <-> sqvm2-1015, with the libvirt PR: live migration in
  both directions of a pc-i440fx-vz7.12.0 host-passthrough guest and
  of the VSTOR-75689 Broadwell-IBRS guest. No crash, no warning,
  hle/rtm kept, the CPU stays match='exact'. Stock libvirt crashes on
  the first of them.
- hci-8.0 and hci-8.1 builds: -cpu EPYC-Milan,svm=off,npt=on,
  nrip-save=on,enforce and -cpu EPYC-Milan,spec-ctrl=on,enforce start
  on vz7.12.0, vz9.0.0 and vz9.2.0 and are refused on vz10.x. A fresh
  Broadwell-IBRS start with check='full' is refused on vz10.1.0.
- bus-lock-detect and v-vmsave-vmload are build-tested only: no Zen 5
  or Zen 4 client host was available.

Signed-off-by: Denis V. Lunev <den@openvz.org>

Denis V. Lunev (6):
  i386/pc: raise the limit of compat arrays per Virtuozzo machine type
    to four #VSTOR-152264
  i386: keep hle and rtm on Virtuozzo machine types up to vz9.2.0
    #PSBM-149402
  i386: keep spec-ctrl for AMD guests on vz machine types up to vz9.2.0
    #VSTOR-151770
  i386: keep bus-lock-detect for AMD guests on vz machine types up to
    vz9.2.0 #VSTOR-152291
  i386: keep v-vmsave-vmload for nested AMD guests on vz types up to
    vz9.2.0 #VSTOR-152264
  i386: keep SVM leaf features without svm on vz types up to vz9.2.0
    #PSBM-144630

 hw/i386/pc.c         |  9 ++++++
 hw/i386/pc_piix.c    |  5 ++--
 hw/i386/pc_q35.c     |  4 +--
 include/hw/i386/pc.h | 10 +++++--
 target/i386/cpu.c    | 67 +++++++++++++++++++++++++++++++++++++++++++-
 target/i386/cpu.h    | 11 ++++++++
 6 files changed, 99 insertions(+), 7 deletions(-)


base-commit: 0c1497c79831c1ec8efd91d5887236963adf0f18
-- 
2.53.0

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Devel] [PATCH hci-8.0/hci-8.1 1/6] i386/pc: raise the limit of compat arrays per Virtuozzo machine type to four #VSTOR-152264
  2026-10-29  9:56 [Devel] [PATCH hci-8.0/hci-8.1 0/6] i386: keep CPU features of guests from older nodes on vz machine types #VSTOR-152264 Denis V. Lunev
@ 2026-10-29  9:56 ` Denis V. Lunev
  2026-10-29 10:00   ` no-reply
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 2/6] i386: keep hle and rtm on Virtuozzo machine types up to vz9.2.0 #PSBM-149402 Denis V. Lunev
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Denis V. Lunev @ 2026-10-29  9:56 UTC (permalink / raw)
  To: andrey.zhadchenko; +Cc: devel

From: Denis V. Lunev <den@openvz.org>

A row of VZ_Q35_MT or VZ_PC_MT can name at most three compat arrays:
COUNT_ARGS counts up to three, VZ_COMPATS_EXPAND has variants for zero
to three, and __vz_compat_props has three slots per row. No row needs
more yet, which is why the limit never showed. The i440fx vz7.16.0 row
uses all three (hw_compat_vz_9_1, hw_compat_vz_7_16,
pc_vz_7_16_compat), and the next commit adds pc_vz_9_2_compat to it.
With a fourth argument COUNT_ARGS returns that argument instead of a
count, and the build fails on an undefined VZ_COMPATS_EXPAND_<name>.

Raise the limit to four.

Signed-off-by: Denis V. Lunev <den@openvz.org>
---
 hw/i386/pc_piix.c    | 2 +-
 hw/i386/pc_q35.c     | 2 +-
 include/hw/i386/pc.h | 7 +++++--
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 9a73dcfad4b..1a50c2a645c 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -1087,7 +1087,7 @@ enum {
 static struct {
     GlobalProperty *prop;
     const size_t *len;
-} __vz_compat_props[][3] = {
+} __vz_compat_props[][4] = {
     { VZ_COMPATS_EXPAND(hw_compat_vz, pc_vz_compat) },
     VZ_PC_MT(AS_ARRAY)
 };
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 9bb0c7e1649..2f4a14b4e01 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -1004,7 +1004,7 @@ enum {
 static struct {
     GlobalProperty *prop;
     const size_t *len;
-} __vz_compat_props[][3] = {
+} __vz_compat_props[][4] = {
     { VZ_COMPATS_EXPAND(hw_compat_vz, pc_vz_compat) },
     VZ_Q35_MT(AS_ARRAY)
 };
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 5140c9c1f23..4d8a01528b8 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -428,8 +428,8 @@ extern const size_t pc_vz_7_4_compat_len;
 /*
  * Helper macros for defining VZ machine types, both pc and q35
  */
-#define _GET_NTH_ARG(_0, _1, _2, _3, N, ...) N
-#define COUNT_ARGS(...) _GET_NTH_ARG(__VA_ARGS__, 3, 2, 1, 0)
+#define _GET_NTH_ARG(_0, _1, _2, _3, _4, N, ...) N
+#define COUNT_ARGS(...) _GET_NTH_ARG(__VA_ARGS__, 4, 3, 2, 1, 0)
 
 #define VZ_COMPATS_EXPAND_0()
 #define VZ_COMPATS_EXPAND_1(prop1) {prop1, &prop1##_len}
@@ -437,6 +437,9 @@ extern const size_t pc_vz_7_4_compat_len;
     {prop1, &prop1##_len}, {prop2, &prop2##_len}
 #define VZ_COMPATS_EXPAND_3(prop1, prop2, prop3)  \
     {prop1, &prop1##_len}, {prop2, &prop2##_len}, {prop3, &prop3##_len}
+#define VZ_COMPATS_EXPAND_4(prop1, prop2, prop3, prop4)  \
+    {prop1, &prop1##_len}, {prop2, &prop2##_len}, {prop3, &prop3##_len}, \
+    {prop4, &prop4##_len}
 
 #define VZ_COMPATS_EXPAND_N(n, ...) VZ_COMPATS_EXPAND_##n(__VA_ARGS__)
 #define VZ_COMPATS_EXPAND_(n, ...)  VZ_COMPATS_EXPAND_N(n, __VA_ARGS__)
-- 
2.53.0

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Devel] [PATCH hci-8.0/hci-8.1 2/6] i386: keep hle and rtm on Virtuozzo machine types up to vz9.2.0 #PSBM-149402
  2026-10-29  9:56 [Devel] [PATCH hci-8.0/hci-8.1 0/6] i386: keep CPU features of guests from older nodes on vz machine types #VSTOR-152264 Denis V. Lunev
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 1/6] i386/pc: raise the limit of compat arrays per Virtuozzo machine type to four #VSTOR-152264 Denis V. Lunev
@ 2026-10-29  9:56 ` Denis V. Lunev
  2026-10-29 10:02   ` no-reply
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 3/6] i386: keep spec-ctrl for AMD guests on vz machine types up to vz9.2.0 #VSTOR-151770 Denis V. Lunev
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Denis V. Lunev @ 2026-10-29  9:56 UTC (permalink / raw)
  To: andrey.zhadchenko; +Cc: devel

From: Denis V. Lunev <den@openvz.org>

Intel microcode updates for TAA disable TSX, and a host may also boot
with tsx=off. KVM then stops offering hle and rtm, QEMU filters them,
and a guest started with TSX can no longer be migrated, restored or
reverted to a snapshot on that host: libvirt rejects the filtered
features (VSTOR-75689, VSTOR-105458). The guest read its CPUID at
boot, so the bits have to stay until it is restarted.

Add x-tsx-compat: hle and rtm requested by an Intel CPU model or on
the command line are then not filtered, and KVM gets them in the guest
CPUID, ignoring bits it does not support. With TSX disabled by
microcode XBEGIN aborts and HLE prefixes are ignored, so a guest that
keeps using TSX falls back to its lock path. Where TSX_CTRL disables
TSX instead, XBEGIN raises #UD, as it does with the libvirt
relaxation this replaces.

pc_vz_9_2_compat turns it on for vz9.2.0 and every older vz machine
type, the only ones used by guests started before release 8.0. vz10.x
types and -cpu host expansion stay strict.

Signed-off-by: Denis V. Lunev <den@openvz.org>
---
 hw/i386/pc.c         |  5 +++++
 hw/i386/pc_piix.c    |  3 ++-
 hw/i386/pc_q35.c     |  2 +-
 include/hw/i386/pc.h |  3 +++
 target/i386/cpu.c    | 27 ++++++++++++++++++++++++++-
 target/i386/cpu.h    |  7 +++++++
 6 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 76289b86c28..25b17866103 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_9_2_compat[] = {
+    { TYPE_X86_CPU, "x-tsx-compat", "on" },
+};
+const size_t pc_vz_9_2_compat_len = G_N_ELEMENTS(pc_vz_9_2_compat);
+
 GlobalProperty pc_vz_7_16_compat[] = {
     { TYPE_X86_CPU, "kvm-pv-ipi", "off" },
     { TYPE_X86_CPU, "kvm-pv-tlb-flush", "off" },
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 1a50c2a645c..5be7c2ab967 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -1060,7 +1060,8 @@ DEFINE_I440FX_RHEL_MACHINE(7, 2, 0);
     X(10, 0, 0, MT_VER_SYM(10, 0, 0), false)                                \
     X(7, 16, 0, MT_VER_SYM(7, 6, 0),  false, hw_compat_vz_9_1,              \
                                              hw_compat_vz_7_16,             \
-                                             pc_vz_7_16_compat)             \
+                                             pc_vz_7_16_compat,             \
+                                             pc_vz_9_2_compat)              \
     X(7, 12, 0, MT_VER_SYM(7, 6, 0),  false, hw_compat_vz_7_12)             \
     X(7, 10, 0, MT_VER_SYM(7, 6, 0),  false, hw_compat_vz_7_10)             \
     X(7, 8,  0, MT_VER_SYM(7, 5, 0),  false)                                \
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 2f4a14b4e01..019239bec6a 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -974,7 +974,7 @@ DEFINE_Q35_RHEL_MACHINE(7, 3, 0);
 #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(9, 2,  0, MT_VER_SYM(9, 6, 0),  false)                                \
+    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)                                \
     X(7, 16, 0, MT_VER_SYM(7, 6, 0),  false, hw_compat_vz_7_16,             \
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 4d8a01528b8..bd73426644e 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_9_2_compat[];
+extern const size_t pc_vz_9_2_compat_len;
+
 extern GlobalProperty pc_vz_7_16_compat[];
 extern const size_t pc_vz_7_16_compat_len;
 
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 5310d68443b..5ff5644dee9 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -9100,6 +9100,29 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
     }
 }
 
+/* Requested features that a vz compat property keeps despite the host */
+static uint64_t x86_cpu_compat_kept_features(X86CPU *cpu, FeatureWord w)
+{
+    CPUX86State *env = &cpu->env;
+    uint64_t kept = 0;
+
+    if (!kvm_enabled()) {
+        return 0;
+    }
+
+    switch (w) {
+    case FEAT_7_0_EBX:
+        if (cpu->tsx_compat && IS_INTEL_CPU(env)) {
+            kept = CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_RTM;
+        }
+        break;
+    default:
+        break;
+    }
+
+    return kept & env->features[w];
+}
+
 /*
  * Finishes initialization of CPUID data, filters CPU feature
  * words based on host availability of each feature.
@@ -9126,7 +9149,8 @@ static bool x86_cpu_filter_features(X86CPU *cpu, bool verbose)
         uint64_t host_feat =
             x86_cpu_get_supported_feature_word(NULL, w);
         uint64_t requested_features = env->features[w];
-        uint64_t unavailable_features = requested_features & ~host_feat;
+        uint64_t unavailable_features = requested_features & ~host_feat &
+            ~x86_cpu_compat_kept_features(cpu, w);
         mark_unavailable_features(cpu, w, unavailable_features, prefix);
     }
 
@@ -10056,6 +10080,7 @@ static const Property x86_cpu_properties[] = {
                      arch_cap_always_on, false),
     DEFINE_PROP_BOOL("x-pdcm-on-even-without-pmu", X86CPU,
                      pdcm_on_even_without_pmu, false),
+    DEFINE_PROP_BOOL("x-tsx-compat", X86CPU, tsx_compat, false),
 };
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 07b7a9417b1..85efd0b9fbe 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2331,6 +2331,13 @@ struct ArchCPU {
      */
     bool pdcm_on_even_without_pmu;
 
+    /*
+     * Virtuozzo machine types up to vz9.2.0: do not filter requested
+     * features the host no longer provides, so that a guest started on an
+     * older node keeps its CPUID.
+     */
+    bool tsx_compat;
+
     /* Number of physical address bits supported */
     uint32_t phys_bits;
 
-- 
2.53.0

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Devel] [PATCH hci-8.0/hci-8.1 3/6] i386: keep spec-ctrl for AMD guests on vz machine types up to vz9.2.0 #VSTOR-151770
  2026-10-29  9:56 [Devel] [PATCH hci-8.0/hci-8.1 0/6] i386: keep CPU features of guests from older nodes on vz machine types #VSTOR-152264 Denis V. Lunev
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 1/6] i386/pc: raise the limit of compat arrays per Virtuozzo machine type to four #VSTOR-152264 Denis V. Lunev
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 2/6] i386: keep hle and rtm on Virtuozzo machine types up to vz9.2.0 #PSBM-149402 Denis V. Lunev
@ 2026-10-29  9:56 ` Denis V. Lunev
  2026-10-29 10:02   ` no-reply
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 4/6] i386: keep bus-lock-detect for AMD guests on vz machine types up to vz9.2.0 #VSTOR-152291 Denis V. Lunev
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Denis V. Lunev @ 2026-10-29  9:56 UTC (permalink / raw)
  To: andrey.zhadchenko; +Cc: devel

From: Denis V. Lunev <den@openvz.org>

Since kernel commit de572491a975 ("KVM: x86: AMD's IBPB is not
equivalent to Intel's IBPB") KVM offers spec-ctrl on AMD hosts only
with IBPB_RET, which Zen 1-3 lack. A guest started under an older
kernel has spec-ctrl in its CPUID, and QEMU filters it on the new
host, so migration, restore and snapshot revert fail (VSTOR-151770).

Add x-spec-ctrl-compat and turn it on in pc_vz_9_2_compat: an AMD
guest keeps a requested spec-ctrl when the host still provides
amd-ibpb and one of amd-ibrs, amd-stibp and amd-ssbd. KVM then keeps
MSR_IA32_SPEC_CTRL and MSR_IA32_PRED_CMD available to the guest
through those bits (kernel commits 39485ed95d6b, 841c2be09fe4).

Signed-off-by: Denis V. Lunev <den@openvz.org>
---
 hw/i386/pc.c      |  1 +
 target/i386/cpu.c | 14 ++++++++++++++
 target/i386/cpu.h |  1 +
 3 files changed, 16 insertions(+)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 25b17866103..95ff2e7860e 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -550,6 +550,7 @@ const size_t pc_vz_compat_len = G_N_ELEMENTS(pc_vz_compat);
 
 GlobalProperty pc_vz_9_2_compat[] = {
     { TYPE_X86_CPU, "x-tsx-compat", "on" },
+    { TYPE_X86_CPU, "x-spec-ctrl-compat", "on" },
 };
 const size_t pc_vz_9_2_compat_len = G_N_ELEMENTS(pc_vz_9_2_compat);
 
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 5ff5644dee9..872c00fc983 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -9116,6 +9116,19 @@ static uint64_t x86_cpu_compat_kept_features(X86CPU *cpu, FeatureWord w)
             kept = CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_RTM;
         }
         break;
+    case FEAT_7_0_EDX:
+        if (cpu->spec_ctrl_compat && IS_AMD_CPU(env)) {
+            uint32_t ebx = kvm_arch_get_supported_cpuid(kvm_state, 0x80000008,
+                                                        0, R_EBX);
+
+            if ((ebx & CPUID_8000_0008_EBX_IBPB) &&
+                (ebx & (CPUID_8000_0008_EBX_IBRS |
+                        CPUID_8000_0008_EBX_STIBP |
+                        CPUID_8000_0008_EBX_AMD_SSBD))) {
+                kept = CPUID_7_0_EDX_SPEC_CTRL;
+            }
+        }
+        break;
     default:
         break;
     }
@@ -10081,6 +10094,7 @@ static const Property x86_cpu_properties[] = {
     DEFINE_PROP_BOOL("x-pdcm-on-even-without-pmu", X86CPU,
                      pdcm_on_even_without_pmu, false),
     DEFINE_PROP_BOOL("x-tsx-compat", X86CPU, tsx_compat, false),
+    DEFINE_PROP_BOOL("x-spec-ctrl-compat", X86CPU, spec_ctrl_compat, false),
 };
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 85efd0b9fbe..740fb3aedc5 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2337,6 +2337,7 @@ struct ArchCPU {
      * older node keeps its CPUID.
      */
     bool tsx_compat;
+    bool spec_ctrl_compat;
 
     /* Number of physical address bits supported */
     uint32_t phys_bits;
-- 
2.53.0

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Devel] [PATCH hci-8.0/hci-8.1 4/6] i386: keep bus-lock-detect for AMD guests on vz machine types up to vz9.2.0 #VSTOR-152291
  2026-10-29  9:56 [Devel] [PATCH hci-8.0/hci-8.1 0/6] i386: keep CPU features of guests from older nodes on vz machine types #VSTOR-152264 Denis V. Lunev
                   ` (2 preceding siblings ...)
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 3/6] i386: keep spec-ctrl for AMD guests on vz machine types up to vz9.2.0 #VSTOR-151770 Denis V. Lunev
@ 2026-10-29  9:56 ` Denis V. Lunev
  2026-10-29 10:03   ` no-reply
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 5/6] i386: keep v-vmsave-vmload for nested AMD guests on vz types up to vz9.2.0 #VSTOR-152264 Denis V. Lunev
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 6/6] i386: keep SVM leaf features without svm on vz types up to vz9.2.0 #PSBM-144630 Denis V. Lunev
  5 siblings, 1 reply; 13+ messages in thread
From: Denis V. Lunev @ 2026-10-29  9:56 UTC (permalink / raw)
  To: andrey.zhadchenko; +Cc: devel

From: Denis V. Lunev <den@openvz.org>

Since kernel commit 54950bfe2b69 KVM on AMD no longer offers
bus-lock-detect. A Zen 5 guest started under an older kernel has it in
its CPUID, and QEMU filters it on the new host, so migration, restore
and snapshot revert fail (VSTOR-152291).

Add x-bus-lock-detect-compat and turn it on in pc_vz_9_2_compat: an
AMD guest keeps a requested bus-lock-detect. The guest loses nothing
it had: bus lock detection did not work under KVM on AMD before kernel
commit 62ad461079e7, DR6 bit 11 stays fixed, and a Linux 6.13 or newer
guest only logs one "unchecked MSR access" warning when it brings a
vCPU online.

Signed-off-by: Denis V. Lunev <den@openvz.org>
---
 hw/i386/pc.c      | 1 +
 target/i386/cpu.c | 7 +++++++
 target/i386/cpu.h | 1 +
 3 files changed, 9 insertions(+)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 95ff2e7860e..91198e8996c 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -551,6 +551,7 @@ const size_t pc_vz_compat_len = G_N_ELEMENTS(pc_vz_compat);
 GlobalProperty pc_vz_9_2_compat[] = {
     { TYPE_X86_CPU, "x-tsx-compat", "on" },
     { TYPE_X86_CPU, "x-spec-ctrl-compat", "on" },
+    { TYPE_X86_CPU, "x-bus-lock-detect-compat", "on" },
 };
 const size_t pc_vz_9_2_compat_len = G_N_ELEMENTS(pc_vz_9_2_compat);
 
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 872c00fc983..84abaf1ae31 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -9116,6 +9116,11 @@ static uint64_t x86_cpu_compat_kept_features(X86CPU *cpu, FeatureWord w)
             kept = CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_RTM;
         }
         break;
+    case FEAT_7_0_ECX:
+        if (cpu->bus_lock_detect_compat && IS_AMD_CPU(env)) {
+            kept = CPUID_7_0_ECX_BUS_LOCK_DETECT;
+        }
+        break;
     case FEAT_7_0_EDX:
         if (cpu->spec_ctrl_compat && IS_AMD_CPU(env)) {
             uint32_t ebx = kvm_arch_get_supported_cpuid(kvm_state, 0x80000008,
@@ -10095,6 +10100,8 @@ static const Property x86_cpu_properties[] = {
                      pdcm_on_even_without_pmu, false),
     DEFINE_PROP_BOOL("x-tsx-compat", X86CPU, tsx_compat, false),
     DEFINE_PROP_BOOL("x-spec-ctrl-compat", X86CPU, spec_ctrl_compat, false),
+    DEFINE_PROP_BOOL("x-bus-lock-detect-compat", X86CPU,
+                     bus_lock_detect_compat, false),
 };
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 740fb3aedc5..b5e2d88d5d5 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2338,6 +2338,7 @@ struct ArchCPU {
      */
     bool tsx_compat;
     bool spec_ctrl_compat;
+    bool bus_lock_detect_compat;
 
     /* Number of physical address bits supported */
     uint32_t phys_bits;
-- 
2.53.0

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Devel] [PATCH hci-8.0/hci-8.1 5/6] i386: keep v-vmsave-vmload for nested AMD guests on vz types up to vz9.2.0 #VSTOR-152264
  2026-10-29  9:56 [Devel] [PATCH hci-8.0/hci-8.1 0/6] i386: keep CPU features of guests from older nodes on vz machine types #VSTOR-152264 Denis V. Lunev
                   ` (3 preceding siblings ...)
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 4/6] i386: keep bus-lock-detect for AMD guests on vz machine types up to vz9.2.0 #VSTOR-152291 Denis V. Lunev
@ 2026-10-29  9:56 ` Denis V. Lunev
  2026-10-29 10:03   ` no-reply
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 6/6] i386: keep SVM leaf features without svm on vz types up to vz9.2.0 #PSBM-144630 Denis V. Lunev
  5 siblings, 1 reply; 13+ messages in thread
From: Denis V. Lunev @ 2026-10-29  9:56 UTC (permalink / raw)
  To: andrey.zhadchenko; +Cc: devel

From: Denis V. Lunev <den@openvz.org>

On Zen 4 client parts (family 19h models 0x18-0x1f and 0x60-0x7f) the
6.12 kernel clears virtualized VMSAVE/VMLOAD in init_amd_zen4(), which
some BIOSes trigger on reboot, and KVM stops offering v-vmsave-vmload.
A nested guest (svm=on) started before has it in its CPUID, and QEMU
filters it on such a host, so migration, restore and snapshot revert
fail.

Add x-v-vmsave-vmload-compat and turn it on in pc_vz_9_2_compat: an
AMD guest keeps a requested v-vmsave-vmload. This does not turn host
VLS back on: KVM keeps intercepting VMLOAD and VMSAVE of the nested
guest and emulates them (nested_vmcb_needs_vls_intercept()), which is
only slower.

Signed-off-by: Denis V. Lunev <den@openvz.org>
---
 hw/i386/pc.c      | 1 +
 target/i386/cpu.c | 7 +++++++
 target/i386/cpu.h | 1 +
 3 files changed, 9 insertions(+)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 91198e8996c..5b2b2de4064 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -552,6 +552,7 @@ GlobalProperty pc_vz_9_2_compat[] = {
     { TYPE_X86_CPU, "x-tsx-compat", "on" },
     { TYPE_X86_CPU, "x-spec-ctrl-compat", "on" },
     { TYPE_X86_CPU, "x-bus-lock-detect-compat", "on" },
+    { TYPE_X86_CPU, "x-v-vmsave-vmload-compat", "on" },
 };
 const size_t pc_vz_9_2_compat_len = G_N_ELEMENTS(pc_vz_9_2_compat);
 
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 84abaf1ae31..52d7ffcb9ac 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -9134,6 +9134,11 @@ static uint64_t x86_cpu_compat_kept_features(X86CPU *cpu, FeatureWord w)
             }
         }
         break;
+    case FEAT_SVM:
+        if (cpu->v_vmsave_vmload_compat && IS_AMD_CPU(env)) {
+            kept = CPUID_SVM_V_VMSAVE_VMLOAD;
+        }
+        break;
     default:
         break;
     }
@@ -10102,6 +10107,8 @@ static const Property x86_cpu_properties[] = {
     DEFINE_PROP_BOOL("x-spec-ctrl-compat", X86CPU, spec_ctrl_compat, false),
     DEFINE_PROP_BOOL("x-bus-lock-detect-compat", X86CPU,
                      bus_lock_detect_compat, false),
+    DEFINE_PROP_BOOL("x-v-vmsave-vmload-compat", X86CPU,
+                     v_vmsave_vmload_compat, false),
 };
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index b5e2d88d5d5..4f8bcbe600a 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2339,6 +2339,7 @@ struct ArchCPU {
     bool tsx_compat;
     bool spec_ctrl_compat;
     bool bus_lock_detect_compat;
+    bool v_vmsave_vmload_compat;
 
     /* Number of physical address bits supported */
     uint32_t phys_bits;
-- 
2.53.0

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Devel] [PATCH hci-8.0/hci-8.1 6/6] i386: keep SVM leaf features without svm on vz types up to vz9.2.0 #PSBM-144630
  2026-10-29  9:56 [Devel] [PATCH hci-8.0/hci-8.1 0/6] i386: keep CPU features of guests from older nodes on vz machine types #VSTOR-152264 Denis V. Lunev
                   ` (4 preceding siblings ...)
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 5/6] i386: keep v-vmsave-vmload for nested AMD guests on vz types up to vz9.2.0 #VSTOR-152264 Denis V. Lunev
@ 2026-10-29  9:56 ` Denis V. Lunev
  2026-10-29 10:07   ` no-reply
  5 siblings, 1 reply; 13+ messages in thread
From: Denis V. Lunev @ 2026-10-29  9:56 UTC (permalink / raw)
  To: andrey.zhadchenko; +Cc: devel

From: Denis V. Lunev <den@openvz.org>

Since commit 730319aef0f ("i386: Mask SVM features if nested SVM is
disabled", QEMU 5.1) the features of CPUID leaf 0x8000000a are dropped
when svm is off. QEMU 2.12 on Vz7 kept them, and a Vz7 host-model
guest runs with svm=off,npt=on,nrip-save=on. Moving it to a newer QEMU
fails in libvirt (PSBM-144630):

  guest CPU doesn't match specification: missing features: npt,nrip-save

Add x-svm-features-compat and turn it on in pc_vz_9_2_compat: requested
SVM leaf features stay when svm is off, both against the dependency
on svm and against the host. The guest sees no difference, because
cpu_x86_cpuid() reports leaf 0x8000000a only with svm, in QEMU 2.12 as
now.

Signed-off-by: Denis V. Lunev <den@openvz.org>
---
 hw/i386/pc.c      |  1 +
 target/i386/cpu.c | 12 ++++++++++++
 target/i386/cpu.h |  1 +
 3 files changed, 14 insertions(+)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 5b2b2de4064..9b6b51bd5f7 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -553,6 +553,7 @@ GlobalProperty pc_vz_9_2_compat[] = {
     { TYPE_X86_CPU, "x-spec-ctrl-compat", "on" },
     { TYPE_X86_CPU, "x-bus-lock-detect-compat", "on" },
     { TYPE_X86_CPU, "x-v-vmsave-vmload-compat", "on" },
+    { TYPE_X86_CPU, "x-svm-features-compat", "on" },
 };
 const size_t pc_vz_9_2_compat_len = G_N_ELEMENTS(pc_vz_9_2_compat);
 
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 52d7ffcb9ac..0ac6fdd19c7 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -8996,6 +8996,12 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
 
     for (i = 0; i < ARRAY_SIZE(feature_dependencies); i++) {
         FeatureDep *d = &feature_dependencies[i];
+
+        /* CPUID leaf 0x8000000a stays empty without svm anyway */
+        if (cpu->svm_features_compat && d->to.index == FEAT_SVM) {
+            continue;
+        }
+
         if (!(env->features[d->from.index] & d->from.mask)) {
             uint64_t unavailable_features = env->features[d->to.index] & d->to.mask;
 
@@ -9138,6 +9144,10 @@ static uint64_t x86_cpu_compat_kept_features(X86CPU *cpu, FeatureWord w)
         if (cpu->v_vmsave_vmload_compat && IS_AMD_CPU(env)) {
             kept = CPUID_SVM_V_VMSAVE_VMLOAD;
         }
+        if (cpu->svm_features_compat &&
+            !(env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM)) {
+            kept = ~0ULL;
+        }
         break;
     default:
         break;
@@ -10109,6 +10119,8 @@ 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-svm-features-compat", X86CPU,
+                     svm_features_compat, false),
 };
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 4f8bcbe600a..97e38013e46 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2340,6 +2340,7 @@ struct ArchCPU {
     bool spec_ctrl_compat;
     bool bus_lock_detect_compat;
     bool v_vmsave_vmload_compat;
+    bool svm_features_compat;
 
     /* Number of physical address bits supported */
     uint32_t phys_bits;
-- 
2.53.0

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Devel] [PATCH hci-8.0/hci-8.1 1/6] i386/pc: raise the limit of compat arrays per Virtuozzo machine type to four #VSTOR-152264
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 1/6] i386/pc: raise the limit of compat arrays per Virtuozzo machine type to four #VSTOR-152264 Denis V. Lunev
@ 2026-10-29 10:00   ` no-reply
  0 siblings, 0 replies; 13+ messages in thread
From: no-reply @ 2026-10-29 10:00 UTC (permalink / raw)
  To: Denis V. Lunev, andrey.zhadchenko; +Cc: devel

> From: Denis V. Lunev <den@openvz.org>
> 
> A row of VZ_Q35_MT or VZ_PC_MT can name at most three compat arrays:
> COUNT_ARGS counts up to three, VZ_COMPATS_EXPAND has variants for zero
> to three, and __vz_compat_props has three slots per row. No row needs
> more yet, which is why the limit never showed. The i440fx vz7.16.0 row
> uses all three (hw_compat_vz_9_1, hw_compat_vz_7_16,
> pc_vz_7_16_compat), and the next commit adds pc_vz_9_2_compat to it.
> With a fourth argument COUNT_ARGS returns that argument instead of a
> count, and the build fails on an undefined VZ_COMPATS_EXPAND_<name>.
> 
> Raise the limit to four.
> 
> Signed-off-by: Denis V. Lunev <den@openvz.org>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261029095645.4173762-1-den@openvz.org?part=1


_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Devel] [PATCH hci-8.0/hci-8.1 2/6] i386: keep hle and rtm on Virtuozzo machine types up to vz9.2.0 #PSBM-149402
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 2/6] i386: keep hle and rtm on Virtuozzo machine types up to vz9.2.0 #PSBM-149402 Denis V. Lunev
@ 2026-10-29 10:02   ` no-reply
  0 siblings, 0 replies; 13+ messages in thread
From: no-reply @ 2026-10-29 10:02 UTC (permalink / raw)
  To: Denis V. Lunev, andrey.zhadchenko; +Cc: devel

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] i386: x-tsx-compat bypasses host_tsx_broken() HLE/RTM filter on erratum CPUs
- [Medium] i386: x-tsx-compat is per machine type, so fresh guests also get HLE/RTM unfiltered
--

commit e10a786995ad2ad41a1d6c5331e18ca149f90107
Author: Denis V. Lunev <den@openvz.org>

i386: keep hle and rtm on Virtuozzo machine types up to vz9.2.0 #PSBM-149402

This commit adds an x-tsx-compat CPU property. When it is set, HLE and RTM requested by an Intel CPU model, or on the command line, are not filtered out under KVM. The pc_vz_9_2_compat global properties turn the property on for vz9.2.0 and older vz machine types.

> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c

[ ... ]

> +GlobalProperty pc_vz_9_2_compat[] = {
> +    { TYPE_X86_CPU, "x-tsx-compat", "on" },
> +};
> +const size_t pc_vz_9_2_compat_len = G_N_ELEMENTS(pc_vz_9_2_compat);

[Severity: Medium]
This property is applied to every CPU on the affected machine types. That includes freshly booted guests, not only guests that are migrated, restored or reverted to a snapshot.

On a host with TSX disabled, a fresh guest on a vz9.2.0 or older machine type gets HLE and RTM in its CPUID. This happens when it uses an Intel CPU model, or hle/rtm=on.

If TSX_CTRL disables TSX on that host, XBEGIN raises #UD. A guest that probes CPUID and then uses RTM could fail. The commit message acknowledges this #UD behaviour.

Is there a way to limit the compat behaviour to incoming migration or restore? Alternatively, could the commit message explain why applying it to fresh boots is acceptable?

The commit message says vz9.2.0 and older are "the only ones used by guests started before release 8.0". Nothing in the repository shows this. Could this claim be backed up?

[ ... ]

> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c

[ ... ]

> +static uint64_t x86_cpu_compat_kept_features(X86CPU *cpu, FeatureWord w)
> +{

[ ... ]

> +    case FEAT_7_0_EBX:
> +        if (cpu->tsx_compat && IS_INTEL_CPU(env)) {
> +            kept = CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_RTM;
> +        }
> +        break;

[Severity: Medium]
Can this bypass the host_tsx_broken() filter in kvm_arch_get_supported_cpuid()?

That filter clears RTM and HLE on Intel family 6 hosts that have the TSX erratum. Those are model 63 with stepping below 4, and models 60, 69 and 70:

target/i386/kvm/kvm.c:kvm_arch_get_supported_cpuid() {
    ...
        if (host_tsx_broken()) {
            ret &= ~(CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_HLE);
        }
    ...
}

On such a host, with tsx_compat set and an Intel CPU model that has hle/rtm, x86_cpu_compat_kept_features() returns HLE and RTM unconditionally. They are then removed from the unavailable set in x86_cpu_filter_features(), so they stay in env->features[FEAT_7_0_EBX].

kvm_arch_init_vcpu() builds the CPUID entries from cpu_x86_cpuid() and passes them to KVM_SET_CPUID2. It does not mask them against the KVM-supported set again, so the kept bits appear to reach the guest. The guest would then see TSX on silicon where TSX is known to misbehave.

The commit message only covers TAA microcode and tsx=off. Should the kept bits be limited to cases where host_tsx_broken() is false, or should keeping them on erratum parts be explicitly justified?

> @@ -9126,7 +9149,8 @@ static bool x86_cpu_filter_features(X86CPU *cpu, bool verbose)
>          uint64_t host_feat =
>              x86_cpu_get_supported_feature_word(NULL, w);
>          uint64_t requested_features = env->features[w];
> -        uint64_t unavailable_features = requested_features & ~host_feat;
> +        uint64_t unavailable_features = requested_features & ~host_feat &
> +            ~x86_cpu_compat_kept_features(cpu, w);
>          mark_unavailable_features(cpu, w, unavailable_features, prefix);

[Severity: Medium]
The kept bits are removed from unavailable_features before mark_unavailable_features() is called. They therefore never reach filtered_features.

As a result, the verbose warnings and the enforce check stay silent for HLE and RTM. This applies to fresh boots as well as migrations.

x86_cpu_filter_features() is also called with verbose=false from the CPU model and definition reporting path. Could that path report a model as runnable on a host without TSX?

[ ... ]

-- 
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261029095645.4173762-1-den@openvz.org?part=2

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Devel] [PATCH hci-8.0/hci-8.1 3/6] i386: keep spec-ctrl for AMD guests on vz machine types up to vz9.2.0 #VSTOR-151770
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 3/6] i386: keep spec-ctrl for AMD guests on vz machine types up to vz9.2.0 #VSTOR-151770 Denis V. Lunev
@ 2026-10-29 10:02   ` no-reply
  0 siblings, 0 replies; 13+ messages in thread
From: no-reply @ 2026-10-29 10:02 UTC (permalink / raw)
  To: andrey.zhadchenko, Denis V. Lunev; +Cc: devel

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] i386: spec-ctrl compat check uses host bits only, not guest CPUID bits
- [Low] i386: spec_ctrl_compat field in struct ArchCPU has no comment
--

commit 155fa87fb8605b42ed9c5514241235cd8cfb7663
Author: Denis V. Lunev <den@openvz.org>

i386: keep spec-ctrl for AMD guests on vz machine types up to vz9.2.0 #VSTOR-151770

This commit adds an x-spec-ctrl-compat CPU property and enables it in
pc_vz_9_2_compat. When the property is set, an AMD guest keeps a requested
spec-ctrl bit if the host reports amd-ibpb plus one of amd-ibrs, amd-stibp
or amd-ssbd. This is meant to keep migration and snapshot revert working
after the KVM change that stopped offering spec-ctrl on AMD hosts without
IBPB_RET.

> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c

[ ... ]

> @@ -9116,6 +9116,19 @@ static uint64_t x86_cpu_compat_kept_features(X86CPU *cpu, FeatureWord w)
>              kept = CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_RTM;
>          }
>          break;
> +    case FEAT_7_0_EDX:
> +        if (cpu->spec_ctrl_compat && IS_AMD_CPU(env)) {
> +            uint32_t ebx = kvm_arch_get_supported_cpuid(kvm_state, 0x80000008,
> +                                                        0, R_EBX);
> +
> +            if ((ebx & CPUID_8000_0008_EBX_IBPB) &&
> +                (ebx & (CPUID_8000_0008_EBX_IBRS |
> +                        CPUID_8000_0008_EBX_STIBP |
> +                        CPUID_8000_0008_EBX_AMD_SSBD))) {
> +                kept = CPUID_7_0_EDX_SPEC_CTRL;

[Severity: Medium]
Is it enough to test only the host-supported bits here? The condition in
x86_cpu_compat_kept_features() looks only at the value returned by
kvm_arch_get_supported_cpuid() for CPUID 0x80000008 EBX. It never looks at
the guest's own env->features[FEAT_8000_0008_EBX].

The commit message says KVM keeps MSR_IA32_SPEC_CTRL and
MSR_IA32_PRED_CMD available to the guest "through those bits". That holds
for the host bits. It is not checked for the guest's amd-ibpb, amd-ibrs,
amd-stibp and amd-ssbd bits.

Some AMD models set only a subset of those bits. For example, one EPYC
variant in builtin_x86_defs sets only:

    .features[FEAT_8000_0008_EBX] =
        CPUID_8000_0008_EBX_IBPB,

None of the AMD models set CPUID_7_0_EDX_SPEC_CTRL by default. So a guest
on a vz machine type up to vz9.2.0 that requests spec-ctrl explicitly, or
uses -cpu host or max, would keep spec-ctrl based on host bits alone.

Could the guest's own CPUID.80000008:EBX bits be checked as well, so that
spec-ctrl is kept only when the guest has the matching amd-* bits? I could
not check how KVM gates the two MSRs from guest CPUID, so this may turn out
to be a non-issue.

[ ... ]

> diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> --- a/target/i386/cpu.h
> +++ b/target/i386/cpu.h
> @@ -2337,6 +2337,7 @@ struct ArchCPU {
>       * older node keeps its CPUID.
>       */
>      bool tsx_compat;
> +    bool spec_ctrl_compat;

[Severity: Low]
This isn't a bug, but the new spec_ctrl_compat field in struct ArchCPU has
no comment of its own. It sits directly below the comment block describing
tsx_compat, so it can be read as sharing the tsx_compat semantics.

Could a short comment be added saying that it applies only to AMD guests
under KVM, and that it is enabled only through the vz machine type compat
properties?

[ ... ]

-- 
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261029095645.4173762-1-den@openvz.org?part=3

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Devel] [PATCH hci-8.0/hci-8.1 5/6] i386: keep v-vmsave-vmload for nested AMD guests on vz types up to vz9.2.0 #VSTOR-152264
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 5/6] i386: keep v-vmsave-vmload for nested AMD guests on vz types up to vz9.2.0 #VSTOR-152264 Denis V. Lunev
@ 2026-10-29 10:03   ` no-reply
  0 siblings, 0 replies; 13+ messages in thread
From: no-reply @ 2026-10-29 10:03 UTC (permalink / raw)
  To: andrey.zhadchenko, Denis V. Lunev; +Cc: devel

> From: Denis V. Lunev <den@openvz.org>
> 
> On Zen 4 client parts (family 19h models 0x18-0x1f and 0x60-0x7f) the
> 6.12 kernel clears virtualized VMSAVE/VMLOAD in init_amd_zen4(), which
> some BIOSes trigger on reboot, and KVM stops offering v-vmsave-vmload.
> A nested guest (svm=on) started before has it in its CPUID, and QEMU
> filters it on such a host, so migration, restore and snapshot revert
> fail.
> 
> Add x-v-vmsave-vmload-compat and turn it on in pc_vz_9_2_compat: an
> AMD guest keeps a requested v-vmsave-vmload. This does not turn host
> VLS back on: KVM keeps intercepting VMLOAD and VMSAVE of the nested
> guest and emulates them (nested_vmcb_needs_vls_intercept()), which is
> only slower.
> 
> Signed-off-by: Denis V. Lunev <den@openvz.org>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261029095645.4173762-1-den@openvz.org?part=5


_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Devel] [PATCH hci-8.0/hci-8.1 4/6] i386: keep bus-lock-detect for AMD guests on vz machine types up to vz9.2.0 #VSTOR-152291
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 4/6] i386: keep bus-lock-detect for AMD guests on vz machine types up to vz9.2.0 #VSTOR-152291 Denis V. Lunev
@ 2026-10-29 10:03   ` no-reply
  0 siblings, 0 replies; 13+ messages in thread
From: no-reply @ 2026-10-29 10:03 UTC (permalink / raw)
  To: andrey.zhadchenko, Denis V. Lunev; +Cc: devel

> From: Denis V. Lunev <den@openvz.org>
> 
> Since kernel commit 54950bfe2b69 KVM on AMD no longer offers
> bus-lock-detect. A Zen 5 guest started under an older kernel has it in
> its CPUID, and QEMU filters it on the new host, so migration, restore
> and snapshot revert fail (VSTOR-152291).
> 
> Add x-bus-lock-detect-compat and turn it on in pc_vz_9_2_compat: an
> AMD guest keeps a requested bus-lock-detect. The guest loses nothing
> it had: bus lock detection did not work under KVM on AMD before kernel
> commit 62ad461079e7, DR6 bit 11 stays fixed, and a Linux 6.13 or newer
> guest only logs one "unchecked MSR access" warning when it brings a
> vCPU online.
> 
> Signed-off-by: Denis V. Lunev <den@openvz.org>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261029095645.4173762-1-den@openvz.org?part=4


_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Devel] [PATCH hci-8.0/hci-8.1 6/6] i386: keep SVM leaf features without svm on vz types up to vz9.2.0 #PSBM-144630
  2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 6/6] i386: keep SVM leaf features without svm on vz types up to vz9.2.0 #PSBM-144630 Denis V. Lunev
@ 2026-10-29 10:07   ` no-reply
  0 siblings, 0 replies; 13+ messages in thread
From: no-reply @ 2026-10-29 10:07 UTC (permalink / raw)
  To: Denis V. Lunev, andrey.zhadchenko; +Cc: devel

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Low] i386: svm-features-compat keeps FEAT_SVM non-zero and can raise CPUID xlevel
- [Low] i386: svm_features_compat dependency skip is not gated on KVM, so TCG warns or fails
--

commit 82ed7aadbf4e0e2f6288562589f8de9162210a0c
Author: Denis V. Lunev <den@openvz.org>

i386: keep SVM leaf features without svm on vz types up to vz9.2.0 #PSBM-144630

This commit adds the x-svm-features-compat CPU property and enables it in pc_vz_9_2_compat. With the property set, requested SVM leaf features (leaf 0x8000000a) are kept when svm is off. They survive both the feature dependency on svm and the host feature filter.

> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c

[ ... ]

> @@ -8996,6 +8996,12 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
>  
>      for (i = 0; i < ARRAY_SIZE(feature_dependencies); i++) {
>          FeatureDep *d = &feature_dependencies[i];
> +
> +        /* CPUID leaf 0x8000000a stays empty without svm anyway */
> +        if (cpu->svm_features_compat && d->to.index == FEAT_SVM) {
> +            continue;
> +        }
> +

[Severity: Low]
Can this skip leave FEAT_SVM non-zero with svm off and change the guest
visible xlevel?

Later in x86_cpu_expand_features(), under full_cpuid_auto_level (which
defaults to true), this call is not guarded by the SVM bit:

    x86_cpu_adjust_feat_level(cpu, FEAT_SVM);

x86_cpu_adjust_feat_level() returns early only when env->features[w] is
zero.  With the dependency clear skipped, FEAT_SVM is now non-zero, so the
call ends up in:

    x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000000A);

This differs from the explicit block that is guarded:

    /* SVM requires CPUID[0x8000000A] */
    if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {

cpuid_xlevel is then taken from cpuid_min_xlevel, and cpu_x86_cpuid()
returns it in EAX for leaf 0x80000000.

For a CPU model whose xlevel is below 0x8000000A (kvm64 or the Intel
models at 0x80000008, for example) with svm=off and an SVM leaf feature
such as npt=on or nrip-save=on, xlevel would change from 0x80000008 to
0x8000000A.

Does this contradict the commit message statement "The guest sees no
difference, because cpu_x86_cpuid() reports leaf 0x8000000a only with
svm"?

Should the x86_cpu_adjust_feat_level(cpu, FEAT_SVM) call be made
conditional on the SVM bit when svm_features_compat is set, or should the
commit message be corrected?

[Severity: Low]
Is it intended that this dependency skip applies to every accelerator?

The skip has no kvm_enabled() check, but the matching host filter bypass
in x86_cpu_compat_kept_features() returns early for non-KVM:

    if (!kvm_enabled()) {
        return 0;
    }

Under TCG, x86_cpu_filter_features() then computes:

    uint64_t unavailable_features = requested_features & ~host_feat &
        ~x86_cpu_compat_kept_features(cpu, w);

Here host_feat is the TCG feature set for FEAT_SVM, TCG_SVM_FEATURES.  In
system emulation CPUID_SVM_KERNEL_FEATURES is 0, so NRIPSAVE and VNMI are
not in it.

A model such as EPYC with svm=off on a vz-9.2 machine type would keep
NRIPSAVE after x86_cpu_expand_features().  It would then be reported by
mark_unavailable_features() as unsupported.  Before this patch the
dependency cleared the bit silently.

x86_cpu_realizefn() calls x86_cpu_filter_features(cpu, check_cpuid ||
enforce_cpuid).  check defaults to true, so a warning is printed.  With
enforce=on, realization fails with "TCG doesn't support requested
features".

Should the dependency skip be gated on kvm_enabled() as well, so it
matches the host filter bypass?  The commit message statement that the
features stay "against the host" is only true for KVM.

>          if (!(env->features[d->from.index] & d->from.mask)) {
>              uint64_t unavailable_features = env->features[d->to.index] & d->to.mask;

[ ... ]

-- 
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261029095645.4173762-1-den@openvz.org?part=6

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-10-29 10:08 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-29  9:56 [Devel] [PATCH hci-8.0/hci-8.1 0/6] i386: keep CPU features of guests from older nodes on vz machine types #VSTOR-152264 Denis V. Lunev
2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 1/6] i386/pc: raise the limit of compat arrays per Virtuozzo machine type to four #VSTOR-152264 Denis V. Lunev
2026-10-29 10:00   ` no-reply
2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 2/6] i386: keep hle and rtm on Virtuozzo machine types up to vz9.2.0 #PSBM-149402 Denis V. Lunev
2026-10-29 10:02   ` no-reply
2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 3/6] i386: keep spec-ctrl for AMD guests on vz machine types up to vz9.2.0 #VSTOR-151770 Denis V. Lunev
2026-10-29 10:02   ` no-reply
2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 4/6] i386: keep bus-lock-detect for AMD guests on vz machine types up to vz9.2.0 #VSTOR-152291 Denis V. Lunev
2026-10-29 10:03   ` no-reply
2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 5/6] i386: keep v-vmsave-vmload for nested AMD guests on vz types up to vz9.2.0 #VSTOR-152264 Denis V. Lunev
2026-10-29 10:03   ` no-reply
2026-10-29  9:56 ` [Devel] [PATCH hci-8.0/hci-8.1 6/6] i386: keep SVM leaf features without svm on vz types up to vz9.2.0 #PSBM-144630 Denis V. Lunev
2026-10-29 10:07   ` no-reply

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.