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 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 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 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 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 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 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 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 */ 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 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 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" (5) 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 */ 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"; 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 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 */ 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 /* 455 * We remapped page 0, making the lowcore inaccessible, which breaks the normal 456 * handler and breaks skipping the faulting instruction. 457 * Just disable dynamic address translation to make things work. 458 */ 459 static void dat_fixup_pgm_int(void) 460 { 461 uint64_t psw_mask = extract_psw_mask(); 462 463 psw_mask &= ~PSW_MASK_DAT; 464 load_psw_mask(psw_mask); 465 } 466 467 #define PREFIX_AREA_SIZE (PAGE_SIZE * 2) 468 static char lowcore_tmp[PREFIX_AREA_SIZE] __attribute__((aligned(PREFIX_AREA_SIZE))); 469 470 /* 471 * Test accessibility of the operand to SET PREFIX given different configurations 472 * with regards to storage keys. That is, check the accessibility of the location 473 * holding the new prefix, not that of the new prefix area. The new prefix area 474 * is a valid lowcore, so that the test does not crash on failure. 475 */ 476 static void test_set_prefix(void) 477 { 478 uint32_t *prefix_ptr = (uint32_t *)pagebuf; 479 uint32_t *no_override_prefix_ptr; 480 uint32_t old_prefix; 481 pgd_t *root; 482 483 report_prefix_push("SET PREFIX"); 484 root = (pgd_t *)(stctg(1) & PAGE_MASK); 485 old_prefix = get_prefix(); 486 memcpy(lowcore_tmp, 0, sizeof(lowcore_tmp)); 487 assert(((uint64_t)&lowcore_tmp >> 31) == 0); 488 *prefix_ptr = (uint32_t)(uint64_t)&lowcore_tmp; 489 490 report_prefix_push("zero key"); 491 set_prefix(old_prefix); 492 set_storage_key(prefix_ptr, 0x20, 0); 493 set_prefix(*prefix_ptr); 494 report(get_prefix() == *prefix_ptr, "set prefix"); 495 report_prefix_pop(); 496 497 report_prefix_push("matching key"); 498 set_prefix(old_prefix); 499 set_storage_key(pagebuf, 0x10, 0); 500 set_prefix_key_1(prefix_ptr); 501 report(get_prefix() == *prefix_ptr, "set prefix"); 502 report_prefix_pop(); 503 504 report_prefix_push("mismatching key"); 505 506 report_prefix_push("no fetch protection"); 507 set_prefix(old_prefix); 508 set_storage_key(pagebuf, 0x20, 0); 509 set_prefix_key_1(prefix_ptr); 510 report(get_prefix() == *prefix_ptr, "set prefix"); 511 report_prefix_pop(); 512 513 report_prefix_push("fetch protection"); 514 set_prefix(old_prefix); 515 set_storage_key(pagebuf, 0x28, 0); 516 expect_pgm_int(); 517 set_prefix_key_1(prefix_ptr); 518 check_key_prot_exc(ACC_FETCH, PROT_FETCH_STORE); 519 report(get_prefix() == old_prefix, "did not set prefix"); 520 report_prefix_pop(); 521 522 register_pgm_cleanup_func(dat_fixup_pgm_int); 523 524 report_prefix_push("remapped page, fetch protection"); 525 set_prefix(old_prefix); 526 set_storage_key(pagebuf, 0x28, 0); 527 expect_pgm_int(); 528 install_page(root, virt_to_pte_phys(root, pagebuf), 0); 529 set_prefix_key_1((uint32_t *)0); 530 install_page(root, 0, 0); 531 check_key_prot_exc(ACC_FETCH, PROT_FETCH_STORE); 532 report(get_prefix() == old_prefix, "did not set prefix"); 533 report_prefix_pop(); 534 535 ctl_set_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE); 536 537 report_prefix_push("fetch protection override applies"); 538 set_prefix(old_prefix); 539 set_storage_key(pagebuf, 0x28, 0); 540 install_page(root, virt_to_pte_phys(root, pagebuf), 0); 541 set_prefix_key_1((uint32_t *)0); 542 install_page(root, 0, 0); 543 report(get_prefix() == *prefix_ptr, "set prefix"); 544 report_prefix_pop(); 545 546 no_override_prefix_ptr = (uint32_t *)(pagebuf + 2048); 547 WRITE_ONCE(*no_override_prefix_ptr, (uint32_t)(uint64_t)&lowcore_tmp); 548 report_prefix_push("fetch protection override does not apply"); 549 set_prefix(old_prefix); 550 set_storage_key(pagebuf, 0x28, 0); 551 expect_pgm_int(); 552 install_page(root, virt_to_pte_phys(root, pagebuf), 0); 553 set_prefix_key_1(OPAQUE_PTR(2048)); 554 install_page(root, 0, 0); 555 check_key_prot_exc(ACC_FETCH, PROT_FETCH_STORE); 556 report(get_prefix() == old_prefix, "did not set prefix"); 557 report_prefix_pop(); 558 559 ctl_clear_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE); 560 register_pgm_cleanup_func(NULL); 561 report_prefix_pop(); 562 set_storage_key(pagebuf, 0x00, 0); 563 report_prefix_pop(); 564 } 565 566 /* 567 * Perform MODIFY SUBCHANNEL (MSCH) instruction while temporarily executing 568 * with access key 1. 569 */ 570 static uint32_t modify_subchannel_key_1(uint32_t sid, struct schib *schib) 571 { 572 uint32_t program_mask; 573 574 asm volatile ( 575 "lr %%r1,%[sid]\n\t" 576 "spka 0x10\n\t" 577 "msch %[schib]\n\t" 578 "spka 0\n\t" 579 "ipm %[program_mask]\n" 580 : [program_mask] "=d" (program_mask) 581 : [sid] "d" (sid), 582 [schib] "Q" (*schib) 583 : "%r1" 584 ); 585 return program_mask >> 28; 586 } 587 588 static void test_msch(void) 589 { 590 struct schib *schib = (struct schib *)pagebuf; 591 struct schib *no_override_schib; 592 int test_device_sid; 593 pgd_t *root; 594 int cc; 595 596 report_prefix_push("MSCH"); 597 root = (pgd_t *)(stctg(1) & PAGE_MASK); 598 test_device_sid = css_enumerate(); 599 600 if (!(test_device_sid & SCHID_ONE)) { 601 report_fail("no I/O device found"); 602 return; 603 } 604 605 cc = stsch(test_device_sid, schib); 606 if (cc) { 607 report_fail("could not store SCHIB"); 608 return; 609 } 610 611 report_prefix_push("zero key"); 612 schib->pmcw.intparm = 100; 613 set_storage_key(schib, 0x28, 0); 614 cc = msch(test_device_sid, schib); 615 if (!cc) { 616 WRITE_ONCE(schib->pmcw.intparm, 0); 617 cc = stsch(test_device_sid, schib); 618 report(!cc && schib->pmcw.intparm == 100, "fetched from SCHIB"); 619 } else { 620 report_fail("MSCH cc != 0"); 621 } 622 report_prefix_pop(); 623 624 report_prefix_push("matching key"); 625 schib->pmcw.intparm = 200; 626 set_storage_key(schib, 0x18, 0); 627 cc = modify_subchannel_key_1(test_device_sid, schib); 628 if (!cc) { 629 WRITE_ONCE(schib->pmcw.intparm, 0); 630 cc = stsch(test_device_sid, schib); 631 report(!cc && schib->pmcw.intparm == 200, "fetched from SCHIB"); 632 } else { 633 report_fail("MSCH cc != 0"); 634 } 635 report_prefix_pop(); 636 637 report_prefix_push("mismatching key"); 638 639 report_prefix_push("no fetch protection"); 640 schib->pmcw.intparm = 300; 641 set_storage_key(schib, 0x20, 0); 642 cc = modify_subchannel_key_1(test_device_sid, schib); 643 if (!cc) { 644 WRITE_ONCE(schib->pmcw.intparm, 0); 645 cc = stsch(test_device_sid, schib); 646 report(!cc && schib->pmcw.intparm == 300, "fetched from SCHIB"); 647 } else { 648 report_fail("MSCH cc != 0"); 649 } 650 report_prefix_pop(); 651 652 schib->pmcw.intparm = 0; 653 if (!msch(test_device_sid, schib)) { 654 report_prefix_push("fetch protection"); 655 schib->pmcw.intparm = 400; 656 set_storage_key(schib, 0x28, 0); 657 expect_pgm_int(); 658 modify_subchannel_key_1(test_device_sid, schib); 659 check_key_prot_exc(ACC_FETCH, PROT_FETCH_STORE); 660 cc = stsch(test_device_sid, schib); 661 report(!cc && schib->pmcw.intparm == 0, "did not modify subchannel"); 662 report_prefix_pop(); 663 } else { 664 report_fail("could not reset SCHIB"); 665 } 666 667 register_pgm_cleanup_func(dat_fixup_pgm_int); 668 669 schib->pmcw.intparm = 0; 670 if (!msch(test_device_sid, schib)) { 671 report_prefix_push("remapped page, fetch protection"); 672 schib->pmcw.intparm = 500; 673 set_storage_key(pagebuf, 0x28, 0); 674 expect_pgm_int(); 675 install_page(root, virt_to_pte_phys(root, pagebuf), 0); 676 modify_subchannel_key_1(test_device_sid, (struct schib *)0); 677 install_page(root, 0, 0); 678 check_key_prot_exc(ACC_FETCH, PROT_FETCH_STORE); 679 cc = stsch(test_device_sid, schib); 680 report(!cc && schib->pmcw.intparm == 0, "did not modify subchannel"); 681 report_prefix_pop(); 682 } else { 683 report_fail("could not reset SCHIB"); 684 } 685 686 ctl_set_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE); 687 688 report_prefix_push("fetch-protection override applies"); 689 schib->pmcw.intparm = 600; 690 set_storage_key(pagebuf, 0x28, 0); 691 install_page(root, virt_to_pte_phys(root, pagebuf), 0); 692 cc = modify_subchannel_key_1(test_device_sid, (struct schib *)0); 693 install_page(root, 0, 0); 694 if (!cc) { 695 WRITE_ONCE(schib->pmcw.intparm, 0); 696 cc = stsch(test_device_sid, schib); 697 report(!cc && schib->pmcw.intparm == 600, "fetched from SCHIB"); 698 } else { 699 report_fail("MSCH cc != 0"); 700 } 701 report_prefix_pop(); 702 703 schib->pmcw.intparm = 0; 704 if (!msch(test_device_sid, schib)) { 705 report_prefix_push("fetch-protection override does not apply"); 706 schib->pmcw.intparm = 700; 707 no_override_schib = (struct schib *)(pagebuf + 2048); 708 memcpy(no_override_schib, schib, sizeof(struct schib)); 709 set_storage_key(pagebuf, 0x28, 0); 710 expect_pgm_int(); 711 install_page(root, virt_to_pte_phys(root, pagebuf), 0); 712 modify_subchannel_key_1(test_device_sid, OPAQUE_PTR(2048)); 713 install_page(root, 0, 0); 714 check_key_prot_exc(ACC_FETCH, PROT_FETCH_STORE); 715 cc = stsch(test_device_sid, schib); 716 report(!cc && schib->pmcw.intparm == 0, "did not modify subchannel"); 717 report_prefix_pop(); 718 } else { 719 report_fail("could not reset SCHIB"); 720 } 721 722 ctl_clear_bit(0, CTL0_FETCH_PROTECTION_OVERRIDE); 723 register_pgm_cleanup_func(NULL); 724 report_prefix_pop(); 725 set_storage_key(schib, 0x00, 0); 726 report_prefix_pop(); 727 } 728 729 int main(void) 730 { 731 report_prefix_push("skey"); 732 if (test_facility(169)) { 733 report_skip("storage key removal facility is active"); 734 goto done; 735 } 736 test_priv(); 737 test_invalid_address(); 738 test_set(); 739 test_set_mb(); 740 test_chg(); 741 test_test_protection(); 742 test_store_cpu_address(); 743 test_diag_308(); 744 test_channel_subsystem_call(); 745 746 setup_vm(); 747 test_set_prefix(); 748 test_msch(); 749 done: 750 report_prefix_pop(); 751 return report_summary(); 752 } 753