xref: /kvm-unit-tests/s390x/migration-skey.c (revision 03dca0b5151b24cb7eea20ff63df1b8d3fd3b0c9)
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 <migrate.h>
13 #include <asm/facility.h>
14 #include <asm/page.h>
15 #include <asm/mem.h>
16 #include <asm/interrupt.h>
17 #include <hardware.h>
18 
19 #define NUM_PAGES 128
20 static uint8_t pagebuf[NUM_PAGES][PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
21 
22 static void test_migration(void)
23 {
24 	union skey expected_key, actual_key;
25 	int i, key_to_set, key_mismatches = 0;
26 
27 	for (i = 0; i < NUM_PAGES; i++) {
28 		/*
29 		 * Storage keys are 7 bit, lowest bit is always returned as zero
30 		 * by iske.
31 		 * This loop will set all 7 bits which means we set fetch
32 		 * protection as well as reference and change indication for
33 		 * some keys.
34 		 */
35 		key_to_set = i * 2;
36 		set_storage_key(pagebuf[i], key_to_set, 1);
37 	}
38 
39 	migrate_once();
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 
68 	if (test_facility(169))
69 		report_skip("storage key removal facility is active");
70 	else
71 		test_migration();
72 
73 	migrate_once();
74 
75 	report_prefix_pop();
76 	return report_summary();
77 }
78