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