xref: /kvm-unit-tests/s390x/skrf.c (revision 47df95c747e1c46e7bfb524e734d98a7d9757cb1)
1*47df95c7SJanosch Frank /*
2*47df95c7SJanosch Frank  * Storage key removal facility tests
3*47df95c7SJanosch Frank  *
4*47df95c7SJanosch Frank  * Copyright (c) 2019 IBM Corp
5*47df95c7SJanosch Frank  *
6*47df95c7SJanosch Frank  * Authors:
7*47df95c7SJanosch Frank  *  Janosch Frank <frankja@linux.ibm.com>
8*47df95c7SJanosch Frank  *
9*47df95c7SJanosch Frank  * This code is free software; you can redistribute it and/or modify it
10*47df95c7SJanosch Frank  * under the terms of the GNU General Public License version 2.
11*47df95c7SJanosch Frank  */
12*47df95c7SJanosch Frank #include <libcflat.h>
13*47df95c7SJanosch Frank #include <asm/asm-offsets.h>
14*47df95c7SJanosch Frank #include <asm/interrupt.h>
15*47df95c7SJanosch Frank #include <asm/page.h>
16*47df95c7SJanosch Frank #include <asm/facility.h>
17*47df95c7SJanosch Frank #include <asm/mem.h>
18*47df95c7SJanosch Frank 
19*47df95c7SJanosch Frank static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2)));
20*47df95c7SJanosch Frank 
21*47df95c7SJanosch Frank static void test_facilities(void)
22*47df95c7SJanosch Frank {
23*47df95c7SJanosch Frank 	report_prefix_push("facilities");
24*47df95c7SJanosch Frank 	report("!10", !test_facility(10));
25*47df95c7SJanosch Frank 	report("!14", !test_facility(14));
26*47df95c7SJanosch Frank 	report("!66", !test_facility(66));
27*47df95c7SJanosch Frank 	report("!145", !test_facility(145));
28*47df95c7SJanosch Frank 	report("!149", !test_facility(140));
29*47df95c7SJanosch Frank 	report_prefix_pop();
30*47df95c7SJanosch Frank }
31*47df95c7SJanosch Frank 
32*47df95c7SJanosch Frank static void test_skey(void)
33*47df95c7SJanosch Frank {
34*47df95c7SJanosch Frank 	report_prefix_push("sske");
35*47df95c7SJanosch Frank 	expect_pgm_int();
36*47df95c7SJanosch Frank 	set_storage_key(pagebuf, 0x30, 0);
37*47df95c7SJanosch Frank 	check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION);
38*47df95c7SJanosch Frank 	expect_pgm_int();
39*47df95c7SJanosch Frank 	report_prefix_pop();
40*47df95c7SJanosch Frank 	report_prefix_push("iske");
41*47df95c7SJanosch Frank 	get_storage_key(pagebuf);
42*47df95c7SJanosch Frank 	check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION);
43*47df95c7SJanosch Frank 	report_prefix_pop();
44*47df95c7SJanosch Frank }
45*47df95c7SJanosch Frank 
46*47df95c7SJanosch Frank static void test_pfmf(void)
47*47df95c7SJanosch Frank {
48*47df95c7SJanosch Frank 	union pfmf_r1 r1;
49*47df95c7SJanosch Frank 
50*47df95c7SJanosch Frank 	report_prefix_push("pfmf");
51*47df95c7SJanosch Frank 	r1.val = 0;
52*47df95c7SJanosch Frank 	r1.reg.sk = 1;
53*47df95c7SJanosch Frank 	r1.reg.fsc = PFMF_FSC_4K;
54*47df95c7SJanosch Frank 	r1.reg.key = 0x30;
55*47df95c7SJanosch Frank 	expect_pgm_int();
56*47df95c7SJanosch Frank 	pfmf(r1.val, pagebuf);
57*47df95c7SJanosch Frank 	check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION);
58*47df95c7SJanosch Frank 	report_prefix_pop();
59*47df95c7SJanosch Frank }
60*47df95c7SJanosch Frank 
61*47df95c7SJanosch Frank static void test_psw_key(void)
62*47df95c7SJanosch Frank {
63*47df95c7SJanosch Frank 	uint64_t psw_mask = extract_psw_mask() | 0xF0000000000000UL;
64*47df95c7SJanosch Frank 
65*47df95c7SJanosch Frank 	report_prefix_push("psw key");
66*47df95c7SJanosch Frank 	expect_pgm_int();
67*47df95c7SJanosch Frank 	load_psw_mask(psw_mask);
68*47df95c7SJanosch Frank 	check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION);
69*47df95c7SJanosch Frank 	report_prefix_pop();
70*47df95c7SJanosch Frank }
71*47df95c7SJanosch Frank 
72*47df95c7SJanosch Frank static void test_mvcos(void)
73*47df95c7SJanosch Frank {
74*47df95c7SJanosch Frank 	uint64_t r3 = 64;
75*47df95c7SJanosch Frank 	uint8_t *src = pagebuf;
76*47df95c7SJanosch Frank 	uint8_t *dst = pagebuf + PAGE_SIZE;
77*47df95c7SJanosch Frank 	/* K bit set, as well as keys */
78*47df95c7SJanosch Frank 	register unsigned long oac asm("0") = 0xf002f002;
79*47df95c7SJanosch Frank 
80*47df95c7SJanosch Frank 	report_prefix_push("mvcos");
81*47df95c7SJanosch Frank 	expect_pgm_int();
82*47df95c7SJanosch Frank 	asm volatile("mvcos	%[dst],%[src],%[len]"
83*47df95c7SJanosch Frank 		     : [dst] "+Q" (*(dst))
84*47df95c7SJanosch Frank 		     : [src] "Q" (*(src)), [len] "d" (r3), "d" (oac)
85*47df95c7SJanosch Frank 		     : "cc", "memory");
86*47df95c7SJanosch Frank 	check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION);
87*47df95c7SJanosch Frank 	report_prefix_pop();
88*47df95c7SJanosch Frank }
89*47df95c7SJanosch Frank 
90*47df95c7SJanosch Frank static void test_spka(void)
91*47df95c7SJanosch Frank {
92*47df95c7SJanosch Frank 	report_prefix_push("spka");
93*47df95c7SJanosch Frank 	expect_pgm_int();
94*47df95c7SJanosch Frank 	asm volatile("spka	0xf0(0)\n");
95*47df95c7SJanosch Frank 	check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION);
96*47df95c7SJanosch Frank 	report_prefix_pop();
97*47df95c7SJanosch Frank }
98*47df95c7SJanosch Frank 
99*47df95c7SJanosch Frank static void test_tprot(void)
100*47df95c7SJanosch Frank {
101*47df95c7SJanosch Frank 	report_prefix_push("tprot");
102*47df95c7SJanosch Frank 	expect_pgm_int();
103*47df95c7SJanosch Frank 	asm volatile("tprot	%[addr],0xf0(0)\n"
104*47df95c7SJanosch Frank 		     : : [addr] "a" (pagebuf) : );
105*47df95c7SJanosch Frank 	check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION);
106*47df95c7SJanosch Frank 	report_prefix_pop();
107*47df95c7SJanosch Frank }
108*47df95c7SJanosch Frank 
109*47df95c7SJanosch Frank int main(void)
110*47df95c7SJanosch Frank {
111*47df95c7SJanosch Frank 	report_prefix_push("skrf");
112*47df95c7SJanosch Frank 	if (!test_facility(169)) {
113*47df95c7SJanosch Frank 		report_skip("storage key removal facility not available\n");
114*47df95c7SJanosch Frank 		goto done;
115*47df95c7SJanosch Frank 	}
116*47df95c7SJanosch Frank 
117*47df95c7SJanosch Frank 	test_facilities();
118*47df95c7SJanosch Frank 	test_skey();
119*47df95c7SJanosch Frank 	test_pfmf();
120*47df95c7SJanosch Frank 	test_psw_key();
121*47df95c7SJanosch Frank 	test_mvcos();
122*47df95c7SJanosch Frank 	test_spka();
123*47df95c7SJanosch Frank 	test_tprot();
124*47df95c7SJanosch Frank 
125*47df95c7SJanosch Frank done:
126*47df95c7SJanosch Frank 	report_prefix_pop();
127*47df95c7SJanosch Frank 	return report_summary();
128*47df95c7SJanosch Frank }
129