1*ee417a84SHeiko Carstens // SPDX-License-Identifier: GPL-2.0 2*ee417a84SHeiko Carstens 3*ee417a84SHeiko Carstens #include <asm/rwonce.h> 4*ee417a84SHeiko Carstens #include <asm/page.h> 5*ee417a84SHeiko Carstens #include <asm/skey.h> 6*ee417a84SHeiko Carstens 7*ee417a84SHeiko Carstens int skey_regions_initialized; 8*ee417a84SHeiko Carstens load_real_address(unsigned long address)9*ee417a84SHeiko Carstensstatic inline unsigned long load_real_address(unsigned long address) 10*ee417a84SHeiko Carstens { 11*ee417a84SHeiko Carstens unsigned long real; 12*ee417a84SHeiko Carstens 13*ee417a84SHeiko Carstens asm volatile( 14*ee417a84SHeiko Carstens " lra %[real],0(%[address])\n" 15*ee417a84SHeiko Carstens : [real] "=d" (real) 16*ee417a84SHeiko Carstens : [address] "a" (address) 17*ee417a84SHeiko Carstens : "cc"); 18*ee417a84SHeiko Carstens return real; 19*ee417a84SHeiko Carstens } 20*ee417a84SHeiko Carstens 21*ee417a84SHeiko Carstens /* 22*ee417a84SHeiko Carstens * Initialize storage keys of registered memory regions with the 23*ee417a84SHeiko Carstens * default key. This is useful for code which is executed with a 24*ee417a84SHeiko Carstens * non-default access key. 25*ee417a84SHeiko Carstens */ __skey_regions_initialize(void)26*ee417a84SHeiko Carstensvoid __skey_regions_initialize(void) 27*ee417a84SHeiko Carstens { 28*ee417a84SHeiko Carstens unsigned long address, real; 29*ee417a84SHeiko Carstens struct skey_region *r, *end; 30*ee417a84SHeiko Carstens 31*ee417a84SHeiko Carstens r = __skey_region_start; 32*ee417a84SHeiko Carstens end = __skey_region_end; 33*ee417a84SHeiko Carstens while (r < end) { 34*ee417a84SHeiko Carstens address = r->start & PAGE_MASK; 35*ee417a84SHeiko Carstens do { 36*ee417a84SHeiko Carstens real = load_real_address(address); 37*ee417a84SHeiko Carstens page_set_storage_key(real, PAGE_DEFAULT_KEY, 1); 38*ee417a84SHeiko Carstens address += PAGE_SIZE; 39*ee417a84SHeiko Carstens } while (address < r->end); 40*ee417a84SHeiko Carstens r++; 41*ee417a84SHeiko Carstens } 42*ee417a84SHeiko Carstens /* 43*ee417a84SHeiko Carstens * Make sure storage keys are initialized before 44*ee417a84SHeiko Carstens * skey_regions_initialized is changed. 45*ee417a84SHeiko Carstens */ 46*ee417a84SHeiko Carstens barrier(); 47*ee417a84SHeiko Carstens WRITE_ONCE(skey_regions_initialized, 1); 48*ee417a84SHeiko Carstens } 49