pkeys.c (d5fa30e6993ffcdd1859d8dab1a07a6f6c6e7c3f) pkeys.c (48a8ab4eeb8271f2a0e2ca3cf80844a59acca153)
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * PowerPC Memory Protection Keys management
4 *
5 * Copyright 2017, Ram Pai, IBM Corporation.
6 */
7
8#include <asm/mman.h>

--- 267 unchanged lines hidden (view full) ---

276 /*
277 * Set the default kernel AMR values on all cpus.
278 */
279 mtspr(SPRN_AMR, AMR_KUAP_BLOCKED);
280 isync();
281}
282#endif
283
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * PowerPC Memory Protection Keys management
4 *
5 * Copyright 2017, Ram Pai, IBM Corporation.
6 */
7
8#include <asm/mman.h>

--- 267 unchanged lines hidden (view full) ---

276 /*
277 * Set the default kernel AMR values on all cpus.
278 */
279 mtspr(SPRN_AMR, AMR_KUAP_BLOCKED);
280 isync();
281}
282#endif
283
284static inline u64 read_amr(void)
284static inline void update_current_thread_amr(u64 value)
285{
285{
286 return mfspr(SPRN_AMR);
286 current->thread.regs->amr = value;
287}
288
287}
288
289static inline void write_amr(u64 value)
289static inline void update_current_thread_iamr(u64 value)
290{
290{
291 mtspr(SPRN_AMR, value);
292}
293
294static inline u64 read_iamr(void)
295{
296 if (!likely(pkey_execute_disable_supported))
291 if (!likely(pkey_execute_disable_supported))
297 return 0x0UL;
298
299 return mfspr(SPRN_IAMR);
300}
301
302static inline void write_iamr(u64 value)
303{
304 if (!likely(pkey_execute_disable_supported))
305 return;
306
292 return;
293
307 mtspr(SPRN_IAMR, value);
294 current->thread.regs->iamr = value;
308}
309
310#ifdef CONFIG_PPC_MEM_KEYS
311void pkey_mm_init(struct mm_struct *mm)
312{
313 if (!mmu_has_feature(MMU_FTR_PKEY))
314 return;
315 mm_pkey_allocation_map(mm) = initial_allocation_mask;
316 mm->context.execute_only_pkey = execute_only_key;
317}
318
319static inline void init_amr(int pkey, u8 init_bits)
320{
321 u64 new_amr_bits = (((u64)init_bits & 0x3UL) << pkeyshift(pkey));
295}
296
297#ifdef CONFIG_PPC_MEM_KEYS
298void pkey_mm_init(struct mm_struct *mm)
299{
300 if (!mmu_has_feature(MMU_FTR_PKEY))
301 return;
302 mm_pkey_allocation_map(mm) = initial_allocation_mask;
303 mm->context.execute_only_pkey = execute_only_key;
304}
305
306static inline void init_amr(int pkey, u8 init_bits)
307{
308 u64 new_amr_bits = (((u64)init_bits & 0x3UL) << pkeyshift(pkey));
322 u64 old_amr = read_amr() & ~((u64)(0x3ul) << pkeyshift(pkey));
309 u64 old_amr = current_thread_amr() & ~((u64)(0x3ul) << pkeyshift(pkey));
323
310
324 write_amr(old_amr | new_amr_bits);
311 update_current_thread_amr(old_amr | new_amr_bits);
325}
326
327static inline void init_iamr(int pkey, u8 init_bits)
328{
329 u64 new_iamr_bits = (((u64)init_bits & 0x1UL) << pkeyshift(pkey));
312}
313
314static inline void init_iamr(int pkey, u8 init_bits)
315{
316 u64 new_iamr_bits = (((u64)init_bits & 0x1UL) << pkeyshift(pkey));
330 u64 old_iamr = read_iamr() & ~((u64)(0x1ul) << pkeyshift(pkey));
317 u64 old_iamr = current_thread_iamr() & ~((u64)(0x1ul) << pkeyshift(pkey));
331
318
332 write_iamr(old_iamr | new_iamr_bits);
319 update_current_thread_iamr(old_iamr | new_iamr_bits);
333}
334
335/*
336 * Set the access rights in AMR IAMR and UAMOR registers for @pkey to that
337 * specified in @init_val.
338 */
339int __arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
340 unsigned long init_val)

--- 26 unchanged lines hidden (view full) ---

367 new_amr_bits |= AMR_RD_BIT | AMR_WR_BIT;
368 else if (init_val & PKEY_DISABLE_WRITE)
369 new_amr_bits |= AMR_WR_BIT;
370
371 init_amr(pkey, new_amr_bits);
372 return 0;
373}
374
320}
321
322/*
323 * Set the access rights in AMR IAMR and UAMOR registers for @pkey to that
324 * specified in @init_val.
325 */
326int __arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
327 unsigned long init_val)

--- 26 unchanged lines hidden (view full) ---

354 new_amr_bits |= AMR_RD_BIT | AMR_WR_BIT;
355 else if (init_val & PKEY_DISABLE_WRITE)
356 new_amr_bits |= AMR_WR_BIT;
357
358 init_amr(pkey, new_amr_bits);
359 return 0;
360}
361
375void thread_pkey_regs_save(struct thread_struct *thread)
376{
377 if (!mmu_has_feature(MMU_FTR_PKEY))
378 return;
379
380 /*
381 * TODO: Skip saving registers if @thread hasn't used any keys yet.
382 */
383 thread->amr = read_amr();
384 thread->iamr = read_iamr();
385}
386
387void thread_pkey_regs_restore(struct thread_struct *new_thread,
388 struct thread_struct *old_thread)
389{
390 if (!mmu_has_feature(MMU_FTR_PKEY))
391 return;
392
393 if (old_thread->amr != new_thread->amr)
394 write_amr(new_thread->amr);
395 if (old_thread->iamr != new_thread->iamr)
396 write_iamr(new_thread->iamr);
397}
398
399int execute_only_pkey(struct mm_struct *mm)
400{
401 return mm->context.execute_only_pkey;
402}
403
404static inline bool vma_is_pkey_exec_only(struct vm_area_struct *vma)
405{
406 /* Do this check first since the vm_flags should be hot */

--- 32 unchanged lines hidden (view full) ---

439
440static bool pkey_access_permitted(int pkey, bool write, bool execute)
441{
442 int pkey_shift;
443 u64 amr;
444
445 pkey_shift = pkeyshift(pkey);
446 if (execute)
362int execute_only_pkey(struct mm_struct *mm)
363{
364 return mm->context.execute_only_pkey;
365}
366
367static inline bool vma_is_pkey_exec_only(struct vm_area_struct *vma)
368{
369 /* Do this check first since the vm_flags should be hot */

--- 32 unchanged lines hidden (view full) ---

402
403static bool pkey_access_permitted(int pkey, bool write, bool execute)
404{
405 int pkey_shift;
406 u64 amr;
407
408 pkey_shift = pkeyshift(pkey);
409 if (execute)
447 return !(read_iamr() & (IAMR_EX_BIT << pkey_shift));
410 return !(current_thread_iamr() & (IAMR_EX_BIT << pkey_shift));
448
411
449 amr = read_amr();
412 amr = current_thread_amr();
450 if (write)
451 return !(amr & (AMR_WR_BIT << pkey_shift));
452
453 return !(amr & (AMR_RD_BIT << pkey_shift));
454}
455
456bool arch_pte_access_permitted(u64 pte, bool write, bool execute)
457{

--- 39 unchanged lines hidden ---
413 if (write)
414 return !(amr & (AMR_WR_BIT << pkey_shift));
415
416 return !(amr & (AMR_RD_BIT << pkey_shift));
417}
418
419bool arch_pte_access_permitted(u64 pte, bool write, bool execute)
420{

--- 39 unchanged lines hidden ---