xref: /kvm-unit-tests/s390x/skey.c (revision e11a0e2f881d7bc038f44d8d4f99b2d55a01bc4e)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Storage key tests
4  *
5  * Copyright (c) 2018 IBM Corp
6  *
7  * Authors:
8  *  Janosch Frank <frankja@linux.vnet.ibm.com>
9  */
10 #include <libcflat.h>
11 #include <asm/arch_def.h>
12 #include <asm/asm-offsets.h>
13 #include <asm/interrupt.h>
14 #include <vmalloc.h>
15 #include <css.h>
16 #include <asm/page.h>
17 #include <asm/facility.h>
18 #include <asm/mem.h>
19 
20 
21 static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2)));
22 
test_set_mb(void)23 static void test_set_mb(void)
24 {
25 	union skey skey, ret1, ret2;
26 	void *addr = (void *)0x10000 - 2 * PAGE_SIZE;
27 	void *end = (void *)0x10000;
28 
29 	/* Multi block support came with EDAT 1 */
30 	if (!test_facility(8))
31 		return;
32 
33 	skey.val = 0x30;
34 	while (addr < end)
35 		addr = set_storage_key_mb(addr, skey.val);
36 
37 	ret1.val = get_storage_key(end - PAGE_SIZE) & (SKEY_ACC | SKEY_FP);
38 	ret2.val = get_storage_key(end - PAGE_SIZE * 2) & (SKEY_ACC | SKEY_FP);
39 	report(ret1.val == ret2.val && ret1.val == skey.val, "multi block");
40 }
41 
test_chg(void)42 static void test_chg(void)
43 {
44 	union skey skey1, skey2;
45 
46 	skey1.val = 0x30;
47 	set_storage_key(pagebuf, skey1.val, 0);
48 	skey1.val = get_storage_key(pagebuf);
49 	pagebuf[0] = 3;
50 	skey2.val = get_storage_key(pagebuf);
51 	report(!skey1.str.ch && skey2.str.ch, "chg bit test");
52 }
53 
test_set(void)54 static void test_set(void)
55 {
56 	union skey skey, ret;
57 
58 	skey.val = 0x30;
59 	ret.val = get_storage_key(pagebuf);
60 	set_storage_key(pagebuf, skey.val, 0);
61 	ret.val = get_storage_key(pagebuf);
62 	/*
63 	 * For all set tests we only test the ACC and FP bits. RF and
64 	 * CH are set by the machine for memory references and changes
65 	 * and hence might change between a set and a get.
66 	 */
67 	report(skey.str.acc == ret.str.acc && skey.str.fp == ret.str.fp,
68 	       "set key test");
69 }
70 
test_priv(void)71 static void test_priv(void)
72 {
73 	union skey skey;
74 
75 	memset(pagebuf, 0, PAGE_SIZE * 2);
76 	report_prefix_push("privileged");
77 	report_prefix_push("sske");
78 	expect_pgm_int();
79 	enter_pstate();
80 	set_storage_key(pagebuf, 0x30, 0);
81 	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
82 	report_prefix_pop();
83 
84 	skey.val = get_storage_key(pagebuf);
85 	report(skey.str.acc != 3, "skey did not change on exception");
86 
87 	report_prefix_push("iske");
88 	expect_pgm_int();
89 	enter_pstate();
90 	get_storage_key(pagebuf);
91 	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
92 	report_prefix_pop();
93 
94 	report_prefix_pop();
95 }
96 
test_invalid_address(void)97 static void test_invalid_address(void)
98 {
99 	void *inv_addr = (void *)-1ull;
100 
101 	report_prefix_push("invalid address");
102 
103 	report_prefix_push("sske");
104 	expect_pgm_int();
105 	set_storage_key(inv_addr, 0, 0);
106 	check_pgm_int_code(PGM_INT_CODE_ADDRESSING);
107 	report_prefix_pop();
108 
109 	report_prefix_push("iske");
110 	expect_pgm_int();
111 	get_storage_key(inv_addr);
112 	check_pgm_int_code(PGM_INT_CODE_ADDRESSING);
113 	report_prefix_pop();
114 
115 	report_prefix_push("rrbe");
116 	expect_pgm_int();
117 	reset_reference_bit(inv_addr);
118 	check_pgm_int_code(PGM_INT_CODE_ADDRESSING);
119 	report_prefix_pop();
120 
121 	report_prefix_pop();
122 }
123 
test_test_protection(void)124 static void test_test_protection(void)
125 {
126 	unsigned long addr = (unsigned long)pagebuf;
127 
128 	report_prefix_push("TPROT");
129 
130 	set_storage_key(pagebuf, 0x10, 0);
131 	report(tprot(addr, 0) == TPROT_READ_WRITE, "zero key: no protection");
132 	report(tprot(addr, 1) == TPROT_READ_WRITE, "matching key: no protection");
133 
134 	report_prefix_push("mismatching key");
135 
136 	report(tprot(addr, 2) == TPROT_READ, "no fetch protection: store protection");
137 
138 	set_storage_key(pagebuf, 0x18, 0);
139 	report(tprot(addr, 2) == TPROT_RW_PROTECTED,
140 	       "fetch protection: fetch & store protection");
141 
142 	report_prefix_push("fetch-protection override");
143 	set_storage_key(0, 0x18, 0);
144 	report(tprot(0, 2) == TPROT_RW_PROTECTED, "disabled: fetch & store protection");
145 	ctl_set_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE);
146 	report(tprot(0, 2) == TPROT_READ, "enabled: store protection");
147 	report(tprot(2048, 2) == TPROT_RW_PROTECTED, "invalid: fetch & store protection");
148 	ctl_clear_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE);
149 	set_storage_key(0, 0x00, 0);
150 	report_prefix_pop();
151 
152 	ctl_set_bit(0, CTL0_STORAGE_PROTECTION_OVERRIDE);
153 	set_storage_key(pagebuf, 0x90, 0);
154 	report(tprot(addr, 2) == TPROT_READ_WRITE,
155 	       "storage-protection override: no protection");
156 	ctl_clear_bit(0, CTL0_STORAGE_PROTECTION_OVERRIDE);
157 
158 	report_prefix_pop();
159 	set_storage_key(pagebuf, 0x00, 0);
160 	report_prefix_pop();
161 }
162 
163 enum access {
164 	ACC_STORE = 1,
165 	ACC_FETCH = 2,
166 	ACC_UPDATE = 3,
167 };
168 
169 enum protection {
170 	PROT_STORE = 1,
171 	PROT_FETCH_STORE = 3,
172 };
173 
check_key_prot_exc(enum access access,enum protection prot)174 static void check_key_prot_exc(enum access access, enum protection prot)
175 {
176 	union teid teid;
177 	int access_code;
178 
179 	check_pgm_int_code(PGM_INT_CODE_PROTECTION);
180 	report_prefix_push("TEID");
181 	teid.val = lowcore.trans_exc_id;
182 	switch (get_supp_on_prot_facility()) {
183 	case SOP_NONE:
184 	case SOP_BASIC:
185 		/* let's ignore ancient/irrelevant machines */
186 		break;
187 	case SOP_ENHANCED_1:
188 		report(!teid.sop_teid_predictable, "valid protection code");
189 		/* no access code in case of key protection */
190 		break;
191 	case SOP_ENHANCED_2:
192 		switch (teid_esop2_prot_code(teid)) {
193 		case PROT_KEY:
194 			/* ESOP-2: no need to check facility */
195 			access_code = teid.acc_exc_fetch_store;
196 
197 			switch (access_code) {
198 			case 0:
199 				report_pass("valid access code");
200 				break;
201 			case 1:
202 			case 2:
203 				report((access & access_code) && (prot & access_code),
204 				       "valid access code");
205 				break;
206 			case 3:
207 				/*
208 				 * This is incorrect in that reserved values
209 				 * should be ignored, but kvm should not return
210 				 * a reserved value and having a test for that
211 				 * is more valuable.
212 				 */
213 				report_fail("valid access code");
214 				break;
215 			}
216 			/* fallthrough */
217 		case PROT_KEY_OR_LAP:
218 			report_pass("valid protection code");
219 			break;
220 		default:
221 			report_fail("valid protection code");
222 		}
223 		break;
224 	}
225 	report_prefix_pop();
226 }
227 
228 /*
229  * Perform STORE CPU ADDRESS (STAP) instruction while temporarily executing
230  * with access key 1.
231  */
store_cpu_address_key_1(uint16_t * out)232 static void store_cpu_address_key_1(uint16_t *out)
233 {
234 	asm volatile (
235 		"spka	0x10\n\t"
236 		"stap	%0\n\t"
237 		"spka	0\n"
238 	     : "+Q" (*out) /* exception: old value remains in out -> + constraint */
239 	);
240 }
241 
test_store_cpu_address(void)242 static void test_store_cpu_address(void)
243 {
244 	uint16_t *out = (uint16_t *)pagebuf;
245 	uint16_t cpu_addr;
246 
247 	report_prefix_push("STORE CPU ADDRESS");
248 	asm ("stap %0" : "=Q" (cpu_addr));
249 
250 	report_prefix_push("zero key");
251 	set_storage_key(pagebuf, 0x20, 0);
252 	WRITE_ONCE(*out, 0xbeef);
253 	asm ("stap %0" : "=Q" (*out));
254 	report(*out == cpu_addr, "store occurred");
255 	report_prefix_pop();
256 
257 	report_prefix_push("matching key");
258 	set_storage_key(pagebuf, 0x10, 0);
259 	*out = 0xbeef;
260 	store_cpu_address_key_1(out);
261 	report(*out == cpu_addr, "store occurred");
262 	report_prefix_pop();
263 
264 	report_prefix_push("mismatching key");
265 	set_storage_key(pagebuf, 0x20, 0);
266 	expect_pgm_int();
267 	*out = 0xbeef;
268 	store_cpu_address_key_1(out);
269 	check_key_prot_exc(ACC_STORE, PROT_STORE);
270 	report(*out == 0xbeef, "no store occurred");
271 	report_prefix_pop();
272 
273 	ctl_set_bit(0, CTL0_STORAGE_PROTECTION_OVERRIDE);
274 
275 	report_prefix_push("storage-protection override, invalid key");
276 	set_storage_key(pagebuf, 0x20, 0);
277 	expect_pgm_int();
278 	*out = 0xbeef;
279 	store_cpu_address_key_1(out);
280 	check_key_prot_exc(ACC_STORE, PROT_STORE);
281 	report(*out == 0xbeef, "no store occurred");
282 	report_prefix_pop();
283 
284 	report_prefix_push("storage-protection override, override key");
285 	set_storage_key(pagebuf, 0x90, 0);
286 	*out = 0xbeef;
287 	store_cpu_address_key_1(out);
288 	report(*out == cpu_addr, "override occurred");
289 	report_prefix_pop();
290 
291 	ctl_clear_bit(0, CTL0_STORAGE_PROTECTION_OVERRIDE);
292 
293 	report_prefix_push("storage-protection override disabled, override key");
294 	set_storage_key(pagebuf, 0x90, 0);
295 	expect_pgm_int();
296 	*out = 0xbeef;
297 	store_cpu_address_key_1(out);
298 	check_key_prot_exc(ACC_STORE, PROT_STORE);
299 	report(*out == 0xbeef, "no store occurred");
300 	report_prefix_pop();
301 
302 	set_storage_key(pagebuf, 0x00, 0);
303 	report_prefix_pop();
304 }
305 
test_diag_308(void)306 static void test_diag_308(void)
307 {
308 	uint16_t response;
309 	uint32_t *ipib = (uint32_t *)pagebuf;
310 
311 	report_prefix_push("DIAG 308");
312 	WRITE_ONCE(ipib[0], 0); /* Invalid length */
313 	set_storage_key(ipib, 0x28, 0);
314 	/* key-controlled protection does not apply */
315 	asm volatile (
316 		"lr	%%r2,%[ipib]\n\t"
317 		"spka	0x10\n\t"
318 		"diag	%%r2,%[code],0x308\n\t"
319 		"spka	0\n\t"
320 		"lr	%[response],%%r3\n"
321 		: [response] "=d" (response)
322 		: [ipib] "d" (ipib),
323 		  [code] "d" (5L)
324 		: "%r2", "%r3"
325 	);
326 	report(response == 0x402, "no exception on fetch, response: invalid IPIB");
327 	set_storage_key(ipib, 0x00, 0);
328 	report_prefix_pop();
329 }
330 
331 /*
332  * Perform CHANNEL SUBSYSTEM CALL (CHSC)  instruction while temporarily executing
333  * with access key 1.
334  */
chsc_key_1(void * comm_block)335 static unsigned int chsc_key_1(void *comm_block)
336 {
337 	uint32_t program_mask;
338 
339 	asm volatile (
340 		"spka	0x10\n\t"
341 		".insn	rre,0xb25f0000,%[comm_block],0\n\t"
342 		"spka	0\n\t"
343 		"ipm	%[program_mask]\n"
344 		: [program_mask] "=d" (program_mask)
345 		: [comm_block] "d" (comm_block)
346 		: "memory"
347 	);
348 	return program_mask >> 28;
349 }
350 
351 static const char chsc_msg[] = "Performed store-channel-subsystem-characteristics";
init_comm_block(uint16_t * comm_block)352 static void init_comm_block(uint16_t *comm_block)
353 {
354 	memset(comm_block, 0, PAGE_SIZE);
355 	/* store-channel-subsystem-characteristics command */
356 	comm_block[0] = 0x10;
357 	comm_block[1] = 0x10;
358 	comm_block[9] = 0;
359 }
360 
test_channel_subsystem_call(void)361 static void test_channel_subsystem_call(void)
362 {
363 	uint16_t *comm_block = (uint16_t *)&pagebuf;
364 	unsigned int cc;
365 
366 	report_prefix_push("CHANNEL SUBSYSTEM CALL");
367 
368 	report_prefix_push("zero key");
369 	init_comm_block(comm_block);
370 	set_storage_key(comm_block, 0x10, 0);
371 	asm volatile (
372 		".insn	rre,0xb25f0000,%[comm_block],0\n\t"
373 		"ipm	%[cc]\n"
374 		: [cc] "=d" (cc)
375 		: [comm_block] "d" (comm_block)
376 		: "memory"
377 	);
378 	cc = cc >> 28;
379 	report(cc == 0 && comm_block[9], chsc_msg);
380 	report_prefix_pop();
381 
382 	report_prefix_push("matching key");
383 	init_comm_block(comm_block);
384 	set_storage_key(comm_block, 0x10, 0);
385 	cc = chsc_key_1(comm_block);
386 	report(cc == 0 && comm_block[9], chsc_msg);
387 	report_prefix_pop();
388 
389 	report_prefix_push("mismatching key");
390 
391 	report_prefix_push("no fetch protection");
392 	init_comm_block(comm_block);
393 	set_storage_key(comm_block, 0x20, 0);
394 	expect_pgm_int();
395 	chsc_key_1(comm_block);
396 	check_key_prot_exc(ACC_UPDATE, PROT_STORE);
397 	report_prefix_pop();
398 
399 	report_prefix_push("fetch protection");
400 	init_comm_block(comm_block);
401 	set_storage_key(comm_block, 0x28, 0);
402 	expect_pgm_int();
403 	chsc_key_1(comm_block);
404 	check_key_prot_exc(ACC_UPDATE, PROT_FETCH_STORE);
405 	report_prefix_pop();
406 
407 	ctl_set_bit(0, CTL0_STORAGE_PROTECTION_OVERRIDE);
408 
409 	report_prefix_push("storage-protection override, invalid key");
410 	set_storage_key(comm_block, 0x20, 0);
411 	init_comm_block(comm_block);
412 	expect_pgm_int();
413 	chsc_key_1(comm_block);
414 	check_key_prot_exc(ACC_UPDATE, PROT_STORE);
415 	report_prefix_pop();
416 
417 	report_prefix_push("storage-protection override, override key");
418 	init_comm_block(comm_block);
419 	set_storage_key(comm_block, 0x90, 0);
420 	cc = chsc_key_1(comm_block);
421 	report(cc == 0 && comm_block[9], chsc_msg);
422 	report_prefix_pop();
423 
424 	ctl_clear_bit(0, CTL0_STORAGE_PROTECTION_OVERRIDE);
425 
426 	report_prefix_push("storage-protection override disabled, override key");
427 	init_comm_block(comm_block);
428 	set_storage_key(comm_block, 0x90, 0);
429 	expect_pgm_int();
430 	chsc_key_1(comm_block);
431 	check_key_prot_exc(ACC_UPDATE, PROT_STORE);
432 	report_prefix_pop();
433 
434 	report_prefix_pop();
435 
436 	set_storage_key(comm_block, 0x00, 0);
437 	report_prefix_pop();
438 }
439 
440 /*
441  * Perform SET PREFIX (SPX) instruction while temporarily executing
442  * with access key 1.
443  */
set_prefix_key_1(uint32_t * prefix_ptr)444 static void set_prefix_key_1(uint32_t *prefix_ptr)
445 {
446 	asm volatile (
447 		"spka	0x10\n\t"
448 		"spx	%0\n\t"
449 		"spka	0\n"
450 	     :: "Q" (*prefix_ptr)
451 	);
452 }
453 
454 #define PREFIX_AREA_SIZE (PAGE_SIZE * 2)
455 static char lowcore_tmp[PREFIX_AREA_SIZE] __attribute__((aligned(PREFIX_AREA_SIZE)));
456 
457 /*
458  * Test accessibility of the operand to SET PREFIX given different configurations
459  * with regards to storage keys. That is, check the accessibility of the location
460  * holding the new prefix, not that of the new prefix area. The new prefix area
461  * is a valid lowcore, so that the test does not crash on failure.
462  */
test_set_prefix(void)463 static void test_set_prefix(void)
464 {
465 	uint32_t *prefix_ptr = (uint32_t *)pagebuf;
466 	uint32_t *no_override_prefix_ptr;
467 	uint32_t old_prefix;
468 	pgd_t *root;
469 
470 	report_prefix_push("SET PREFIX");
471 	root = (pgd_t *)(stctg(1) & PAGE_MASK);
472 	old_prefix = get_prefix();
473 	memcpy(lowcore_tmp, 0, sizeof(lowcore_tmp));
474 	assert(((uint64_t)&lowcore_tmp >> 31) == 0);
475 	*prefix_ptr = (uint32_t)(uint64_t)&lowcore_tmp;
476 
477 	report_prefix_push("zero key");
478 	set_prefix(old_prefix);
479 	set_storage_key(prefix_ptr, 0x20, 0);
480 	set_prefix(*prefix_ptr);
481 	report(get_prefix() == *prefix_ptr, "set prefix");
482 	report_prefix_pop();
483 
484 	report_prefix_push("matching key");
485 	set_prefix(old_prefix);
486 	set_storage_key(pagebuf, 0x10, 0);
487 	set_prefix_key_1(prefix_ptr);
488 	report(get_prefix() == *prefix_ptr, "set prefix");
489 	report_prefix_pop();
490 
491 	report_prefix_push("mismatching key");
492 
493 	report_prefix_push("no fetch protection");
494 	set_prefix(old_prefix);
495 	set_storage_key(pagebuf, 0x20, 0);
496 	set_prefix_key_1(prefix_ptr);
497 	report(get_prefix() == *prefix_ptr, "set prefix");
498 	report_prefix_pop();
499 
500 	report_prefix_push("fetch protection");
501 	set_prefix(old_prefix);
502 	set_storage_key(pagebuf, 0x28, 0);
503 	expect_pgm_int();
504 	set_prefix_key_1(prefix_ptr);
505 	check_key_prot_exc(ACC_FETCH, PROT_FETCH_STORE);
506 	report(get_prefix() == old_prefix, "did not set prefix");
507 	report_prefix_pop();
508 
509 	/*
510 	 * Page 0 will be remapped, making the lowcore inaccessible, which
511 	 * breaks the normal handler and breaks skipping the faulting
512 	 * instruction. Disable dynamic address translation for the
513 	 * interrupt handler to make things work.
514 	 */
515 	lowcore.pgm_new_psw.mask &= ~PSW_MASK_DAT;
516 
517 	report_prefix_push("remapped page, fetch protection");
518 	set_prefix(old_prefix);
519 	set_storage_key(pagebuf, 0x28, 0);
520 	expect_pgm_int();
521 	install_page(root, virt_to_pte_phys(root, pagebuf), 0);
522 	set_prefix_key_1((uint32_t *)0);
523 	install_page(root, 0, 0);
524 	check_key_prot_exc(ACC_FETCH, PROT_FETCH_STORE);
525 	report(get_prefix() == old_prefix, "did not set prefix");
526 	report_prefix_pop();
527 
528 	ctl_set_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE);
529 
530 	report_prefix_push("fetch protection override applies");
531 	set_prefix(old_prefix);
532 	set_storage_key(pagebuf, 0x28, 0);
533 	install_page(root, virt_to_pte_phys(root, pagebuf), 0);
534 	set_prefix_key_1((uint32_t *)0);
535 	install_page(root, 0, 0);
536 	report(get_prefix() == *prefix_ptr, "set prefix");
537 	report_prefix_pop();
538 
539 	no_override_prefix_ptr = (uint32_t *)(pagebuf + 2048);
540 	WRITE_ONCE(*no_override_prefix_ptr, (uint32_t)(uint64_t)&lowcore_tmp);
541 	report_prefix_push("fetch protection override does not apply");
542 	set_prefix(old_prefix);
543 	set_storage_key(pagebuf, 0x28, 0);
544 	expect_pgm_int();
545 	install_page(root, virt_to_pte_phys(root, pagebuf), 0);
546 	set_prefix_key_1(OPAQUE_PTR(2048));
547 	install_page(root, 0, 0);
548 	check_key_prot_exc(ACC_FETCH, PROT_FETCH_STORE);
549 	report(get_prefix() == old_prefix, "did not set prefix");
550 	report_prefix_pop();
551 
552 	ctl_clear_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE);
553 	lowcore.pgm_new_psw.mask |= PSW_MASK_DAT;
554 	report_prefix_pop();
555 	set_storage_key(pagebuf, 0x00, 0);
556 	report_prefix_pop();
557 }
558 
559 /*
560  * Perform MODIFY SUBCHANNEL (MSCH) instruction while temporarily executing
561  * with access key 1.
562  */
modify_subchannel_key_1(uint32_t sid,struct schib * schib)563 static uint32_t modify_subchannel_key_1(uint32_t sid, struct schib *schib)
564 {
565 	uint32_t program_mask;
566 
567 	asm volatile (
568 		"lr %%r1,%[sid]\n\t"
569 		"spka	0x10\n\t"
570 		"msch	%[schib]\n\t"
571 		"spka	0\n\t"
572 		"ipm	%[program_mask]\n"
573 		: [program_mask] "=d" (program_mask)
574 		: [sid] "d" (sid),
575 		  [schib] "Q" (*schib)
576 		: "%r1"
577 	);
578 	return program_mask >> 28;
579 }
580 
test_msch(void)581 static void test_msch(void)
582 {
583 	struct schib *schib = (struct schib *)pagebuf;
584 	struct schib *no_override_schib;
585 	int test_device_sid;
586 	pgd_t *root;
587 	int cc;
588 
589 	report_prefix_push("MSCH");
590 	root = (pgd_t *)(stctg(1) & PAGE_MASK);
591 	test_device_sid = css_enumerate();
592 
593 	if (!(test_device_sid & SCHID_ONE)) {
594 		report_fail("no I/O device found");
595 		return;
596 	}
597 
598 	cc = stsch(test_device_sid, schib);
599 	if (cc) {
600 		report_fail("could not store SCHIB");
601 		return;
602 	}
603 
604 	report_prefix_push("zero key");
605 	schib->pmcw.intparm = 100;
606 	set_storage_key(schib, 0x28, 0);
607 	cc = msch(test_device_sid, schib);
608 	if (!cc) {
609 		WRITE_ONCE(schib->pmcw.intparm, 0);
610 		cc = stsch(test_device_sid, schib);
611 		report(!cc && schib->pmcw.intparm == 100, "fetched from SCHIB");
612 	} else {
613 		report_fail("MSCH cc != 0");
614 	}
615 	report_prefix_pop();
616 
617 	report_prefix_push("matching key");
618 	schib->pmcw.intparm = 200;
619 	set_storage_key(schib, 0x18, 0);
620 	cc = modify_subchannel_key_1(test_device_sid, schib);
621 	if (!cc) {
622 		WRITE_ONCE(schib->pmcw.intparm, 0);
623 		cc = stsch(test_device_sid, schib);
624 		report(!cc && schib->pmcw.intparm == 200, "fetched from SCHIB");
625 	} else {
626 		report_fail("MSCH cc != 0");
627 	}
628 	report_prefix_pop();
629 
630 	report_prefix_push("mismatching key");
631 
632 	report_prefix_push("no fetch protection");
633 	schib->pmcw.intparm = 300;
634 	set_storage_key(schib, 0x20, 0);
635 	cc = modify_subchannel_key_1(test_device_sid, schib);
636 	if (!cc) {
637 		WRITE_ONCE(schib->pmcw.intparm, 0);
638 		cc = stsch(test_device_sid, schib);
639 		report(!cc && schib->pmcw.intparm == 300, "fetched from SCHIB");
640 	} else {
641 		report_fail("MSCH cc != 0");
642 	}
643 	report_prefix_pop();
644 
645 	schib->pmcw.intparm = 0;
646 	if (!msch(test_device_sid, schib)) {
647 		report_prefix_push("fetch protection");
648 		schib->pmcw.intparm = 400;
649 		set_storage_key(schib, 0x28, 0);
650 		expect_pgm_int();
651 		modify_subchannel_key_1(test_device_sid, schib);
652 		check_key_prot_exc(ACC_FETCH, PROT_FETCH_STORE);
653 		cc = stsch(test_device_sid, schib);
654 		report(!cc && schib->pmcw.intparm == 0, "did not modify subchannel");
655 		report_prefix_pop();
656 	} else {
657 		report_fail("could not reset SCHIB");
658 	}
659 
660 	/*
661 	 * Page 0 will be remapped, making the lowcore inaccessible, which
662 	 * breaks the normal handler and breaks skipping the faulting
663 	 * instruction. Disable dynamic address translation for the
664 	 * interrupt handler to make things work.
665 	 */
666 	lowcore.pgm_new_psw.mask &= ~PSW_MASK_DAT;
667 
668 	schib->pmcw.intparm = 0;
669 	if (!msch(test_device_sid, schib)) {
670 		report_prefix_push("remapped page, fetch protection");
671 		schib->pmcw.intparm = 500;
672 		set_storage_key(pagebuf, 0x28, 0);
673 		expect_pgm_int();
674 		install_page(root, virt_to_pte_phys(root, pagebuf), 0);
675 		modify_subchannel_key_1(test_device_sid, (struct schib *)0);
676 		install_page(root, 0, 0);
677 		check_key_prot_exc(ACC_FETCH, PROT_FETCH_STORE);
678 		cc = stsch(test_device_sid, schib);
679 		report(!cc && schib->pmcw.intparm == 0, "did not modify subchannel");
680 		report_prefix_pop();
681 	} else {
682 		report_fail("could not reset SCHIB");
683 	}
684 
685 	ctl_set_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE);
686 
687 	report_prefix_push("fetch-protection override applies");
688 	schib->pmcw.intparm = 600;
689 	set_storage_key(pagebuf, 0x28, 0);
690 	install_page(root, virt_to_pte_phys(root, pagebuf), 0);
691 	cc = modify_subchannel_key_1(test_device_sid, (struct schib *)0);
692 	install_page(root, 0, 0);
693 	if (!cc) {
694 		WRITE_ONCE(schib->pmcw.intparm, 0);
695 		cc = stsch(test_device_sid, schib);
696 		report(!cc && schib->pmcw.intparm == 600, "fetched from SCHIB");
697 	} else {
698 		report_fail("MSCH cc != 0");
699 	}
700 	report_prefix_pop();
701 
702 	schib->pmcw.intparm = 0;
703 	if (!msch(test_device_sid, schib)) {
704 		report_prefix_push("fetch-protection override does not apply");
705 		schib->pmcw.intparm = 700;
706 		no_override_schib = (struct schib *)(pagebuf + 2048);
707 		memcpy(no_override_schib, schib, sizeof(struct schib));
708 		set_storage_key(pagebuf, 0x28, 0);
709 		expect_pgm_int();
710 		install_page(root, virt_to_pte_phys(root, pagebuf), 0);
711 		modify_subchannel_key_1(test_device_sid, OPAQUE_PTR(2048));
712 		install_page(root, 0, 0);
713 		check_key_prot_exc(ACC_FETCH, PROT_FETCH_STORE);
714 		cc = stsch(test_device_sid, schib);
715 		report(!cc && schib->pmcw.intparm == 0, "did not modify subchannel");
716 		report_prefix_pop();
717 	} else {
718 		report_fail("could not reset SCHIB");
719 	}
720 
721 	ctl_clear_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE);
722 	lowcore.pgm_new_psw.mask |= PSW_MASK_DAT;
723 	report_prefix_pop();
724 	set_storage_key(schib, 0x00, 0);
725 	report_prefix_pop();
726 }
727 
main(void)728 int main(void)
729 {
730 	report_prefix_push("skey");
731 	if (test_facility(169)) {
732 		report_skip("storage key removal facility is active");
733 		goto done;
734 	}
735 	test_priv();
736 	test_invalid_address();
737 	test_set();
738 	test_set_mb();
739 	test_chg();
740 	test_test_protection();
741 	test_store_cpu_address();
742 	test_diag_308();
743 	test_channel_subsystem_call();
744 
745 	setup_vm();
746 	test_set_prefix();
747 	test_msch();
748 done:
749 	report_prefix_pop();
750 	return report_summary();
751 }
752