All Virtuozzo development lists (kernel + QEMU)
 help / color / mirror / Atom feed
* [Devel] [PATCH hci-8.1 v3 0/5] x86/ve: CPUID override follow-ups: arm at once, prefixes, selftests
@ 2026-10-06 20:44 Konstantin Khorenko
  2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 1/5] selftests/ve: check CPUID override emulation for VE tasks Konstantin Khorenko
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Konstantin Khorenko @ 2026-10-06 20:44 UTC (permalink / raw)
  To: Pavel Tikhomirov, Vasileios Almpanis; +Cc: devel

VSTOR-148656, every Container start dying with SIGSEGV once
/proc/vz/cpuid_override is non-empty, is fixed in 22.8 by 07338fbae5a3
("x86/traps: emulate CPUID faults for user tasks in
exc_general_protection()"). Working on it turned up two more defects in
the same feature, and the fact that nothing had ever exercised it. This
series takes care of those. None of them is a 22.x regression, all have
been there since the vz9 port.

Patch 2: ve_setup_task() only sets TIF_CPUID_OVERRIDE, the MSR follows
at the next context switch. A task entering a VE through unshare() or
setns() executes CPUID natively until it is scheduled out and sees the
host values. set_cpuid_override() flips the MSR synchronously for the
current task, the way disable_cpuid() does.

Patch 4: check_cpuid_fault() compares two bytes at ip with 0f a2. A
CPUID with a legacy or REX prefix faults the same way, but the handler
sees the prefix and the task gets SIGSEGV. Use the instruction decoder,
as fixup_umip_exception() does, and advance ip by the decoded length.

Patches 1, 3, 5: selftests/ve/ve_cpuid_override_test. Each kernel patch
gets its own case. The test saves and restores the table around every
case and tears down in the parent, because the kselftest harness skips
a child-side teardown after a failed ASSERT.

Tested on sqvm2-4060, the node of the failing CI run (Broadwell VM with
cpuid_fault, cpupools-features 9.1.7, so the table is armed at every
Container start). With only the 22.8 fix, cases 3 and 4 fail the way
their patches describe: host values, and a child killed by signal 11.
With the whole series all four cases pass, repeatedly and on a
non-empty table, and the vzctl-pytest start cases from the original
ticket pass as well.

https://virtuozzo.atlassian.net/browse/VSTOR-148843

Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
Changes in v3:
- Patch 1: a saved table the kernel cannot take back in one write (a
  page or more as printed) fails the setup instead of being silently
  left behind by a failed restore; writes replace the table, so there
  is no way to restore it in pieces (Sashiko).
- Patch 1: the child pid lives in the fixture and the parent-side
  teardown kills a child that a failed ASSERT left stopped in the VE
  cgroup, otherwise destroy_ve() fails with EBUSY (Sashiko).
- Patch 1: the Makefile keeps ARCH untouched and decides on a private
  variable, lib.mk picks the clang target by ARCH being empty (Sashiko).
- Link to v2: http://lore.virtuozzo.com/20261006-b4-prep-khorenko-vstor-148656-cpuid-v2-0-f6d1192c7d60@virtuozzo.com

Changes in v2:
- Patch 1: the child stops itself with SIGSTOP after entering the VE
  and the parent resumes it, so faulting is armed by a real context
  switch; the pipe handshake, whose read could return without sleeping,
  is gone (Sashiko).
- Patch 1: setup creates the VE cgroup last, so a failed ASSERT in
  setup leaves nothing behind; a failed restore in teardown is logged
  (Sashiko).
- Patch 1: drop the EAX comparison after the fallback to hardware, the
  child is not pinned and hybrid CPUs may differ per core (Sashiko).
- Patch 1: build the test on x86 only, add the binary to .gitignore
  (Sashiko).
- Patch 3: the no-reschedule case repeats the sequence, a tick can
  still preempt the child in the window; with the handshake gone a
  child that dies before reporting is reaped where the result is read
  and its signal logged (Sashiko).
- Retested on sqvm2-2084 with the whole series: all cases pass and the
  table is restored; on sqvm2-4060 with the stock kernel all cases fail
  with the expected diagnostics.
- Link to v1: http://lore.virtuozzo.com/20261006-b4-prep-khorenko-vstor-148656-cpuid-v1-0-741609f4f03a@virtuozzo.com

---
Konstantin Khorenko (5):
      selftests/ve: check CPUID override emulation for VE tasks
      x86/ve: enable CPUID faulting at once when the current task enters a VE
      selftests/ve: check CPUID override right after entering a VE
      x86/traps: decode the faulting CPUID with the instruction decoder
      selftests/ve: check CPUID override emulation for a prefixed CPUID

 arch/x86/kernel/process.c                          |  12 +
 arch/x86/kernel/traps.c                            |  16 +-
 include/linux/cpuid_override.h                     |   3 +
 kernel/ve/ve.c                                     |   2 +-
 tools/testing/selftests/ve/.gitignore              |   1 +
 tools/testing/selftests/ve/Makefile                |  10 +
 .../testing/selftests/ve/ve_cpuid_override_test.c  | 300 +++++++++++++++++++++
 7 files changed, 337 insertions(+), 7 deletions(-)
---
base-commit: f5d1fdcfffe101fe2bafa7df09d95d2e811c5c5e
change-id: 20261006-b4-prep-khorenko-vstor-148656-cpuid-a5c5993e1f83

Best regards,
--  
Konstantin Khorenko <khorenko@virtuozzo.com>

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

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

* [Devel] [PATCH hci-8.1 v3 1/5] selftests/ve: check CPUID override emulation for VE tasks
  2026-10-06 20:44 [Devel] [PATCH hci-8.1 v3 0/5] x86/ve: CPUID override follow-ups: arm at once, prefixes, selftests Konstantin Khorenko
@ 2026-10-06 20:44 ` Konstantin Khorenko
  2026-10-06 20:52   ` no-reply
  2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 2/5] x86/ve: enable CPUID faulting at once when the current task enters a VE Konstantin Khorenko
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Konstantin Khorenko @ 2026-10-06 20:44 UTC (permalink / raw)
  To: Pavel Tikhomirov, Vasileios Almpanis; +Cc: devel

Write a one-entry /proc/vz/cpuid_override table that clears one leaf 1
feature bit and compare what a task in a fresh VE and the host see:
the VE task must get the table values, the host the hardware ones. A
second test flushes the table after the task was armed and expects the
hardware values again, since faulting stays on for the task and the
emulation has to fall back to the real CPUID.

The child stops itself with SIGSTOP after entering the VE and the
parent resumes it before the CPUID: faulting is switched on for a task
at its next context switch, not when the flag is set, and a stopped
task is off the CPU for sure. For the second test the table is flushed
while the child stands still.

Without the fix both children die with SIGSEGV. The tests skip on CPUs
without CPUID faulting and restore the previous table on exit; a table
the kernel cannot take back in one write fails the setup instead. The
teardown runs in the parent because the harness skips a child-side
teardown once an ASSERT has fired, and it kills a child that such an
ASSERT left stopped in the VE cgroup. The test is built on x86 only.

https://virtuozzo.atlassian.net/browse/VSTOR-148843

Feature: x86: cpu pools (cpuid override)
Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
 tools/testing/selftests/ve/.gitignore              |   1 +
 tools/testing/selftests/ve/Makefile                |  10 +
 .../testing/selftests/ve/ve_cpuid_override_test.c  | 247 +++++++++++++++++++++
 3 files changed, 258 insertions(+)

diff --git a/tools/testing/selftests/ve/.gitignore b/tools/testing/selftests/ve/.gitignore
index 3df4d05888dce..bdc322c645d95 100644
--- a/tools/testing/selftests/ve/.gitignore
+++ b/tools/testing/selftests/ve/.gitignore
@@ -1,3 +1,4 @@
 ve_ns_owner_test
 ve_perms_test
 ve_mount_accounting_test
+ve_cpuid_override_test
diff --git a/tools/testing/selftests/ve/Makefile b/tools/testing/selftests/ve/Makefile
index c6efe7c4b4fba..d919c1c289c8b 100644
--- a/tools/testing/selftests/ve/Makefile
+++ b/tools/testing/selftests/ve/Makefile
@@ -6,4 +6,14 @@ TEST_GEN_PROGS += ve_ns_owner_test
 TEST_GEN_PROGS += ve_perms_test
 TEST_GEN_PROGS += ve_mount_accounting_test
 
+# ARCH stays untouched: lib.mk picks the clang target by its emptiness.
+ifeq ($(ARCH),)
+ve_arch := $(shell uname -m 2>/dev/null || echo not)
+else
+ve_arch := $(ARCH)
+endif
+ifeq ($(ve_arch),$(filter $(ve_arch),x86 x86_64))
+TEST_GEN_PROGS += ve_cpuid_override_test
+endif
+
 include ../lib.mk
diff --git a/tools/testing/selftests/ve/ve_cpuid_override_test.c b/tools/testing/selftests/ve/ve_cpuid_override_test.c
new file mode 100644
index 0000000000000..0e3537099ddb2
--- /dev/null
+++ b/tools/testing/selftests/ve/ve_cpuid_override_test.c
@@ -0,0 +1,247 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * /proc/vz/cpuid_override selftests
+ *
+ * A non-empty override table turns CPUID faulting on for every task that
+ * enters a VE, and the #GP handler has to emulate the instruction for
+ * them. The tests check that a task in a VE sees the table values, that
+ * the host keeps seeing the hardware values, and that a task which was
+ * armed while the table was set falls back to the hardware once the
+ * table is flushed. A kernel that does not emulate the fault kills the
+ * child with SIGSEGV instead.
+ */
+#define _GNU_SOURCE
+#include <sched.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/wait.h>
+
+#include "../kselftest_harness.h"
+#include "ve_selftest.h"
+
+#define CPUID_OVERRIDE_PATH	"/proc/vz/cpuid_override"
+#define CPUID_LEAF		1
+#define CPUID_TABLE_LEN		128
+/* The kernel takes a table back only in one write below a page. */
+#define CPUID_WRITE_MAX		4096
+#define CPUID_TABLE_MAX		(2 * CPUID_WRITE_MAX)
+
+struct cpuid_regs {
+	unsigned int eax, ebx, ecx, edx;
+};
+
+/* x86_64 only, so ebx is not the PIC base and "=b" is safe. */
+static void do_cpuid(unsigned int leaf, struct cpuid_regs *r)
+{
+	asm volatile("cpuid"
+		     : "=a" (r->eax), "=b" (r->ebx), "=c" (r->ecx), "=d" (r->edx)
+		     : "a" (leaf), "c" (0));
+}
+
+static int write_cpuid_override(const char *table)
+{
+	int fd, ret;
+
+	fd = open(CPUID_OVERRIDE_PATH, O_WRONLY);
+	if (fd < 0)
+		return -1;
+	ret = write(fd, table, strlen(table));
+	close(fd);
+	return ret == (int)strlen(table) ? 0 : -1;
+}
+
+/*
+ * The child enters a fresh VE, so it is armed with the table state of that
+ * moment, then reports its view of the leaf to the parent over a pipe. It
+ * stops itself in between: a stopped task is off the CPU, so the resume is
+ * a context switch, and the parent may change the table while the child
+ * stands still.
+ */
+struct child_ctx {
+	int result_pipe[2];
+};
+
+static int cpuid_child(struct child_ctx *ctx)
+{
+	struct cpuid_regs r;
+
+	close(ctx->result_pipe[0]);
+
+	if (unshare(CLONE_NEWVE) < 0)
+		return 21;
+	if (raise(SIGSTOP))
+		return 22;
+
+	do_cpuid(CPUID_LEAF, &r);
+
+	if (write(ctx->result_pipe[1], &r, sizeof(r)) != sizeof(r))
+		return 24;
+	return 0;
+}
+
+FIXTURE(ve_cpuid_override)
+{
+	int cgv2_fd;
+	int ctid;
+	struct cpuid_regs host;
+	unsigned int bit;
+	pid_t child;
+	char table[CPUID_TABLE_LEN];
+	char saved[CPUID_TABLE_MAX];
+};
+
+FIXTURE_SETUP(ve_cpuid_override)
+{
+	int fd, len;
+
+	fd = open(CPUID_OVERRIDE_PATH, O_RDONLY);
+	if (fd < 0)
+		SKIP(return, "%s: %s", CPUID_OVERRIDE_PATH, strerror(errno));
+	close(fd);
+
+	len = read_file_at(AT_FDCWD, CPUID_OVERRIDE_PATH, self->saved,
+			   sizeof(self->saved));
+	ASSERT_GE(len, 0);
+	ASSERT_LT(len, CPUID_WRITE_MAX)
+		TH_LOG("a table of %d bytes cannot be restored", len);
+
+	/* Mask one feature bit the host has; SSE2 when present. */
+	do_cpuid(CPUID_LEAF, &self->host);
+	self->bit = 1u << 26;
+	if (!(self->host.edx & self->bit))
+		self->bit = self->host.edx & -self->host.edx;
+	ASSERT_NE(self->bit, 0);
+
+	snprintf(self->table, sizeof(self->table),
+		 "0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n", CPUID_LEAF,
+		 self->host.eax, self->host.ebx, self->host.ecx,
+		 self->host.edx & ~self->bit);
+
+	/* Last, so that a failed ASSERT above leaves no VE cgroup behind. */
+	self->cgv2_fd = mount_cg2_fd();
+	ASSERT_GE(self->cgv2_fd, 0);
+	ASSERT_EQ(write_file_at(self->cgv2_fd, "cgroup.subtree_control",
+				VE_CONTROLLERS), 0);
+	self->ctid = make_ve(self->cgv2_fd, CTID_MIN);
+	ASSERT_GE(self->ctid, 0);
+}
+
+/*
+ * Runs in the parent: a child-side teardown is skipped when an ASSERT fires,
+ * and the table must be restored even then. The fd from setup belongs to the
+ * child, so the cgroup2 tree is mounted again here.
+ */
+FIXTURE_TEARDOWN_PARENT(ve_cpuid_override)
+{
+	int cgv2_fd;
+
+	if (write_cpuid_override(self->saved[0] ? self->saved : "\n"))
+		TH_LOG("could not restore %s: %s", CPUID_OVERRIDE_PATH,
+		       strerror(errno));
+
+	/* A child left stopped by a failed ASSERT keeps the VE cgroup busy. */
+	if (self->child > 0)
+		kill(self->child, SIGKILL);
+
+	cgv2_fd = mount_cg2_fd();
+	if (cgv2_fd < 0)
+		return;
+	destroy_ve(cgv2_fd, self->ctid);
+	close(cgv2_fd);
+}
+
+/* Fork the child into the VE and return once it stands still there. */
+static pid_t spawn_cpuid_child(struct __test_metadata *_metadata,
+			       FIXTURE_DATA(ve_cpuid_override) * self,
+			       struct child_ctx *ctx)
+{
+	int status;
+	pid_t pid;
+
+	ASSERT_EQ(pipe(ctx->result_pipe), 0);
+	ASSERT_GE(enter_cgroup(self->cgv2_fd, self->ctid), 0);
+
+	pid = fork();
+	ASSERT_GE(pid, 0);
+	if (pid == 0)
+		_exit(cpuid_child(ctx));
+	self->child = pid;
+
+	ASSERT_GE(enter_cgroup(self->cgv2_fd, 0), 0);
+	close(ctx->result_pipe[1]);
+
+	ASSERT_GE(waitpid(pid, &status, WUNTRACED), 0);
+	if (WIFEXITED(status))
+		TH_LOG("child exited with %d before stopping",
+		       WEXITSTATUS(status));
+	ASSERT_TRUE(WIFSTOPPED(status));
+	return pid;
+}
+
+static void resume_cpuid_child(struct __test_metadata *_metadata, pid_t pid)
+{
+	ASSERT_EQ(kill(pid, SIGCONT), 0);
+}
+
+static void collect_cpuid_child(struct __test_metadata *_metadata,
+				FIXTURE_DATA(ve_cpuid_override) * self,
+				struct child_ctx *ctx, struct cpuid_regs *r)
+{
+	int status, len;
+
+	len = read(ctx->result_pipe[0], r, sizeof(*r));
+	ASSERT_GE(waitpid(self->child, &status, 0), 0);
+	self->child = 0;
+	if (WIFSIGNALED(status))
+		TH_LOG("child killed by signal %d", WTERMSIG(status));
+	ASSERT_TRUE(WIFEXITED(status));
+	ASSERT_EQ(WEXITSTATUS(status), 0);
+	ASSERT_EQ(len, sizeof(*r));
+
+	close(ctx->result_pipe[0]);
+}
+
+TEST_F(ve_cpuid_override, ve_sees_table_host_sees_hardware)
+{
+	struct child_ctx ctx;
+	struct cpuid_regs r;
+	pid_t pid;
+
+	ASSERT_EQ(write_cpuid_override(self->table), 0);
+
+	pid = spawn_cpuid_child(_metadata, self, &ctx);
+	resume_cpuid_child(_metadata, pid);
+	collect_cpuid_child(_metadata, self, &ctx, &r);
+
+	EXPECT_EQ(r.eax, self->host.eax);
+	EXPECT_EQ(r.ebx, self->host.ebx);
+	EXPECT_EQ(r.ecx, self->host.ecx);
+	EXPECT_EQ(r.edx, self->host.edx & ~self->bit);
+
+	do_cpuid(CPUID_LEAF, &r);
+	EXPECT_NE(r.edx & self->bit, 0);
+}
+
+TEST_F(ve_cpuid_override, flushed_table_falls_back_to_hardware)
+{
+	struct child_ctx ctx;
+	struct cpuid_regs r;
+	pid_t pid;
+
+	ASSERT_EQ(write_cpuid_override(self->table), 0);
+
+	pid = spawn_cpuid_child(_metadata, self, &ctx);
+
+	ASSERT_EQ(write_cpuid_override("\n"), 0);
+	resume_cpuid_child(_metadata, pid);
+	collect_cpuid_child(_metadata, self, &ctx, &r);
+
+	EXPECT_NE(r.edx & self->bit, 0);
+}
+
+TEST_HARNESS_MAIN

-- 
2.43.0

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

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

* [Devel] [PATCH hci-8.1 v3 2/5] x86/ve: enable CPUID faulting at once when the current task enters a VE
  2026-10-06 20:44 [Devel] [PATCH hci-8.1 v3 0/5] x86/ve: CPUID override follow-ups: arm at once, prefixes, selftests Konstantin Khorenko
  2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 1/5] selftests/ve: check CPUID override emulation for VE tasks Konstantin Khorenko
@ 2026-10-06 20:44 ` Konstantin Khorenko
  2026-10-06 20:49   ` no-reply
  2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 3/5] selftests/ve: check CPUID override right after entering " Konstantin Khorenko
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Konstantin Khorenko @ 2026-10-06 20:44 UTC (permalink / raw)
  To: Pavel Tikhomirov, Vasileios Almpanis; +Cc: devel

ve_setup_task() only sets TIF_CPUID_OVERRIDE. The MSR follows the flag
in __switch_to_xtra(), so a task that enters a VE through unshare() or
setns() keeps executing CPUID natively until it is scheduled out for the
first time and sees the host values instead of the override table.

Add set_cpuid_override(), which sets the flag and, like disable_cpuid(),
flips the CPU state synchronously when the task is the current one.
Tasks set up through clone() are not running yet and are still handled
at their first switch-in.

https://virtuozzo.atlassian.net/browse/VSTOR-148843

Feature: x86: cpu pools (cpuid override)
Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
 arch/x86/kernel/process.c      | 12 ++++++++++++
 include/linux/cpuid_override.h |  3 +++
 kernel/ve/ve.c                 |  2 +-
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 28fc4168b6c9f..2673f2e51a833 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -23,6 +23,7 @@
 #include <linux/utsname.h>
 #include <linux/stackprotector.h>
 #include <linux/cpuidle.h>
+#include <linux/cpuid_override.h>
 #include <linux/acpi.h>
 #include <linux/elf-randomize.h>
 #include <linux/static_call.h>
@@ -381,6 +382,17 @@ static void enable_cpuid(void)
 	preempt_enable();
 }
 
+#ifdef CONFIG_VE
+void set_cpuid_override(struct task_struct *tsk)
+{
+	preempt_disable();
+	if (!test_and_set_tsk_thread_flag(tsk, TIF_CPUID_OVERRIDE) &&
+	    tsk == current)
+		set_cpuid_faulting(true);
+	preempt_enable();
+}
+#endif
+
 static int get_cpuid_mode(void)
 {
 	return !test_thread_flag(TIF_NOCPUID);
diff --git a/include/linux/cpuid_override.h b/include/linux/cpuid_override.h
index 1f5223728c9ba..83a955b628cdf 100644
--- a/include/linux/cpuid_override.h
+++ b/include/linux/cpuid_override.h
@@ -35,4 +35,7 @@ static inline bool cpuid_override_on(void)
 {
 	return rcu_access_pointer(cpuid_override);
 }
+
+struct task_struct;
+void set_cpuid_override(struct task_struct *tsk);
 #endif
diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index 579628a8a310a..8df881039c3c6 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -1857,7 +1857,7 @@ void ve_setup_task(struct task_struct *task, struct ve_struct *ve)
 
 #ifdef CONFIG_X86
 	if (cpuid_override_on())
-		set_tsk_thread_flag(task, TIF_CPUID_OVERRIDE);
+		set_cpuid_override(task);
 #endif
 }
 EXPORT_SYMBOL(ve_setup_task);

-- 
2.43.0

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

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

* [Devel] [PATCH hci-8.1 v3 3/5] selftests/ve: check CPUID override right after entering a VE
  2026-10-06 20:44 [Devel] [PATCH hci-8.1 v3 0/5] x86/ve: CPUID override follow-ups: arm at once, prefixes, selftests Konstantin Khorenko
  2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 1/5] selftests/ve: check CPUID override emulation for VE tasks Konstantin Khorenko
  2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 2/5] x86/ve: enable CPUID faulting at once when the current task enters a VE Konstantin Khorenko
@ 2026-10-06 20:44 ` Konstantin Khorenko
  2026-10-06 20:50   ` no-reply
  2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 4/5] x86/traps: decode the faulting CPUID with the instruction decoder Konstantin Khorenko
  2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 5/5] selftests/ve: check CPUID override emulation for a prefixed CPUID Konstantin Khorenko
  4 siblings, 1 reply; 11+ messages in thread
From: Konstantin Khorenko @ 2026-10-06 20:44 UTC (permalink / raw)
  To: Pavel Tikhomirov, Vasileios Almpanis; +Cc: devel

Add a case where the child executes CPUID straight after unshare(),
without stopping or blocking in between, and expects the table values.
Before the kernel change the override took effect only after the first
context switch, so the child saw the hardware values.

A tick can still preempt the child in that window, so the case runs
the sequence several times: a kernel that arms faulting only at the
switch has to get lucky every time.

https://virtuozzo.atlassian.net/browse/VSTOR-148843

Feature: x86: cpu pools (cpuid override)
---
 .../testing/selftests/ve/ve_cpuid_override_test.c  | 52 ++++++++++++++++------
 1 file changed, 39 insertions(+), 13 deletions(-)

diff --git a/tools/testing/selftests/ve/ve_cpuid_override_test.c b/tools/testing/selftests/ve/ve_cpuid_override_test.c
index 0e3537099ddb2..9d2d5ddd32201 100644
--- a/tools/testing/selftests/ve/ve_cpuid_override_test.c
+++ b/tools/testing/selftests/ve/ve_cpuid_override_test.c
@@ -27,6 +27,7 @@
 #define CPUID_OVERRIDE_PATH	"/proc/vz/cpuid_override"
 #define CPUID_LEAF		1
 #define CPUID_TABLE_LEN		128
+#define NO_RESCHED_ROUNDS	20
 /* The kernel takes a table back only in one write below a page. */
 #define CPUID_WRITE_MAX		4096
 #define CPUID_TABLE_MAX		(2 * CPUID_WRITE_MAX)
@@ -57,13 +58,14 @@ static int write_cpuid_override(const char *table)
 
 /*
  * The child enters a fresh VE, so it is armed with the table state of that
- * moment, then reports its view of the leaf to the parent over a pipe. It
- * stops itself in between: a stopped task is off the CPU, so the resume is
- * a context switch, and the parent may change the table while the child
- * stands still.
+ * moment, then reports its view of the leaf to the parent over a pipe. With
+ * @stop it stops itself in between: a stopped task is off the CPU, so the
+ * resume is a context switch, and the parent may change the table while
+ * the child stands still.
  */
 struct child_ctx {
 	int result_pipe[2];
+	int stop;
 };
 
 static int cpuid_child(struct child_ctx *ctx)
@@ -74,7 +76,7 @@ static int cpuid_child(struct child_ctx *ctx)
 
 	if (unshare(CLONE_NEWVE) < 0)
 		return 21;
-	if (raise(SIGSTOP))
+	if (ctx->stop && raise(SIGSTOP))
 		return 22;
 
 	do_cpuid(CPUID_LEAF, &r);
@@ -155,7 +157,7 @@ FIXTURE_TEARDOWN_PARENT(ve_cpuid_override)
 	close(cgv2_fd);
 }
 
-/* Fork the child into the VE and return once it stands still there. */
+/* Fork the child into the VE; with @stop return once it stands still. */
 static pid_t spawn_cpuid_child(struct __test_metadata *_metadata,
 			       FIXTURE_DATA(ve_cpuid_override) * self,
 			       struct child_ctx *ctx)
@@ -175,11 +177,13 @@ static pid_t spawn_cpuid_child(struct __test_metadata *_metadata,
 	ASSERT_GE(enter_cgroup(self->cgv2_fd, 0), 0);
 	close(ctx->result_pipe[1]);
 
-	ASSERT_GE(waitpid(pid, &status, WUNTRACED), 0);
-	if (WIFEXITED(status))
-		TH_LOG("child exited with %d before stopping",
-		       WEXITSTATUS(status));
-	ASSERT_TRUE(WIFSTOPPED(status));
+	if (ctx->stop) {
+		ASSERT_GE(waitpid(pid, &status, WUNTRACED), 0);
+		if (WIFEXITED(status))
+			TH_LOG("child exited with %d before stopping",
+			       WEXITSTATUS(status));
+		ASSERT_TRUE(WIFSTOPPED(status));
+	}
 	return pid;
 }
 
@@ -208,7 +212,7 @@ static void collect_cpuid_child(struct __test_metadata *_metadata,
 
 TEST_F(ve_cpuid_override, ve_sees_table_host_sees_hardware)
 {
-	struct child_ctx ctx;
+	struct child_ctx ctx = { .stop = 1 };
 	struct cpuid_regs r;
 	pid_t pid;
 
@@ -229,7 +233,7 @@ TEST_F(ve_cpuid_override, ve_sees_table_host_sees_hardware)
 
 TEST_F(ve_cpuid_override, flushed_table_falls_back_to_hardware)
 {
-	struct child_ctx ctx;
+	struct child_ctx ctx = { .stop = 1 };
 	struct cpuid_regs r;
 	pid_t pid;
 
@@ -244,4 +248,26 @@ TEST_F(ve_cpuid_override, flushed_table_falls_back_to_hardware)
 	EXPECT_NE(r.edx & self->bit, 0);
 }
 
+/*
+ * The child does not block between entering the VE and the CPUID, but a
+ * tick can still preempt it there. Repeat, so that a kernel which arms
+ * faulting only at the switch has to get lucky every time.
+ */
+TEST_F(ve_cpuid_override, armed_before_first_reschedule)
+{
+	struct cpuid_regs r;
+	int i;
+
+	ASSERT_EQ(write_cpuid_override(self->table), 0);
+
+	for (i = 0; i < NO_RESCHED_ROUNDS; i++) {
+		struct child_ctx ctx = { .stop = 0 };
+
+		spawn_cpuid_child(_metadata, self, &ctx);
+		collect_cpuid_child(_metadata, self, &ctx, &r);
+		ASSERT_EQ(r.edx, self->host.edx & ~self->bit)
+			TH_LOG("round %d", i);
+	}
+}
+
 TEST_HARNESS_MAIN

-- 
2.43.0

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

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

* [Devel] [PATCH hci-8.1 v3 4/5] x86/traps: decode the faulting CPUID with the instruction decoder
  2026-10-06 20:44 [Devel] [PATCH hci-8.1 v3 0/5] x86/ve: CPUID override follow-ups: arm at once, prefixes, selftests Konstantin Khorenko
                   ` (2 preceding siblings ...)
  2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 3/5] selftests/ve: check CPUID override right after entering " Konstantin Khorenko
@ 2026-10-06 20:44 ` Konstantin Khorenko
  2026-10-06 20:51   ` no-reply
  2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 5/5] selftests/ve: check CPUID override emulation for a prefixed CPUID Konstantin Khorenko
  4 siblings, 1 reply; 11+ messages in thread
From: Konstantin Khorenko @ 2026-10-06 20:44 UTC (permalink / raw)
  To: Pavel Tikhomirov, Vasileios Almpanis; +Cc: devel

check_cpuid_fault() reads two bytes at the faulting ip and emulates
only when they are 0f a2, the bare CPUID encoding.

CPUID has no operands, so the CPU accepts and ignores every legacy
and REX prefix in front of it. All of these are valid CPUID and raise
the same #GP(0) when CPUID faulting is on:

  0f a2           cpuid
  66 0f a2        data16 cpuid       (operand-size override)
  f3 0f a2        repz cpuid
  2e 0f a2        cs cpuid           (segment override)
  48 0f a2        rex.W cpuid

Only the first one is recognised. For the others the handler reads
the prefix byte instead of the opcode, declines, and the task is
killed with SIGSEGV although the instruction is legal and the host
would have executed it.
Such encodings could come from hand-written and generated assembly, from
binary translators and JITs that emit prefixes for alignment or as
padding, and from any binary that disassembles as "data16 cpuid" rather
than "cpuid".

Fetch and decode the instruction with insn_fetch_from_user() and
insn_decode_from_regs(), as fixup_umip_exception() does, match the
opcode bytes and advance ip by the decoded length. The decoder derives
the linear ip from the code segment itself, so convert_ip_to_linear()
is not needed any more.

Fixes: 1033fe455434 ("arch/x86: introduce cpuid override")
https://virtuozzo.atlassian.net/browse/VSTOR-148843

Feature: x86: cpu pools (cpuid override)
Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
 arch/x86/kernel/traps.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 8074387bf4f43..fa12da67adbf0 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -633,8 +633,9 @@ static enum kernel_gp_hint get_kernel_gp_address(struct pt_regs *regs,
 
 static int check_cpuid_fault(struct pt_regs *regs, long error_code)
 {
-	unsigned long addr;
-	unsigned short opcode;
+	unsigned char buf[MAX_INSN_SIZE];
+	struct insn insn;
+	int nr_copied;
 
 	if (error_code != 0)
 		return 0;
@@ -642,16 +643,19 @@ static int check_cpuid_fault(struct pt_regs *regs, long error_code)
 	if (test_thread_flag(TIF_NOCPUID))
 		return 0;
 
-	addr = convert_ip_to_linear(current, regs);
-	if (get_user(opcode, (unsigned short __user *)addr))
+	nr_copied = insn_fetch_from_user(regs, buf);
+	if (nr_copied <= 0)
+		return 0;
+
+	if (!insn_decode_from_regs(&insn, regs, buf, nr_copied))
 		return 0;
 
-	if (opcode != 0xa20f)
+	if (insn.opcode.bytes[0] != 0x0f || insn.opcode.bytes[1] != 0xa2)
 		return 0;
 
 	do_cpuid_fault(regs);
 
-	regs->ip += 2;
+	regs->ip += insn.length;
 	return 1;
 }
 

-- 
2.43.0

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

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

* [Devel] [PATCH hci-8.1 v3 5/5] selftests/ve: check CPUID override emulation for a prefixed CPUID
  2026-10-06 20:44 [Devel] [PATCH hci-8.1 v3 0/5] x86/ve: CPUID override follow-ups: arm at once, prefixes, selftests Konstantin Khorenko
                   ` (3 preceding siblings ...)
  2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 4/5] x86/traps: decode the faulting CPUID with the instruction decoder Konstantin Khorenko
@ 2026-10-06 20:44 ` Konstantin Khorenko
  2026-10-06 20:52   ` no-reply
  4 siblings, 1 reply; 11+ messages in thread
From: Konstantin Khorenko @ 2026-10-06 20:44 UTC (permalink / raw)
  To: Pavel Tikhomirov, Vasileios Almpanis; +Cc: devel

Execute CPUID with an operand-size prefix, which the CPU ignores, and
expect the table values. Before the kernel change the #GP handler
matched only the bare opcode and the child died with SIGSEGV.

https://virtuozzo.atlassian.net/browse/VSTOR-148843

Feature: x86: cpu pools (cpuid override)
Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
 .../testing/selftests/ve/ve_cpuid_override_test.c  | 29 +++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/ve/ve_cpuid_override_test.c b/tools/testing/selftests/ve/ve_cpuid_override_test.c
index 9d2d5ddd32201..6a18a180191c5 100644
--- a/tools/testing/selftests/ve/ve_cpuid_override_test.c
+++ b/tools/testing/selftests/ve/ve_cpuid_override_test.c
@@ -44,6 +44,14 @@ static void do_cpuid(unsigned int leaf, struct cpuid_regs *r)
 		     : "a" (leaf), "c" (0));
 }
 
+/* CPUID with an operand-size prefix, which the CPU accepts and ignores. */
+static void do_cpuid_prefixed(unsigned int leaf, struct cpuid_regs *r)
+{
+	asm volatile(".byte 0x66, 0x0f, 0xa2"
+		     : "=a" (r->eax), "=b" (r->ebx), "=c" (r->ecx), "=d" (r->edx)
+		     : "a" (leaf), "c" (0));
+}
+
 static int write_cpuid_override(const char *table)
 {
 	int fd, ret;
@@ -66,6 +74,7 @@ static int write_cpuid_override(const char *table)
 struct child_ctx {
 	int result_pipe[2];
 	int stop;
+	int prefixed;
 };
 
 static int cpuid_child(struct child_ctx *ctx)
@@ -79,7 +88,10 @@ static int cpuid_child(struct child_ctx *ctx)
 	if (ctx->stop && raise(SIGSTOP))
 		return 22;
 
-	do_cpuid(CPUID_LEAF, &r);
+	if (ctx->prefixed)
+		do_cpuid_prefixed(CPUID_LEAF, &r);
+	else
+		do_cpuid(CPUID_LEAF, &r);
 
 	if (write(ctx->result_pipe[1], &r, sizeof(r)) != sizeof(r))
 		return 24;
@@ -270,4 +282,19 @@ TEST_F(ve_cpuid_override, armed_before_first_reschedule)
 	}
 }
 
+TEST_F(ve_cpuid_override, prefixed_cpuid_is_emulated)
+{
+	struct child_ctx ctx = { .stop = 1, .prefixed = 1 };
+	struct cpuid_regs r;
+	pid_t pid;
+
+	ASSERT_EQ(write_cpuid_override(self->table), 0);
+
+	pid = spawn_cpuid_child(_metadata, self, &ctx);
+	resume_cpuid_child(_metadata, pid);
+	collect_cpuid_child(_metadata, self, &ctx, &r);
+
+	EXPECT_EQ(r.edx, self->host.edx & ~self->bit);
+}
+
 TEST_HARNESS_MAIN

-- 
2.43.0

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

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

* Re: [Devel] [PATCH hci-8.1 v3 2/5] x86/ve: enable CPUID faulting at once when the current task enters a VE
  2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 2/5] x86/ve: enable CPUID faulting at once when the current task enters a VE Konstantin Khorenko
@ 2026-10-06 20:49   ` no-reply
  0 siblings, 0 replies; 11+ messages in thread
From: no-reply @ 2026-10-06 20:49 UTC (permalink / raw)
  To: Pavel Tikhomirov, Konstantin Khorenko, Vasileios Almpanis; +Cc: devel

> ve_setup_task() only sets TIF_CPUID_OVERRIDE. The MSR follows the flag
> in __switch_to_xtra(), so a task that enters a VE through unshare() or
> setns() keeps executing CPUID natively until it is scheduled out for the
> first time and sees the host values instead of the override table.
> 
> Add set_cpuid_override(), which sets the flag and, like disable_cpuid(),
> flips the CPU state synchronously when the task is the current one.
> Tasks set up through clone() are not running yet and are still handled
> at their first switch-in.
> 
> https://virtuozzo.atlassian.net/browse/VSTOR-148843
> 
> Feature: x86: cpu pools (cpuid override)
> Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>

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

-- 
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261006-b4-prep-khorenko-vstor-148656-cpuid-v3-0-16141b8ca07d@virtuozzo.com?part=2


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

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

* Re: [Devel] [PATCH hci-8.1 v3 3/5] selftests/ve: check CPUID override right after entering a VE
  2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 3/5] selftests/ve: check CPUID override right after entering " Konstantin Khorenko
@ 2026-10-06 20:50   ` no-reply
  0 siblings, 0 replies; 11+ messages in thread
From: no-reply @ 2026-10-06 20:50 UTC (permalink / raw)
  To: Vasileios Almpanis, Konstantin Khorenko, Pavel Tikhomirov; +Cc: devel

> Add a case where the child executes CPUID straight after unshare(),
> without stopping or blocking in between, and expects the table values.
> Before the kernel change the override took effect only after the first
> context switch, so the child saw the hardware values.
> 
> A tick can still preempt the child in that window, so the case runs
> the sequence several times: a kernel that arms faulting only at the
> switch has to get lucky every time.
> 
> https://virtuozzo.atlassian.net/browse/VSTOR-148843
> 
> Feature: x86: cpu pools (cpuid override)

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

-- 
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261006-b4-prep-khorenko-vstor-148656-cpuid-v3-0-16141b8ca07d@virtuozzo.com?part=3


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

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

* Re: [Devel] [PATCH hci-8.1 v3 4/5] x86/traps: decode the faulting CPUID with the instruction decoder
  2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 4/5] x86/traps: decode the faulting CPUID with the instruction decoder Konstantin Khorenko
@ 2026-10-06 20:51   ` no-reply
  0 siblings, 0 replies; 11+ messages in thread
From: no-reply @ 2026-10-06 20:51 UTC (permalink / raw)
  To: Pavel Tikhomirov, Vasileios Almpanis, Konstantin Khorenko; +Cc: devel

> check_cpuid_fault() reads two bytes at the faulting ip and emulates
> only when they are 0f a2, the bare CPUID encoding.
> 
> CPUID has no operands, so the CPU accepts and ignores every legacy
> and REX prefix in front of it. All of these are valid CPUID and raise
> the same #GP(0) when CPUID faulting is on:
> 
>   0f a2           cpuid
>   66 0f a2        data16 cpuid       (operand-size override)
>   f3 0f a2        repz cpuid
>   2e 0f a2        cs cpuid           (segment override)
>   48 0f a2        rex.W cpuid
> 
> Only the first one is recognised. For the others the handler reads
> the prefix byte instead of the opcode, declines, and the task is
> [ ... ]
> Fixes: 1033fe455434 ("arch/x86: introduce cpuid override")
> https://virtuozzo.atlassian.net/browse/VSTOR-148843
> 
> Feature: x86: cpu pools (cpuid override)
> Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>

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

-- 
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261006-b4-prep-khorenko-vstor-148656-cpuid-v3-0-16141b8ca07d@virtuozzo.com?part=4


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

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

* Re: [Devel] [PATCH hci-8.1 v3 5/5] selftests/ve: check CPUID override emulation for a prefixed CPUID
  2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 5/5] selftests/ve: check CPUID override emulation for a prefixed CPUID Konstantin Khorenko
@ 2026-10-06 20:52   ` no-reply
  0 siblings, 0 replies; 11+ messages in thread
From: no-reply @ 2026-10-06 20:52 UTC (permalink / raw)
  To: Pavel Tikhomirov, Konstantin Khorenko, Vasileios Almpanis; +Cc: devel

> Execute CPUID with an operand-size prefix, which the CPU ignores, and
> expect the table values. Before the kernel change the #GP handler
> matched only the bare opcode and the child died with SIGSEGV.
> 
> https://virtuozzo.atlassian.net/browse/VSTOR-148843
> 
> Feature: x86: cpu pools (cpuid override)
> Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>

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

-- 
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261006-b4-prep-khorenko-vstor-148656-cpuid-v3-0-16141b8ca07d@virtuozzo.com?part=5


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

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

* Re: [Devel] [PATCH hci-8.1 v3 1/5] selftests/ve: check CPUID override emulation for VE tasks
  2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 1/5] selftests/ve: check CPUID override emulation for VE tasks Konstantin Khorenko
@ 2026-10-06 20:52   ` no-reply
  0 siblings, 0 replies; 11+ messages in thread
From: no-reply @ 2026-10-06 20:52 UTC (permalink / raw)
  To: Vasileios Almpanis, Konstantin Khorenko, Pavel Tikhomirov; +Cc: devel

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] selftests/ve: stale self->child PID is killed in teardown after early reap
--

commit 2e6583525965f296409edf5f5ba686bf9a7c7bce
Author: Konstantin Khorenko <khorenko@virtuozzo.com>

selftests/ve: check CPUID override emulation for VE tasks

This commit adds a selftest for /proc/vz/cpuid_override. It checks that a
task in a fresh VE sees the override table values while the host sees the
hardware values. It also checks that a task armed before the table is
flushed falls back to the real CPUID afterwards.

Link: https://virtuozzo.atlassian.net/browse/VSTOR-148843

> diff --git a/tools/testing/selftests/ve/ve_cpuid_override_test.c b/tools/testing/selftests/ve/ve_cpuid_override_test.c
> new file mode 100644
> index 000000000000..0e3537099ddb
> --- /dev/null
> +++ b/tools/testing/selftests/ve/ve_cpuid_override_test.c

[ ... ]

> +FIXTURE_TEARDOWN_PARENT(ve_cpuid_override)
> +{
> +	int cgv2_fd;
> +
> +	if (write_cpuid_override(self->saved[0] ? self->saved : "\n"))
> +		TH_LOG("could not restore %s: %s", CPUID_OVERRIDE_PATH,
> +		       strerror(errno));
> +
> +	/* A child left stopped by a failed ASSERT keeps the VE cgroup busy. */
> +	if (self->child > 0)
> +		kill(self->child, SIGKILL);

[Severity: Low]
Can this kill() hit a PID that no longer belongs to the test child?

In spawn_cpuid_child(), self->child is set right after fork():

	self->child = pid;
	...
	ASSERT_GE(waitpid(pid, &status, WUNTRACED), 0);
	if (WIFEXITED(status))
		TH_LOG("child exited with %d before stopping",
		       WEXITSTATUS(status));
	ASSERT_TRUE(WIFSTOPPED(status));

If the child exits or is killed before it stops (for example cpuid_child()
returning 21, 22 or 24), waitpid() reaps it. ASSERT_TRUE(WIFSTOPPED(status))
then fails and aborts the test, but self->child is not cleared on that path.

self->child is only cleared in collect_cpuid_child(), which this path never
reaches. The teardown runs in the parent and sees the stale non-zero
self->child. It then calls kill(self->child, SIGKILL) on a PID that has
already been reaped and could have been reused by an unrelated process.

Would it make sense to clear self->child in spawn_cpuid_child() once
waitpid() has reaped the child, before the ASSERT_TRUE(WIFSTOPPED(status))
check?

[ ... ]

-- 
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261006-b4-prep-khorenko-vstor-148656-cpuid-v3-0-16141b8ca07d@virtuozzo.com?part=1

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

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

end of thread, other threads:[~2026-10-06 20:53 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-06 20:44 [Devel] [PATCH hci-8.1 v3 0/5] x86/ve: CPUID override follow-ups: arm at once, prefixes, selftests Konstantin Khorenko
2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 1/5] selftests/ve: check CPUID override emulation for VE tasks Konstantin Khorenko
2026-10-06 20:52   ` no-reply
2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 2/5] x86/ve: enable CPUID faulting at once when the current task enters a VE Konstantin Khorenko
2026-10-06 20:49   ` no-reply
2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 3/5] selftests/ve: check CPUID override right after entering " Konstantin Khorenko
2026-10-06 20:50   ` no-reply
2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 4/5] x86/traps: decode the faulting CPUID with the instruction decoder Konstantin Khorenko
2026-10-06 20:51   ` no-reply
2026-10-06 20:44 ` [Devel] [PATCH hci-8.1 v3 5/5] selftests/ve: check CPUID override emulation for a prefixed CPUID Konstantin Khorenko
2026-10-06 20:52   ` 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.