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