Saving and restoring soft-mask state can now be done in C using the
interrupt handler wrapper functions.

Signed-off-by: Nicholas Piggin <npig...@gmail.com>
---
 arch/powerpc/include/asm/interrupt.h | 25 ++++++++++++
 arch/powerpc/kernel/exceptions-64s.S | 60 ----------------------------
 2 files changed, 25 insertions(+), 60 deletions(-)

diff --git a/arch/powerpc/include/asm/interrupt.h 
b/arch/powerpc/include/asm/interrupt.h
index 69eb8a432984..c26a7c466416 100644
--- a/arch/powerpc/include/asm/interrupt.h
+++ b/arch/powerpc/include/asm/interrupt.h
@@ -33,12 +33,30 @@ static inline void interrupt_enter_prepare(struct pt_regs 
*regs)
 
 struct interrupt_nmi_state {
 #ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC_BOOK3S_64
+       u8 irq_soft_mask;
+       u8 irq_happened;
+#endif
        u8 ftrace_enabled;
 #endif
 };
 
 static inline void interrupt_nmi_enter_prepare(struct pt_regs *regs, struct 
interrupt_nmi_state *state)
 {
+#ifdef CONFIG_PPC_BOOK3S_64
+       state->irq_soft_mask = local_paca->irq_soft_mask;
+       state->irq_happened = local_paca->irq_happened;
+       state->ftrace_enabled = this_cpu_get_ftrace_enabled();
+
+       /*
+        * Set IRQS_ALL_DISABLED unconditionally so irqs_disabled() does
+        * the right thing, and set IRQ_HARD_DIS. We do not want to reconcile
+        * because that goes through irq tracing which we don't want in NMI.
+        */
+       local_paca->irq_soft_mask = IRQS_ALL_DISABLED;
+       local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
+#endif
+
        this_cpu_set_ftrace_enabled(0);
 
        nmi_enter();
@@ -49,6 +67,13 @@ static inline void interrupt_nmi_exit_prepare(struct pt_regs 
*regs, struct inter
        nmi_exit();
 
        this_cpu_set_ftrace_enabled(state->ftrace_enabled);
+
+#ifdef CONFIG_PPC_BOOK3S_64
+       /* Check we didn't change the pending interrupt mask. */
+       WARN_ON_ONCE((state->irq_happened | PACA_IRQ_HARD_DIS) != 
local_paca->irq_happened);
+       local_paca->irq_happened = state->irq_happened;
+       local_paca->irq_soft_mask = state->irq_soft_mask;
+#endif
 }
 
 
diff --git a/arch/powerpc/kernel/exceptions-64s.S 
b/arch/powerpc/kernel/exceptions-64s.S
index 121a55c87c02..0949dd47be59 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1010,20 +1010,6 @@ EXC_COMMON_BEGIN(system_reset_common)
        ld      r1,PACA_NMI_EMERG_SP(r13)
        subi    r1,r1,INT_FRAME_SIZE
        __GEN_COMMON_BODY system_reset
-       /*
-        * Set IRQS_ALL_DISABLED unconditionally so irqs_disabled() does
-        * the right thing. We do not want to reconcile because that goes
-        * through irq tracing which we don't want in NMI.
-        *
-        * Save PACAIRQHAPPENED to RESULT (otherwise unused), and set HARD_DIS
-        * as we are running with MSR[EE]=0.
-        */
-       li      r10,IRQS_ALL_DISABLED
-       stb     r10,PACAIRQSOFTMASK(r13)
-       lbz     r10,PACAIRQHAPPENED(r13)
-       std     r10,RESULT(r1)
-       ori     r10,r10,PACA_IRQ_HARD_DIS
-       stb     r10,PACAIRQHAPPENED(r13)
 
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      system_reset_exception
@@ -1039,14 +1025,6 @@ EXC_COMMON_BEGIN(system_reset_common)
        subi    r10,r10,1
        sth     r10,PACA_IN_NMI(r13)
 
-       /*
-        * Restore soft mask settings.
-        */
-       ld      r10,RESULT(r1)
-       stb     r10,PACAIRQHAPPENED(r13)
-       ld      r10,SOFTE(r1)
-       stb     r10,PACAIRQSOFTMASK(r13)
-
        kuap_restore_amr r9, r10
        EXCEPTION_RESTORE_REGS
        RFI_TO_USER_OR_KERNEL
@@ -1192,30 +1170,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
        li      r10,MSR_RI
        mtmsrd  r10,1
 
-       /*
-        * Set IRQS_ALL_DISABLED and save PACAIRQHAPPENED (see
-        * system_reset_common)
-        */
-       li      r10,IRQS_ALL_DISABLED
-       stb     r10,PACAIRQSOFTMASK(r13)
-       lbz     r10,PACAIRQHAPPENED(r13)
-       std     r10,RESULT(r1)
-       ori     r10,r10,PACA_IRQ_HARD_DIS
-       stb     r10,PACAIRQHAPPENED(r13)
-
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      machine_check_early
        std     r3,RESULT(r1)   /* Save result */
        ld      r12,_MSR(r1)
 
-       /*
-        * Restore soft mask settings.
-        */
-       ld      r10,RESULT(r1)
-       stb     r10,PACAIRQHAPPENED(r13)
-       ld      r10,SOFTE(r1)
-       stb     r10,PACAIRQSOFTMASK(r13)
-
 #ifdef CONFIG_PPC_P7_NAP
        /*
         * Check if thread was in power saving mode. We come here when any
@@ -2814,17 +2773,6 @@ EXC_COMMON_BEGIN(soft_nmi_common)
        subi    r1,r1,INT_FRAME_SIZE
        __GEN_COMMON_BODY soft_nmi
 
-       /*
-        * Set IRQS_ALL_DISABLED and save PACAIRQHAPPENED (see
-        * system_reset_common)
-        */
-       li      r10,IRQS_ALL_DISABLED
-       stb     r10,PACAIRQSOFTMASK(r13)
-       lbz     r10,PACAIRQHAPPENED(r13)
-       std     r10,RESULT(r1)
-       ori     r10,r10,PACA_IRQ_HARD_DIS
-       stb     r10,PACAIRQHAPPENED(r13)
-
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      soft_nmi_interrupt
 
@@ -2832,14 +2780,6 @@ EXC_COMMON_BEGIN(soft_nmi_common)
        li      r9,0
        mtmsrd  r9,1
 
-       /*
-        * Restore soft mask settings.
-        */
-       ld      r10,RESULT(r1)
-       stb     r10,PACAIRQHAPPENED(r13)
-       ld      r10,SOFTE(r1)
-       stb     r10,PACAIRQSOFTMASK(r13)
-
        kuap_restore_amr r9, r10
        EXCEPTION_RESTORE_REGS hsrr=0
        RFI_TO_KERNEL
-- 
2.23.0

Reply via email to