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 expect_pgm_int(); 72 enter_pstate(); 73 set_storage_key(page0, 0x30, 0); 74 check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION); 75 76 skey.val = get_storage_key(page0); 77 report("skey did not change on exception", skey.str.acc != 3); 78 79 expect_pgm_int(); 80 enter_pstate(); 81 get_storage_key(page0); 82 check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION); 83 } 84 85 int main(void) 86 { 87 report_prefix_push("skey"); 88 test_priv(); 89 test_set(); 90 test_set_mb(); 91 test_chg(); 92 report_prefix_pop(); 93 return report_summary(); 94 } 95