|
15 | 15 | #include <linux/sched/hotplug.h> |
16 | 16 | #include <linux/mm_types.h> |
17 | 17 | #include <linux/pgtable.h> |
| 18 | +#include <linux/pkeys.h> |
18 | 19 |
|
19 | 20 | #include <asm/cacheflush.h> |
20 | 21 | #include <asm/cpufeature.h> |
21 | 22 | #include <asm/daifflags.h> |
22 | 23 | #include <asm/proc-fns.h> |
23 | | -#include <asm-generic/mm_hooks.h> |
24 | 24 | #include <asm/cputype.h> |
25 | 25 | #include <asm/sysreg.h> |
26 | 26 | #include <asm/tlbflush.h> |
@@ -175,9 +175,36 @@ init_new_context(struct task_struct *tsk, struct mm_struct *mm) |
175 | 175 | { |
176 | 176 | atomic64_set(&mm->context.id, 0); |
177 | 177 | refcount_set(&mm->context.pinned, 0); |
| 178 | + |
| 179 | + /* pkey 0 is the default, so always reserve it. */ |
| 180 | + mm->context.pkey_allocation_map = BIT(0); |
| 181 | + |
| 182 | + return 0; |
| 183 | +} |
| 184 | + |
| 185 | +static inline void arch_dup_pkeys(struct mm_struct *oldmm, |
| 186 | + struct mm_struct *mm) |
| 187 | +{ |
| 188 | + /* Duplicate the oldmm pkey state in mm: */ |
| 189 | + mm->context.pkey_allocation_map = oldmm->context.pkey_allocation_map; |
| 190 | +} |
| 191 | + |
| 192 | +static inline int arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm) |
| 193 | +{ |
| 194 | + arch_dup_pkeys(oldmm, mm); |
| 195 | + |
178 | 196 | return 0; |
179 | 197 | } |
180 | 198 |
|
| 199 | +static inline void arch_exit_mmap(struct mm_struct *mm) |
| 200 | +{ |
| 201 | +} |
| 202 | + |
| 203 | +static inline void arch_unmap(struct mm_struct *mm, |
| 204 | + unsigned long start, unsigned long end) |
| 205 | +{ |
| 206 | +} |
| 207 | + |
181 | 208 | #ifdef CONFIG_ARM64_SW_TTBR0_PAN |
182 | 209 | static inline void update_saved_ttbr0(struct task_struct *tsk, |
183 | 210 | struct mm_struct *mm) |
@@ -267,6 +294,23 @@ static inline unsigned long mm_untag_mask(struct mm_struct *mm) |
267 | 294 | return -1UL >> 8; |
268 | 295 | } |
269 | 296 |
|
| 297 | +/* |
| 298 | + * Only enforce protection keys on the current process, because there is no |
| 299 | + * user context to access POR_EL0 for another address space. |
| 300 | + */ |
| 301 | +static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, |
| 302 | + bool write, bool execute, bool foreign) |
| 303 | +{ |
| 304 | + if (!system_supports_poe()) |
| 305 | + return true; |
| 306 | + |
| 307 | + /* allow access if the VMA is not one from this process */ |
| 308 | + if (foreign || vma_is_foreign(vma)) |
| 309 | + return true; |
| 310 | + |
| 311 | + return por_el0_allows_pkey(vma_pkey(vma), write, execute); |
| 312 | +} |
| 313 | + |
270 | 314 | #include <asm-generic/mmu_context.h> |
271 | 315 |
|
272 | 316 | #endif /* !__ASSEMBLY__ */ |
|
0 commit comments