powerpc/64e/interrupt: reconcile irq soft-mask state in C
authorNicholas Piggin <npiggin@gmail.com>
Tue, 16 Mar 2021 10:42:00 +0000 (20:42 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 14 Apr 2021 13:04:43 +0000 (23:04 +1000)
Use existing 64s interrupt entry wrapper code to reconcile irqs in C.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210316104206.407354-7-npiggin@gmail.com
arch/powerpc/include/asm/interrupt.h
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/exceptions-64e.S

index b17a550..104a77c 100644 (file)
@@ -51,14 +51,14 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrup
                kuap_save_and_lock(regs);
        }
 #endif
-       /*
-        * Book3E reconciles irq soft mask in asm
-        */
-#ifdef CONFIG_PPC_BOOK3S_64
+
+#ifdef CONFIG_PPC64
        if (irq_soft_mask_set_return(IRQS_ALL_DISABLED) == IRQS_ENABLED)
                trace_hardirqs_off();
        local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
+#endif
 
+#ifdef CONFIG_PPC_BOOK3S_64
        if (user_mode(regs)) {
                CT_WARN_ON(ct_state() != CONTEXT_USER);
                user_exit_irqoff();
index 555b3d0..0372730 100644 (file)
@@ -117,13 +117,12 @@ BEGIN_FTR_SECTION
 END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
 
        /*
-        * RECONCILE_IRQ_STATE without calling trace_hardirqs_off(), which
-        * would clobber syscall parameters. Also we always enter with IRQs
-        * enabled and nothing pending. system_call_exception() will call
-        * trace_hardirqs_off().
-        *
-        * scv enters with MSR[EE]=1, so don't set PACA_IRQ_HARD_DIS. The
-        * entry vector already sets PACAIRQSOFTMASK to IRQS_ALL_DISABLED.
+        * scv enters with MSR[EE]=1 and is immediately considered soft-masked.
+        * The entry vector already sets PACAIRQSOFTMASK to IRQS_ALL_DISABLED,
+        * and interrupts may be masked and pending already.
+        * system_call_exception() will call trace_hardirqs_off() which means
+        * interrupts could already have been blocked before trace_hardirqs_off,
+        * but this is the best we can do.
         */
 
        /* Calling convention has r9 = orig r0, r10 = regs */
@@ -288,9 +287,8 @@ END_BTB_FLUSH_SECTION
        std     r11,-16(r10)            /* "regshere" marker */
 
        /*
-        * RECONCILE_IRQ_STATE without calling trace_hardirqs_off(), which
-        * would clobber syscall parameters. Also we always enter with IRQs
-        * enabled and nothing pending. system_call_exception() will call
+        * We always enter kernel from userspace with irq soft-mask enabled and
+        * nothing pending. system_call_exception() will call
         * trace_hardirqs_off().
         */
        li      r11,IRQS_ALL_DISABLED
index 18be576..3c222a9 100644 (file)
@@ -409,28 +409,6 @@ exc_##n##_common:                                                      \
 #define EXCEPTION_COMMON_DBG(n) \
        EXCEPTION_COMMON_LVL(n, SPRN_SPRG_DBG_SCRATCH, PACA_EXDBG)
 
-/*
- * This is meant for exceptions that don't immediately hard-enable.  We
- * set a bit in paca->irq_happened to ensure that a subsequent call to
- * arch_local_irq_restore() will properly hard-enable and avoid the
- * fast-path, and then reconcile irq state.
- */
-#define INTS_DISABLE   RECONCILE_IRQ_STATE(r3,r4)
-
-/*
- * This is called by exceptions that don't use INTS_DISABLE (that did not
- * touch irq indicators in the PACA).  This will restore MSR:EE to it's
- * previous value
- *
- * XXX In the long run, we may want to open-code it in order to separate the
- *     load from the wrtee, thus limiting the latency caused by the dependency
- *     but at this point, I'll favor code clarity until we have a near to final
- *     implementation
- */
-#define INTS_RESTORE_HARD                                                  \
-       ld      r11,_MSR(r1);                                               \
-       wrtee   r11;
-
 /* XXX FIXME: Restore r14/r15 when necessary */
 #define BAD_STACK_TRAMPOLINE(n)                                                    \
 exc_##n##_bad_stack:                                                       \
@@ -479,7 +457,6 @@ exc_##n##_bad_stack:                                                            \
        START_EXCEPTION(label);                                         \
        NORMAL_EXCEPTION_PROLOG(trapnum, intnum, PROLOG_ADDITION_MASKABLE)\
        EXCEPTION_COMMON(trapnum)                                       \
-       INTS_DISABLE;                                                   \
        ack(r8);                                                        \
        CHECK_NAPPING();                                                \
        addi    r3,r1,STACK_FRAME_OVERHEAD;                             \
@@ -559,7 +536,6 @@ __end_interrupts:
        mfspr   r14,SPRN_DEAR
        mfspr   r15,SPRN_ESR
        EXCEPTION_COMMON(0x300)
-       INTS_DISABLE
        b       storage_fault_common
 
 /* Instruction Storage Interrupt */
@@ -569,7 +545,6 @@ __end_interrupts:
        li      r15,0
        mr      r14,r10
        EXCEPTION_COMMON(0x400)
-       INTS_DISABLE
        b       storage_fault_common
 
 /* External Input Interrupt */
@@ -591,7 +566,6 @@ __end_interrupts:
                                PROLOG_ADDITION_1REG)
        mfspr   r14,SPRN_ESR
        EXCEPTION_COMMON(0x700)
-       INTS_DISABLE
        std     r14,_DSISR(r1)
        addi    r3,r1,STACK_FRAME_OVERHEAD
        ld      r14,PACA_EXGEN+EX_R14(r13)
@@ -610,8 +584,7 @@ __end_interrupts:
        beq-    1f
        bl      load_up_fpu
        b       fast_interrupt_return
-1:     INTS_DISABLE
-       addi    r3,r1,STACK_FRAME_OVERHEAD
+1:     addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      kernel_fp_unavailable_exception
        b       interrupt_return
 
@@ -631,7 +604,6 @@ BEGIN_FTR_SECTION
 1:
 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 #endif
-       INTS_DISABLE
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      altivec_unavailable_exception
        b       interrupt_return
@@ -642,7 +614,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
                                BOOKE_INTERRUPT_ALTIVEC_ASSIST,
                                PROLOG_ADDITION_NONE)
        EXCEPTION_COMMON(0x220)
-       INTS_DISABLE
        addi    r3,r1,STACK_FRAME_OVERHEAD
 #ifdef CONFIG_ALTIVEC
 BEGIN_FTR_SECTION
@@ -691,7 +662,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
        NORMAL_EXCEPTION_PROLOG(0xf20, BOOKE_INTERRUPT_AP_UNAVAIL,
                                PROLOG_ADDITION_NONE)
        EXCEPTION_COMMON(0xf20)
-       INTS_DISABLE
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      unknown_exception
        b       interrupt_return
@@ -827,7 +797,6 @@ kernel_dbg_exc:
         */
        mfspr   r14,SPRN_DBSR
        EXCEPTION_COMMON_DBG(0xd08)
-       INTS_DISABLE
        std     r14,_DSISR(r1)
        addi    r3,r1,STACK_FRAME_OVERHEAD
        ld      r14,PACA_EXDBG+EX_R14(r13)
@@ -840,7 +809,6 @@ kernel_dbg_exc:
        NORMAL_EXCEPTION_PROLOG(0x260, BOOKE_INTERRUPT_PERFORMANCE_MONITOR,
                                PROLOG_ADDITION_NONE)
        EXCEPTION_COMMON(0x260)
-       INTS_DISABLE
        CHECK_NAPPING()
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      performance_monitor_exception
@@ -870,7 +838,6 @@ kernel_dbg_exc:
                                PROLOG_ADDITION_NONE)
        EXCEPTION_COMMON(0x2c0)
        addi    r3,r1,STACK_FRAME_OVERHEAD
-       INTS_RESTORE_HARD
        bl      unknown_exception
        b       interrupt_return
 
@@ -891,7 +858,6 @@ kernel_dbg_exc:
                                PROLOG_ADDITION_NONE)
        EXCEPTION_COMMON(0x310)
        addi    r3,r1,STACK_FRAME_OVERHEAD
-       INTS_RESTORE_HARD
        bl      unknown_exception
        b       interrupt_return
 
@@ -901,7 +867,6 @@ kernel_dbg_exc:
                                PROLOG_ADDITION_NONE)
        EXCEPTION_COMMON(0x320)
        addi    r3,r1,STACK_FRAME_OVERHEAD
-       INTS_RESTORE_HARD
        bl      unknown_exception
        b       interrupt_return
 
@@ -911,7 +876,6 @@ kernel_dbg_exc:
                                PROLOG_ADDITION_NONE)
        EXCEPTION_COMMON(0x340)
        addi    r3,r1,STACK_FRAME_OVERHEAD
-       INTS_RESTORE_HARD
        bl      unknown_exception
        b       interrupt_return
 
@@ -991,7 +955,6 @@ alignment_more:
        addi    r3,r1,STACK_FRAME_OVERHEAD
        ld      r14,PACA_EXGEN+EX_R14(r13)
        ld      r15,PACA_EXGEN+EX_R15(r13)
-       INTS_RESTORE_HARD
        bl      alignment_exception
        REST_NVGPRS(r1)
        b       interrupt_return