xref: /kvm-unit-tests/s390x/migration-cmm.c (revision c85124d28a51ea3619e91cf6da788142677f4a4d)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * CMM migration tests (ESSA)
4  *
5  * Copyright IBM Corp. 2022
6  *
7  * Authors:
8  *  Nico Boehr <nrb@linux.ibm.com>
9  */
10 
11 #include <libcflat.h>
12 #include <asm/interrupt.h>
13 #include <asm/page.h>
14 #include <asm/cmm.h>
15 #include <bitops.h>
16 
17 #define NUM_PAGES 128
18 static uint8_t pagebuf[NUM_PAGES][PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
19 
20 static void test_migration(void)
21 {
22 	int i, state_mask, actual_state;
23 	/*
24 	 * Maps ESSA actions to states the page is allowed to be in after the
25 	 * respective action was executed.
26 	 */
27 	int allowed_essa_state_masks[4] = {
28 		BIT(ESSA_USAGE_STABLE),					/* ESSA_SET_STABLE */
29 		BIT(ESSA_USAGE_UNUSED),					/* ESSA_SET_UNUSED */
30 		BIT(ESSA_USAGE_VOLATILE),				/* ESSA_SET_VOLATILE */
31 		BIT(ESSA_USAGE_VOLATILE) | BIT(ESSA_USAGE_POT_VOLATILE) /* ESSA_SET_POT_VOLATILE */
32 	};
33 
34 	assert(NUM_PAGES % 4 == 0);
35 	for (i = 0; i < NUM_PAGES; i += 4) {
36 		essa(ESSA_SET_STABLE, (unsigned long)pagebuf[i]);
37 		essa(ESSA_SET_UNUSED, (unsigned long)pagebuf[i + 1]);
38 		essa(ESSA_SET_VOLATILE, (unsigned long)pagebuf[i + 2]);
39 		essa(ESSA_SET_POT_VOLATILE, (unsigned long)pagebuf[i + 3]);
40 	}
41 
42 	puts("Please migrate me, then press return\n");
43 	(void)getchar();
44 
45 	for (i = 0; i < NUM_PAGES; i++) {
46 		actual_state = essa(ESSA_GET_STATE, (unsigned long)pagebuf[i]);
47 		/* extract the usage state in bits 60 and 61 */
48 		actual_state = (actual_state >> 2) & 0x3;
49 		state_mask = allowed_essa_state_masks[i % ARRAY_SIZE(allowed_essa_state_masks)];
50 		report(BIT(actual_state) & state_mask, "page %d state: expected_mask=0x%x actual_mask=0x%lx", i, state_mask, BIT(actual_state));
51 	}
52 }
53 
54 int main(void)
55 {
56 	bool has_essa = check_essa_available();
57 
58 	report_prefix_push("migration-cmm");
59 	if (!has_essa) {
60 		report_skip("ESSA is not available");
61 
62 		/*
63 		 * If we just exit and don't ask migrate_cmd to migrate us, it
64 		 * will just hang forever. Hence, also ask for migration when we
65 		 * skip this test alltogether.
66 		 */
67 		puts("Please migrate me, then press return\n");
68 		(void)getchar();
69 
70 		goto done;
71 	}
72 
73 	test_migration();
74 done:
75 	report_prefix_pop();
76 	return report_summary();
77 }
78