x86/pkeys: Move read_pkru() and write_pkru()
[linux-2.6-microblaze.git] / arch / x86 / include / asm / pkru.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_X86_PKRU_H
3 #define _ASM_X86_PKRU_H
4
5 #include <asm/fpu/xstate.h>
6
7 #define PKRU_AD_BIT 0x1
8 #define PKRU_WD_BIT 0x2
9 #define PKRU_BITS_PER_PKEY 2
10
11 #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
12 extern u32 init_pkru_value;
13 #else
14 #define init_pkru_value 0
15 #endif
16
17 static inline bool __pkru_allows_read(u32 pkru, u16 pkey)
18 {
19         int pkru_pkey_bits = pkey * PKRU_BITS_PER_PKEY;
20         return !(pkru & (PKRU_AD_BIT << pkru_pkey_bits));
21 }
22
23 static inline bool __pkru_allows_write(u32 pkru, u16 pkey)
24 {
25         int pkru_pkey_bits = pkey * PKRU_BITS_PER_PKEY;
26         /*
27          * Access-disable disables writes too so we need to check
28          * both bits here.
29          */
30         return !(pkru & ((PKRU_AD_BIT|PKRU_WD_BIT) << pkru_pkey_bits));
31 }
32
33 static inline u32 read_pkru(void)
34 {
35         if (boot_cpu_has(X86_FEATURE_OSPKE))
36                 return rdpkru();
37         return 0;
38 }
39
40 static inline void write_pkru(u32 pkru)
41 {
42         struct pkru_state *pk;
43
44         if (!boot_cpu_has(X86_FEATURE_OSPKE))
45                 return;
46
47         pk = get_xsave_addr(&current->thread.fpu.state.xsave, XFEATURE_PKRU);
48
49         /*
50          * The PKRU value in xstate needs to be in sync with the value that is
51          * written to the CPU. The FPU restore on return to userland would
52          * otherwise load the previous value again.
53          */
54         fpregs_lock();
55         if (pk)
56                 pk->pkru = pkru;
57         __write_pkru(pkru);
58         fpregs_unlock();
59 }
60
61 #endif