Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/1cbf94e26e6d6e2e028fd687588a7e6622d454a6.1634627931.git.christophe.leroy@csgroup.eu

authored by

Christophe Leroy and committed by
Michael Ellerman
42e03bc5 047a6fd4

+14 -5
+9
arch/powerpc/include/asm/book3s/64/kup.h
··· 298 298 return amr; 299 299 } 300 300 301 + /* Do nothing, book3s/64 does that in ASM */ 302 + static inline void __kuap_lock(void) 303 + { 304 + } 305 + 306 + static inline void __kuap_save_and_lock(struct pt_regs *regs) 307 + { 308 + } 309 + 301 310 /* 302 311 * We support individually allowing read or write, but we don't support nesting 303 312 * because that would require an expensive read/modify write of the AMR.
+2
arch/powerpc/include/asm/interrupt.h
··· 154 154 local_paca->irq_happened |= PACA_IRQ_HARD_DIS; 155 155 156 156 if (user_mode(regs)) { 157 + kuap_lock(); 157 158 CT_WARN_ON(ct_state() != CONTEXT_USER); 158 159 user_exit_irqoff(); 159 160 160 161 account_cpu_user_entry(); 161 162 account_stolen_time(); 162 163 } else { 164 + kuap_save_and_lock(regs); 163 165 /* 164 166 * CT_WARN_ON comes here via program_check_exception, 165 167 * so avoid recursion.
-2
arch/powerpc/include/asm/kup.h
··· 91 91 __kuap_get_and_assert_locked(); 92 92 } 93 93 94 - #ifdef CONFIG_PPC32 95 94 static __always_inline void kuap_lock(void) 96 95 { 97 96 if (kuap_is_disabled()) ··· 106 107 107 108 __kuap_save_and_lock(regs); 108 109 } 109 - #endif 110 110 111 111 static __always_inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long amr) 112 112 {
+3 -3
arch/powerpc/kernel/process.c
··· 1315 1315 1316 1316 set_return_regs_changed(); /* _switch changes stack (and regs) */ 1317 1317 1318 - #ifdef CONFIG_PPC32 1319 - kuap_assert_locked(); 1320 - #endif 1318 + if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64)) 1319 + kuap_assert_locked(); 1320 + 1321 1321 last = _switch(old_thread, new_thread); 1322 1322 1323 1323 /*