1
2#ifndef _ASM_X86_PKEYS_H
3#define _ASM_X86_PKEYS_H
4
5
6
7
8
9
10#define arch_max_pkey() (cpu_feature_enabled(X86_FEATURE_OSPKE) ? 16 : 1)
11
12extern int arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
13 unsigned long init_val);
14
15static inline bool arch_pkeys_enabled(void)
16{
17 return cpu_feature_enabled(X86_FEATURE_OSPKE);
18}
19
20
21
22
23
24extern int __execute_only_pkey(struct mm_struct *mm);
25static inline int execute_only_pkey(struct mm_struct *mm)
26{
27 if (!cpu_feature_enabled(X86_FEATURE_OSPKE))
28 return ARCH_DEFAULT_PKEY;
29
30 return __execute_only_pkey(mm);
31}
32
33extern int __arch_override_mprotect_pkey(struct vm_area_struct *vma,
34 int prot, int pkey);
35static inline int arch_override_mprotect_pkey(struct vm_area_struct *vma,
36 int prot, int pkey)
37{
38 if (!cpu_feature_enabled(X86_FEATURE_OSPKE))
39 return 0;
40
41 return __arch_override_mprotect_pkey(vma, prot, pkey);
42}
43
44extern int __arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
45 unsigned long init_val);
46
47#define ARCH_VM_PKEY_FLAGS (VM_PKEY_BIT0 | VM_PKEY_BIT1 | VM_PKEY_BIT2 | VM_PKEY_BIT3)
48
49#define mm_pkey_allocation_map(mm) (mm->context.pkey_allocation_map)
50#define mm_set_pkey_allocated(mm, pkey) do { \
51 mm_pkey_allocation_map(mm) |= (1U << pkey); \
52} while (0)
53#define mm_set_pkey_free(mm, pkey) do { \
54 mm_pkey_allocation_map(mm) &= ~(1U << pkey); \
55} while (0)
56
57static inline
58bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey)
59{
60
61
62
63
64
65 if (pkey < 0)
66 return false;
67 if (pkey >= arch_max_pkey())
68 return false;
69
70
71
72
73
74 if (pkey == mm->context.execute_only_pkey)
75 return false;
76
77 return mm_pkey_allocation_map(mm) & (1U << pkey);
78}
79
80
81
82
83static inline
84int mm_pkey_alloc(struct mm_struct *mm)
85{
86
87
88
89
90
91
92 u16 all_pkeys_mask = ((1U << arch_max_pkey()) - 1);
93 int ret;
94
95
96
97
98
99
100 if (mm_pkey_allocation_map(mm) == all_pkeys_mask)
101 return -1;
102
103 ret = ffz(mm_pkey_allocation_map(mm));
104
105 mm_set_pkey_allocated(mm, ret);
106
107 return ret;
108}
109
110static inline
111int mm_pkey_free(struct mm_struct *mm, int pkey)
112{
113 if (!mm_pkey_is_allocated(mm, pkey))
114 return -EINVAL;
115
116 mm_set_pkey_free(mm, pkey);
117
118 return 0;
119}
120
121extern int arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
122 unsigned long init_val);
123extern int __arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
124 unsigned long init_val);
125
126static inline int vma_pkey(struct vm_area_struct *vma)
127{
128 unsigned long vma_pkey_mask = VM_PKEY_BIT0 | VM_PKEY_BIT1 |
129 VM_PKEY_BIT2 | VM_PKEY_BIT3;
130
131 return (vma->vm_flags & vma_pkey_mask) >> VM_PKEY_SHIFT;
132}
133
134#endif
135