On fork, we inherit from the parent and on exec, we should switch to default_amr values.
Also, avoid changing the AMR register value within the kernel. The kernel now runs with different AMR values. Signed-off-by: Aneesh Kumar K.V <[email protected]> --- arch/powerpc/include/asm/book3s/64/kup.h | 2 ++ arch/powerpc/kernel/process.c | 19 ++++++++++++++++++- arch/powerpc/mm/book3s64/pkeys.c | 18 ++---------------- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/kup.h b/arch/powerpc/include/asm/book3s/64/kup.h index 67320a990f3f..fe1818954e51 100644 --- a/arch/powerpc/include/asm/book3s/64/kup.h +++ b/arch/powerpc/include/asm/book3s/64/kup.h @@ -171,6 +171,8 @@ #include <asm/ptrace.h> extern u64 default_uamor; +extern u64 default_amr; +extern u64 default_iamr; static inline void kuap_restore_user_amr(struct pt_regs *regs) { diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 9ef95a1217ef..0ab9a8cf1bcb 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1474,7 +1474,25 @@ void arch_setup_new_exec(void) current->thread.regs = regs - 1; } +#ifdef CONFIG_PPC_MEM_KEYS + current->thread.regs->kuap = default_amr; + current->thread.regs->kuep = default_iamr; +#endif + } +#else +void arch_setup_new_exec(void) +{ + /* + * If we exec out of a kernel thread then thread.regs will not be + * set. Do it now. + */ + if (!current->thread.regs) { + struct pt_regs *regs = task_stack_page(current) + THREAD_SIZE; + current->thread.regs = regs - 1; + } +} + #endif #ifdef CONFIG_PPC64 @@ -1809,7 +1827,6 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) current->thread.load_tm = 0; #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ - thread_pkey_regs_init(¤t->thread); } EXPORT_SYMBOL(start_thread); diff --git a/arch/powerpc/mm/book3s64/pkeys.c b/arch/powerpc/mm/book3s64/pkeys.c index 976f65f27324..5012b57af808 100644 --- a/arch/powerpc/mm/book3s64/pkeys.c +++ b/arch/powerpc/mm/book3s64/pkeys.c @@ -20,8 +20,8 @@ int max_pkey; /* Maximum key value supported */ */ u32 reserved_allocation_mask; static u32 initial_allocation_mask; /* Bits set for the initially allocated keys */ -static u64 default_amr; -static u64 default_iamr; +u64 default_amr; +u64 default_iamr; /* Allow all keys to be modified by default */ u64 default_uamor = ~0x0UL; /* @@ -387,20 +387,6 @@ void thread_pkey_regs_restore(struct thread_struct *new_thread, write_uamor(new_thread->uamor); } -void thread_pkey_regs_init(struct thread_struct *thread) -{ - if (!mmu_has_feature(MMU_FTR_PKEY)) - return; - - thread->amr = default_amr; - thread->iamr = default_iamr; - thread->uamor = default_uamor; - - write_amr(default_amr); - write_iamr(default_iamr); - write_uamor(default_uamor); -} - int execute_only_pkey(struct mm_struct *mm) { if (static_branch_likely(&execute_pkey_disabled)) -- 2.26.2
