diff --git a/s390x/Makefile b/s390x/Makefile
index efd5e0c13102..90df45285b0b 100644
--- a/s390x/Makefile
+++ b/s390x/Makefile
@@ -30,10 +30,11 @@ 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
 tests += $(TEST_DIR)/pv-attest.elf
 tests += $(TEST_DIR)/migration-cmm.elf
 tests += $(TEST_DIR)/migration-skey.elf
+tests += $(TEST_DIR)/migration-gs.elf
+tests += $(TEST_DIR)/migration-vec.elf
 
 pv-tests += $(TEST_DIR)/pv-diags.elf
 
diff --git a/s390x/migration-gs.c b/s390x/migration-gs.c
new file mode 100644
index 000000000000..c702d7493635
--- /dev/null
+++ b/s390x/migration-gs.c
@@ -0,0 +1,122 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * s390x Migration Test for Guarded-Storage Extension
+ *
+ * Copyright IBM Corp. 2022
+ *
+ * Authors:
+ *  Nico Boehr <nrb@linux.ibm.com>
+ */
+#include <libcflat.h>
+#include <asm/arch_def.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_guarded_storage_facility(void)
+{
+	return test_facility(133);
+}
+
+static void test_func(void)
+{
+	if (have_guarded_storage_facility()) {
+		ctl_set_bit(2, CTL2_GUARDED_STORAGE);
+
+		write_gs_regs();
+	}
+
+	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-gs");
+
+	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/migration.c b/s390x/migration-vec.c
similarity index 77%
rename from s390x/migration.c
rename to s390x/migration-vec.c
index a45296374cd8..2aab540f781b 100644
--- a/s390x/migration.c
+++ b/s390x/migration-vec.c
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Migration Test for s390x
+ * s390x Migration Test for Vector Extensions
  *
  * Copyright IBM Corp. 2022
  *
@@ -12,55 +12,19 @@
 #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];
@@ -69,12 +33,6 @@ static void test_func(void)
 	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];
@@ -145,14 +103,6 @@ static void test_func(void)
 
 	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;
 }
 
@@ -161,7 +111,7 @@ int main(void)
 	struct psw psw;
 
 	/* don't say migrate here otherwise we will migrate right away */
-	report_prefix_push("migration");
+	report_prefix_push("migration-vec");
 
 	if (smp_query_num_cpus() == 1) {
 		report_skip("need at least 2 cpus for this test");
diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
index 8e52f560bb1e..04d9f0761a1f 100644
--- a/s390x/unittests.cfg
+++ b/s390x/unittests.cfg
@@ -172,11 +172,6 @@ smp = 2
 accel = tcg
 extra_params = -cpu qemu,gs=off,vx=off
 
-[migration]
-file = migration.elf
-groups = migration
-smp = 2
-
 [migration-cmm]
 file = migration-cmm.elf
 groups = migration
@@ -184,3 +179,13 @@ groups = migration
 [migration-skey]
 file = migration-skey.elf
 groups = migration
+
+[migration-gs]
+file = migration-gs.elf
+groups = migration
+smp = 2
+
+[migration-vec]
+file = migration-vec.elf
+groups = migration
+smp = 2
