From: Christophe Leroy Date: Tue, 19 Oct 2021 07:29:26 +0000 (+0200) Subject: powerpc/kuap: Prepare for supporting KUAP on BOOK3E/64 X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=42e03bc5240b75007682d9941ef672d12828fc70;p=linux.git powerpc/kuap: Prepare for supporting KUAP on BOOK3E/64 Also call kuap_lock() and kuap_save_and_lock() from interrupt functions with CONFIG_PPC64. For book3s/64 we keep them empty as it is done in assembly. Also do the locked assert when switching task unless it is book3s/64. Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/1cbf94e26e6d6e2e028fd687588a7e6622d454a6.1634627931.git.christophe.leroy@csgroup.eu --- diff --git a/arch/powerpc/include/asm/book3s/64/kup.h b/arch/powerpc/include/asm/book3s/64/kup.h index 503828709d55d..69fcf63eec941 100644 --- a/arch/powerpc/include/asm/book3s/64/kup.h +++ b/arch/powerpc/include/asm/book3s/64/kup.h @@ -298,6 +298,15 @@ static inline unsigned long __kuap_get_and_assert_locked(void) return amr; } +/* Do nothing, book3s/64 does that in ASM */ +static inline void __kuap_lock(void) +{ +} + +static inline void __kuap_save_and_lock(struct pt_regs *regs) +{ +} + /* * We support individually allowing read or write, but we don't support nesting * because that would require an expensive read/modify write of the AMR. diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h index 50d891e4c08c4..6d414ddc8e24c 100644 --- a/arch/powerpc/include/asm/interrupt.h +++ b/arch/powerpc/include/asm/interrupt.h @@ -154,12 +154,14 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrup local_paca->irq_happened |= PACA_IRQ_HARD_DIS; if (user_mode(regs)) { + kuap_lock(); CT_WARN_ON(ct_state() != CONTEXT_USER); user_exit_irqoff(); account_cpu_user_entry(); account_stolen_time(); } else { + kuap_save_and_lock(regs); /* * CT_WARN_ON comes here via program_check_exception, * so avoid recursion. diff --git a/arch/powerpc/include/asm/kup.h b/arch/powerpc/include/asm/kup.h index 34574a7455cee..656e6f1d6b6f1 100644 --- a/arch/powerpc/include/asm/kup.h +++ b/arch/powerpc/include/asm/kup.h @@ -91,7 +91,6 @@ static __always_inline void kuap_assert_locked(void) __kuap_get_and_assert_locked(); } -#ifdef CONFIG_PPC32 static __always_inline void kuap_lock(void) { if (kuap_is_disabled()) @@ -107,7 +106,6 @@ static __always_inline void kuap_save_and_lock(struct pt_regs *regs) __kuap_save_and_lock(regs); } -#endif static __always_inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long amr) { diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index a64cfbb85ca2f..afdcc2d3d470d 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1315,9 +1315,9 @@ struct task_struct *__switch_to(struct task_struct *prev, set_return_regs_changed(); /* _switch changes stack (and regs) */ -#ifdef CONFIG_PPC32 - kuap_assert_locked(); -#endif + if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64)) + kuap_assert_locked(); + last = _switch(old_thread, new_thread); /*