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