[kvm-unit-tests GIT PULL 11/13] s390x: stsi: regression test for the STSI 3.2.2 count clamp

Janosch Frank <[email protected]>
Newsgroups org.kernel.vger.kvm,org.kernel.vger.linux-s390
Message-ID <[email protected]>
From: Christian Borntraeger <[email protected]>

See https://lore.kernel.org/qemu-devel/[email protected]/
for the QEMU fix.
Add a regression test that races STSI 3.2.2 on one CPU against a second CPU
that continuously forces an out-of-range count value.
The out of bound access usually crashes/asserts QEMU with any sane
distribution build of QEMU, so its more or less guest root can kill itself.
We should test and fix nevertheless.
Testcase piggybacks on the existing stsi test, so some cases will be
tested twice. (with smp 1 and smp 2)

Signed-off-by: Christian Borntraeger <[email protected]>
Cc: Cornelia Huck <[email protected]>
Reviewed-by: Janosch Frank <[email protected]>
Reviewed-by: Cornelia Huck <[email protected]>
[[email protected]: Merged the new unittests.cgf entry into old one]
Signed-off-by: Janosch Frank <[email protected]>
---
 s390x/stsi.c        | 76 ++++++++++++++++++++++++++++++++++++++++++++-
 s390x/unittests.cfg |  2 +-
 2 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/s390x/stsi.c b/s390x/stsi.c
index 94a579dc..96361143 100644
--- a/s390x/stsi.c
+++ b/s390x/stsi.c
@@ -2,7 +2,7 @@
 /*
  * Store System Information tests
  *
- * Copyright (c) 2019 IBM Corp
+ * Copyright IBM Corp. 2019,2026
  *
  * Authors:
  *  Janosch Frank <[email protected]>
@@ -133,6 +133,79 @@ out:
 	report_prefix_pop();
 }
 
+/*
+ * Number of STSI 3.2.2 calls raced against the count corruptor below.
+ * A memory write should be faster than an kvm->qemu exit, so 100 is
+ * good enough.
+ */
+#define RACE_ITERATIONS 100
+static u8 corrupt_count_value;
+
+static void count_corruptor(void)
+{
+	struct sysinfo_3_2_2 *data = (void *)pagebuf;
+
+	for (;;)
+		*(volatile u8 *)&data->count = corrupt_count_value;
+}
+
+/*
+ * Race STSI 3.2.2 on the boot CPU against a secondary CPU that continuously
+ * forces the given out-of-range value into the "count" field. Returns true
+ * if every STSI returned cc == 0, false on an unexpected condition code.
+ */
+static bool race_count_value(uint8_t value)
+{
+	int i, cc;
+
+	corrupt_count_value = value;
+	smp_cpu_setup(1, PSW_WITH_CUR_MASK(count_corruptor));
+
+	for (i = 0; i < RACE_ITERATIONS; i++) {
+		cc = stsi(pagebuf, 3, 2, 2);
+		if (cc) {
+			report_fail("count 0x%02x: unexpected cc %d on iteration %d",
+				    value, cc, i);
+			break;
+		}
+	}
+
+	smp_cpu_stop(1);
+	smp_cpu_destroy(1);
+
+	return i == RACE_ITERATIONS;
+}
+
+/*
+ * The count value is 8 bit and valid values are 1-8 if stsi 3.2.2 is present.
+ * We test 0,9 as off-by-one, and 0xff as maximum value.
+ */
+static void test_3_2_2_race(void)
+{
+	report_prefix_push("3.2.2 count race");
+
+	if (stsi_get_fc() < 3) {
+		report_skip("Running under lpar, no level 3 to test.");
+		goto out;
+	}
+
+	if (smp_query_num_cpus() < 2) {
+		report_skip("Need at least 2 CPUs to race the count field.");
+		goto out;
+	}
+
+	if (race_count_value(0x0))
+		report_pass("host survived racing STSI 3.2.2 count 0x00");
+
+	if (race_count_value(0x9))
+		report_pass("host survived racing STSI 3.2.2 count 0x09");
+
+	if (race_count_value(0xff))
+		report_pass("host survived racing STSI 3.2.2 count 0xff");
+out:
+	report_prefix_pop();
+}
+
 int main(void)
 {
 	report_prefix_push("stsi");
@@ -140,5 +213,6 @@ int main(void)
 	test_specs();
 	test_fc();
 	test_3_2_2();
+	test_3_2_2_race();
 	return report_summary();
 }
diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
index ed4d069e..8c39d4f1 100644
--- a/s390x/unittests.cfg
+++ b/s390x/unittests.cfg
@@ -79,7 +79,7 @@ qemu_params=-device diag288,id=watchdog0 --watchdog-action inject-nmi
 
 [stsi]
 file = stsi.elf
-qemu_params=-name kvm-unit-test --uuid 0fb84a86-727c-11ea-bc55-0242ac130003 -smp 1,maxcpus=8
+qemu_params=-name kvm-unit-test --uuid 0fb84a86-727c-11ea-bc55-0242ac130003 -smp 2,maxcpus=8
 
 [smp]
 file = smp.elf
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.