xref: /kvm-unit-tests/s390x/migration-skey.c (revision 4c8a99ca02252d4a2bee43f4558fe47ce5ab7ec0)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Storage Key migration tests
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/facility.h>
13 #include <asm/page.h>
14 #include <asm/mem.h>
15 #include <asm/interrupt.h>
16 #include <hardware.h>
17 
18 #define NUM_PAGES 128
19 static uint8_t pagebuf[NUM_PAGES][PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
20 
21 static void test_migration(void)
22 {
23 	union skey expected_key, actual_key;
24 	int i, key_to_set, key_mismatches = 0;
25 
26 	for (i = 0; i < NUM_PAGES; i++) {
27 		/*
28 		 * Storage keys are 7 bit, lowest bit is always returned as zero
29 		 * by iske.
30 		 * This loop will set all 7 bits which means we set fetch
31 		 * protection as well as reference and change indication for
32 		 * some keys.
33 		 */
34 		key_to_set = i * 2;
35 		set_storage_key(pagebuf[i], key_to_set, 1);
36 	}
37 
38 	puts("Please migrate me, then press return\n");
39 	(void)getchar();
40 
41 	for (i = 0; i < NUM_PAGES; i++) {
42 		actual_key.val = get_storage_key(pagebuf[i]);
43 		expected_key.val = i * 2;
44 
45 		/*
46 		 * The PoP neither gives a guarantee that the reference bit is
47 		 * accurate nor that it won't be cleared by hardware. Hence we
48 		 * don't rely on it and just clear the bits to avoid compare
49 		 * errors.
50 		 */
51 		actual_key.str.rf = 0;
52 		expected_key.str.rf = 0;
53 
54 		/* don't log anything when key matches to avoid spamming the log */
55 		if (actual_key.val != expected_key.val) {
56 			key_mismatches++;
57 			report_fail("page %d expected_key=0x%x actual_key=0x%x", i, expected_key.val, actual_key.val);
58 		}
59 	}
60 
61 	report(!key_mismatches, "skeys after migration match");
62 }
63 
64 int main(void)
65 {
66 	report_prefix_push("migration-skey");
67 	if (test_facility(169)) {
68 		report_skip("storage key removal facility is active");
69 
70 		/*
71 		 * If we just exit and don't ask migrate_cmd to migrate us, it
72 		 * will just hang forever. Hence, also ask for migration when we
73 		 * skip this test altogether.
74 		 */
75 		puts("Please migrate me, then press return\n");
76 		(void)getchar();
77 	} else {
78 		test_migration();
79 	}
80 
81 	report_prefix_pop();
82 	return report_summary();
83 }
84