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

source code of linux/arch/s390/kernel/skey.c