powerpc/kuap: Prepare for supporting KUAP on BOOK3E/64
authorChristophe Leroy <christophe.leroy@csgroup.eu>
Tue, 19 Oct 2021 07:29:26 +0000 (09:29 +0200)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 9 Dec 2021 11:41:19 +0000 (22:41 +1100)
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
arch/powerpc/include/asm/book3s/64/kup.h
arch/powerpc/include/asm/interrupt.h
arch/powerpc/include/asm/kup.h
arch/powerpc/kernel/process.c

index 503828709d55d0a4504058276b5b98fc0f7bc4b6..69fcf63eec941048b4fb96f4bb6b47f9c2fe64b1 100644 (file)
@@ -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.
index 50d891e4c08c4e700a81a63b78a0320d97b10be2..6d414ddc8e24cdb998e44a1024d0a63862379172 100644 (file)
@@ -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.
index 34574a7455cee83c8790dd98de28c91254f603e5..656e6f1d6b6f1931d6f5a81b8c857c2c75ed4a93 100644 (file)
@@ -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)
 {
index a64cfbb85ca2f09997e733493993e901e5946780..afdcc2d3d470d1540308ac946a0861ec7d206394 100644 (file)
@@ -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);
 
        /*