1 /* 2 * Storage key tests 3 * 4 * Copyright (c) 2018 IBM Corp 5 * 6 * Authors: 7 * Janosch Frank <frankja@linux.vnet.ibm.com> 8 * 9 * This code is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU Library 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 20 static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2))); 21 const unsigned long page0 = (unsigned long)pagebuf; 22 const unsigned long page1 = (unsigned long)(pagebuf + PAGE_SIZE); 23 24 static void test_set_mb(void) 25 { 26 union skey skey, ret1, ret2; 27 unsigned long addr = 0x10000 - 2 * PAGE_SIZE; 28 unsigned long end = 0x10000; 29 30 /* Multi block support came with EDAT 1 */ 31 if (!test_facility(8)) 32 return; 33 34 skey.val = 0x30; 35 while (addr < end) 36 addr = set_storage_key_mb(addr, skey.val); 37 38 ret1.val = get_storage_key(end - PAGE_SIZE); 39 ret2.val = get_storage_key(end - PAGE_SIZE * 2); 40 report("multi block", ret1.val == ret2.val && ret1.val == skey.val); 41 } 42 43 static void test_chg(void) 44 { 45 union skey skey1, skey2; 46 47 skey1.val = 0x30; 48 set_storage_key(page0, skey1.val, 0); 49 skey1.val = get_storage_key(page0); 50 pagebuf[0] = 3; 51 skey2.val = get_storage_key(page0); 52 report("chg bit test", !skey1.str.ch && skey2.str.ch); 53 } 54 55 static void test_set(void) 56 { 57 union skey skey, ret; 58 59 skey.val = 0x30; 60 ret.val = get_storage_key(page0); 61 set_storage_key(page0, skey.val, 0); 62 ret.val = get_storage_key(page0); 63 report("set key test", skey.val == ret.val); 64 } 65 66 static void test_priv(void) 67 { 68 union skey skey; 69 70 memset(pagebuf, 0, PAGE_SIZE * 2); 71 report_prefix_push("privileged"); 72 report_prefix_push("sske"); 73 expect_pgm_int(); 74 enter_pstate(); 75 set_storage_key(page0, 0x30, 0); 76 check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION); 77 report_prefix_pop(); 78 79 skey.val = get_storage_key(page0); 80 report("skey did not change on exception", skey.str.acc != 3); 81 82 report_prefix_push("iske"); 83 expect_pgm_int(); 84 enter_pstate(); 85 get_storage_key(page0); 86 check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION); 87 report_prefix_pop(); 88 89 report_prefix_pop(); 90 } 91 92 int main(void) 93 { 94 report_prefix_push("skey"); 95 test_priv(); 96 test_set(); 97 test_set_mb(); 98 test_chg(); 99 report_prefix_pop(); 100 return report_summary(); 101 } 102