All of lore.kernel.org
 help / color / mirror / Atom feed
From: Claudio Imbrenda <imbrenda@linux.ibm.com>
To: pbonzini@redhat.com
Cc: kvm@vger.kernel.org, thuth@redhat.com, frankja@linux.ibm.com,
	Nico Boehr <nrb@linux.ibm.com>
Subject: [kvm-unit-tests GIT PULL 19/28] s390x: add basic migration test
Date: Thu, 12 May 2022 11:35:14 +0200	[thread overview]
Message-ID: <20220512093523.36132-20-imbrenda@linux.ibm.com> (raw)
In-Reply-To: <20220512093523.36132-1-imbrenda@linux.ibm.com>

From: Nico Boehr <nrb@linux.ibm.com>

Add a basic migration test for s390x. This tests the guarded-storage
registers and vector registers are preserved on migration.

Check for the respective facilities. Since it is possible neither
guarded-storage nor vector are there, add an additional report_pass()
such that least one PASS is reported.

Signed-off-by: Nico Boehr <nrb@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
---
 s390x/Makefile      |   1 +
 s390x/migration.c   | 198 ++++++++++++++++++++++++++++++++++++++++++++
 s390x/unittests.cfg |   5 ++
 3 files changed, 204 insertions(+)
 create mode 100644 s390x/migration.c

diff --git a/s390x/Makefile b/s390x/Makefile
index f38f442b..5336ed8a 100644
--- a/s390x/Makefile
+++ b/s390x/Makefile
@@ -30,6 +30,7 @@ tests += $(TEST_DIR)/spec_ex-sie.elf
 tests += $(TEST_DIR)/firq.elf
 tests += $(TEST_DIR)/epsw.elf
 tests += $(TEST_DIR)/adtl-status.elf
+tests += $(TEST_DIR)/migration.elf
 
 pv-tests += $(TEST_DIR)/pv-diags.elf
 
diff --git a/s390x/migration.c b/s390x/migration.c
new file mode 100644
index 00000000..a4529637
--- /dev/null
+++ b/s390x/migration.c
@@ -0,0 +1,198 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Migration Test for s390x
+ *
+ * Copyright IBM Corp. 2022
+ *
+ * Authors:
+ *  Nico Boehr <nrb@linux.ibm.com>
+ */
+#include <libcflat.h>
+#include <asm/arch_def.h>
+#include <asm/vector.h>
+#include <asm/barrier.h>
+#include <asm/facility.h>
+#include <gs.h>
+#include <bitops.h>
+#include <smp.h>
+
+static struct gs_cb gs_cb;
+static struct gs_epl gs_epl;
+
+/* set by CPU1 to signal it has completed */
+static int flag_thread_complete;
+/* set by CPU0 to signal migration has completed */
+static int flag_migration_complete;
+
+static void write_gs_regs(void)
+{
+	const unsigned long gs_area = 0x2000000;
+	const unsigned long gsc = 25; /* align = 32 M, section size = 512K */
+
+	gs_cb.gsd = gs_area | gsc;
+	gs_cb.gssm = 0xfeedc0ffe;
+	gs_cb.gs_epl_a = (uint64_t) &gs_epl;
+
+	load_gs_cb(&gs_cb);
+}
+
+static void check_gs_regs(void)
+{
+	struct gs_cb gs_cb_after_migration;
+
+	store_gs_cb(&gs_cb_after_migration);
+
+	report_prefix_push("guarded-storage registers");
+
+	report(gs_cb_after_migration.gsd == gs_cb.gsd, "gsd matches");
+	report(gs_cb_after_migration.gssm == gs_cb.gssm, "gssm matches");
+	report(gs_cb_after_migration.gs_epl_a == gs_cb.gs_epl_a, "gs_epl_a matches");
+
+	report_prefix_pop();
+}
+
+static bool have_vector_facility(void)
+{
+	return test_facility(129);
+}
+
+static bool have_guarded_storage_facility(void)
+{
+	return test_facility(133);
+}
+
+static void test_func(void)
+{
+	uint8_t expected_vec_contents[VEC_REGISTER_NUM][VEC_REGISTER_SIZE];
+	uint8_t actual_vec_contents[VEC_REGISTER_NUM][VEC_REGISTER_SIZE];
+	uint8_t *vec_reg;
+	int i;
+	int vec_result = 0;
+
+	if (have_guarded_storage_facility()) {
+		ctl_set_bit(2, CTL2_GUARDED_STORAGE);
+
+		write_gs_regs();
+	}
+
+	if (have_vector_facility()) {
+		for (i = 0; i < VEC_REGISTER_NUM; i++) {
+			vec_reg = &expected_vec_contents[i][0];
+			/* i+1 to avoid zero content */
+			memset(vec_reg, i + 1, VEC_REGISTER_SIZE);
+		}
+
+		ctl_set_bit(0, CTL0_VECTOR);
+
+		/*
+		 * It is important loading the vector/floating point registers and
+		 * comparing their contents occurs in the same inline assembly block.
+		 * Otherwise, the compiler is allowed to re-use the registers for
+		 * something else in between.
+		 * For this very reason, this also runs on a second CPU, so all the
+		 * complex console stuff can be done in C on the first CPU and here we
+		 * just need to wait for it to set the flag.
+		 */
+		asm inline(
+			"	.machine z13\n"
+			/* load vector registers: vlm handles at most 16 registers at a time */
+			"	vlm 0,15, 0(%[expected_vec_reg])\n"
+			"	vlm 16,31, 256(%[expected_vec_reg])\n"
+			/* inform CPU0 we are done, it will request migration */
+			"	mvhi %[flag_thread_complete], 1\n"
+			/* wait for migration to finish */
+			"0:	clfhsi %[flag_migration_complete], 1\n"
+			"	jnz 0b\n"
+			/*
+			 * store vector register contents in actual_vec_reg: vstm
+			 * handles at most 16 registers at a time
+			 */
+			"	vstm 0,15, 0(%[actual_vec_reg])\n"
+			"	vstm 16,31, 256(%[actual_vec_reg])\n"
+			/*
+			 * compare the contents in expected_vec_reg with actual_vec_reg:
+			 * clc handles at most 256 bytes at a time
+			 */
+			"	clc 0(256, %[expected_vec_reg]), 0(%[actual_vec_reg])\n"
+			"	jnz 1f\n"
+			"	clc 256(256, %[expected_vec_reg]), 256(%[actual_vec_reg])\n"
+			"	jnz 1f\n"
+			/* success */
+			"	mvhi %[vec_result], 1\n"
+			"1:"
+			:
+			: [expected_vec_reg] "a"(expected_vec_contents),
+			  [actual_vec_reg] "a"(actual_vec_contents),
+			  [flag_thread_complete] "Q"(flag_thread_complete),
+			  [flag_migration_complete] "Q"(flag_migration_complete),
+			  [vec_result] "Q"(vec_result)
+			: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9",
+			  "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18",
+			  "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27",
+			  "v28", "v29", "v30", "v31", "cc", "memory"
+		);
+
+		report(vec_result, "vector contents match");
+
+		report(stctg(0) & BIT(CTL0_VECTOR), "ctl0 vector bit set");
+
+		ctl_clear_bit(0, CTL0_VECTOR);
+	} else {
+		flag_thread_complete = 1;
+		while(!flag_migration_complete)
+			mb();
+	}
+
+	report_pass("Migrated");
+
+	if (have_guarded_storage_facility()) {
+		check_gs_regs();
+
+		report(stctg(2) & BIT(CTL2_GUARDED_STORAGE), "ctl2 guarded-storage bit set");
+
+		ctl_clear_bit(2, CTL2_GUARDED_STORAGE);
+	}
+
+	flag_thread_complete = 1;
+}
+
+int main(void)
+{
+	struct psw psw;
+
+	/* don't say migrate here otherwise we will migrate right away */
+	report_prefix_push("migration");
+
+	if (smp_query_num_cpus() == 1) {
+		report_skip("need at least 2 cpus for this test");
+		goto done;
+	}
+
+	/* Second CPU does the actual tests */
+	psw.mask = extract_psw_mask();
+	psw.addr = (unsigned long)test_func;
+	smp_cpu_setup(1, psw);
+
+	/* wait for thread setup */
+	while(!flag_thread_complete)
+		mb();
+	flag_thread_complete = 0;
+
+	/* ask migrate_cmd to migrate (it listens for 'migrate') */
+	puts("Please migrate me, then press return\n");
+
+	/* wait for migration to finish, we will read a newline */
+	(void)getchar();
+
+	flag_migration_complete = 1;
+
+	/* wait for thread to complete assertions */
+	while(!flag_thread_complete)
+		mb();
+
+	smp_cpu_destroy(1);
+
+done:
+	report_prefix_pop();
+	return report_summary();
+}
diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
index 256c7169..b456b288 100644
--- a/s390x/unittests.cfg
+++ b/s390x/unittests.cfg
@@ -171,3 +171,8 @@ file = adtl-status.elf
 smp = 2
 accel = tcg
 extra_params = -cpu qemu,gs=off,vx=off
+
+[migration]
+file = migration.elf
+groups = migration
+smp = 2
-- 
2.36.1


  parent reply	other threads:[~2022-05-12  9:36 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-12  9:34 [kvm-unit-tests GIT PULL 00/28] storage keys, attestation, migration tests Claudio Imbrenda
2022-05-12  9:34 ` [kvm-unit-tests GIT PULL 01/28] s390x: gs: move to new header file Claudio Imbrenda
2022-05-12  9:34 ` [kvm-unit-tests GIT PULL 02/28] s390x: add test for SIGP STORE_ADTL_STATUS order Claudio Imbrenda
2022-09-20 15:53   ` Thomas Huth
2022-10-05 13:18     ` Nico Boehr
2022-10-05 13:25       ` Thomas Huth
2022-10-05 14:00         ` Nico Boehr
2022-05-12  9:34 ` [kvm-unit-tests GIT PULL 03/28] s390x: epsw: fix report_pop_prefix() when running under non-QEMU Claudio Imbrenda
2022-05-12  9:34 ` [kvm-unit-tests GIT PULL 04/28] s390x: tprot: use lib include for mmu.h Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 05/28] s390x: smp: make stop stopped cpu look the same as the running case Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 06/28] lib: s390x: hardware: Add host_is_qemu() function Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 07/28] s390x: css: Skip if we're not run by qemu Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 08/28] s390x: diag308: Only test subcode 2 under QEMU Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 09/28] s390x: pfmf: Initialize pfmf_r1 union on declaration Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 10/28] s390x: snippets: asm: Add license and copyright headers Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 11/28] s390x: pv-diags: Cleanup includes Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 12/28] s390x: css: " Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 13/28] s390x: iep: " Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 14/28] s390x: mvpg: " Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 15/28] s390x: uv-host: Fix pgm tests Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 16/28] lib: s390x: add support for SCLP console read Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 17/28] s390x: add support for migration tests Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 18/28] s390x: don't run migration tests under PV Claudio Imbrenda
2022-05-12  9:35 ` Claudio Imbrenda [this message]
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 20/28] s390x: Give name to return value of tprot() Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 21/28] s390x: Test effect of storage keys on some instructions Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 22/28] Disable s390x skey test in GitLab CI Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 23/28] s390x: uv-host: Add invalid command attestation check Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 24/28] s390x: lib: Add QUI getter Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 25/28] s390x: uv-guest: remove duplicated checks Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 26/28] s390x: uv-guest: Remove double report_prefix_pop Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 27/28] s390x: uv-guest: add share bit test Claudio Imbrenda
2022-05-12  9:35 ` [kvm-unit-tests GIT PULL 28/28] s390x: Add attestation tests Claudio Imbrenda

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=20220512093523.36132-20-imbrenda@linux.ibm.com \
    --to=imbrenda@linux.ibm.com \
    --cc=frankja@linux.ibm.com \
    --cc=kvm@vger.kernel.org \
    --cc=nrb@linux.ibm.com \
    --cc=pbonzini@redhat.com \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

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

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