OpenVZ / Virtuozzo kernel development (devel@openvz.org)
 help / color / mirror / Atom feed
From: Konstantin Khorenko <khorenko@virtuozzo.com>
To: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>,
	Vasileios Almpanis <vasileios.almpanis@virtuozzo.com>
Cc: devel@openvz.org
Subject: [Devel] [PATCH hci-8.1 v2 3/5] selftests/ve: check CPUID override right after entering a VE
Date: Tue, 06 Oct 2026 19:19:12 +0200	[thread overview]
Message-ID: <20261006-b4-prep-khorenko-vstor-148656-cpuid-v2-3-f6d1192c7d60@virtuozzo.com> (raw)
In-Reply-To: <20261006-b4-prep-khorenko-vstor-148656-cpuid-v2-0-f6d1192c7d60@virtuozzo.com>

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  | 54 ++++++++++++++++------
 1 file changed, 41 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 291b88404a53e..0e748d4fd5f33 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
 /* 128 entries of up to 67 characters each, as the kernel prints them. */
 #define CPUID_TABLE_MAX		16384
 
@@ -56,13 +57,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)
@@ -73,7 +75,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);
@@ -148,7 +150,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,
 			       int cgv2_fd, int ctid, struct child_ctx *ctx)
 {
@@ -166,11 +168,13 @@ static pid_t spawn_cpuid_child(struct __test_metadata *_metadata,
 	ASSERT_GE(enter_cgroup(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;
 }
 
@@ -197,7 +201,7 @@ static void collect_cpuid_child(struct __test_metadata *_metadata, pid_t pid,
 
 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;
 
@@ -218,7 +222,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;
 
@@ -233,4 +237,28 @@ 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;
+	pid_t pid;
+	int i;
+
+	ASSERT_EQ(write_cpuid_override(self->table), 0);
+
+	for (i = 0; i < NO_RESCHED_ROUNDS; i++) {
+		struct child_ctx ctx = { .stop = 0 };
+
+		pid = spawn_cpuid_child(_metadata, self->cgv2_fd, self->ctid,
+					&ctx);
+		collect_cpuid_child(_metadata, pid, &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

  parent reply	other threads:[~2026-10-06 17:20 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-06 17:19 [Devel] [PATCH hci-8.1 v2 0/5] x86/ve: CPUID override follow-ups: arm at once, prefixes, selftests Konstantin Khorenko
2026-10-06 17:19 ` [Devel] [PATCH hci-8.1 v2 1/5] selftests/ve: check CPUID override emulation for VE tasks Konstantin Khorenko
2026-10-06 17:29   ` no-reply
2026-10-06 17:19 ` [Devel] [PATCH hci-8.1 v2 2/5] x86/ve: enable CPUID faulting at once when the current task enters a VE Konstantin Khorenko
2026-10-06 17:23   ` no-reply
2026-10-06 17:19 ` Konstantin Khorenko [this message]
2026-10-06 17:24   ` [Devel] [PATCH hci-8.1 v2 3/5] selftests/ve: check CPUID override right after entering " no-reply
2026-10-06 17:19 ` [Devel] [PATCH hci-8.1 v2 4/5] x86/traps: decode the faulting CPUID with the instruction decoder Konstantin Khorenko
2026-10-06 17:25   ` no-reply
2026-10-06 17:19 ` [Devel] [PATCH hci-8.1 v2 5/5] selftests/ve: check CPUID override emulation for a prefixed CPUID Konstantin Khorenko
2026-10-06 17:26   ` no-reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261006-b4-prep-khorenko-vstor-148656-cpuid-v2-3-f6d1192c7d60@virtuozzo.com \
    --to=khorenko@virtuozzo.com \
    --cc=devel@openvz.org \
    --cc=ptikhomirov@virtuozzo.com \
    --cc=vasileios.almpanis@virtuozzo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox