mirror of https://gitee.com/openkylin/linux.git
powerpc/64e/interrupt: reconcile irq soft-mask state in C
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
This commit is contained in:
parent
3db8aa10de
commit
097157e16c
|
@ -51,14 +51,14 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrup
|
||||||
kuap_save_and_lock(regs);
|
kuap_save_and_lock(regs);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/*
|
|
||||||
* Book3E reconciles irq soft mask in asm
|
#ifdef CONFIG_PPC64
|
||||||
*/
|
|
||||||
#ifdef CONFIG_PPC_BOOK3S_64
|
|
||||||
if (irq_soft_mask_set_return(IRQS_ALL_DISABLED) == IRQS_ENABLED)
|
if (irq_soft_mask_set_return(IRQS_ALL_DISABLED) == IRQS_ENABLED)
|
||||||
trace_hardirqs_off();
|
trace_hardirqs_off();
|
||||||
local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
|
local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PPC_BOOK3S_64
|
||||||
if (user_mode(regs)) {
|
if (user_mode(regs)) {
|
||||||
CT_WARN_ON(ct_state() != CONTEXT_USER);
|
CT_WARN_ON(ct_state() != CONTEXT_USER);
|
||||||
user_exit_irqoff();
|
user_exit_irqoff();
|
||||||
|
|
|
@ -117,13 +117,12 @@ BEGIN_FTR_SECTION
|
||||||
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
|
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RECONCILE_IRQ_STATE without calling trace_hardirqs_off(), which
|
* scv enters with MSR[EE]=1 and is immediately considered soft-masked.
|
||||||
* would clobber syscall parameters. Also we always enter with IRQs
|
* The entry vector already sets PACAIRQSOFTMASK to IRQS_ALL_DISABLED,
|
||||||
* enabled and nothing pending. system_call_exception() will call
|
* and interrupts may be masked and pending already.
|
||||||
* trace_hardirqs_off().
|
* system_call_exception() will call trace_hardirqs_off() which means
|
||||||
*
|
* interrupts could already have been blocked before trace_hardirqs_off,
|
||||||
* scv enters with MSR[EE]=1, so don't set PACA_IRQ_HARD_DIS. The
|
* but this is the best we can do.
|
||||||
* entry vector already sets PACAIRQSOFTMASK to IRQS_ALL_DISABLED.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Calling convention has r9 = orig r0, r10 = regs */
|
/* Calling convention has r9 = orig r0, r10 = regs */
|
||||||
|
@ -288,9 +287,8 @@ END_BTB_FLUSH_SECTION
|
||||||
std r11,-16(r10) /* "regshere" marker */
|
std r11,-16(r10) /* "regshere" marker */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RECONCILE_IRQ_STATE without calling trace_hardirqs_off(), which
|
* We always enter kernel from userspace with irq soft-mask enabled and
|
||||||
* would clobber syscall parameters. Also we always enter with IRQs
|
* nothing pending. system_call_exception() will call
|
||||||
* enabled and nothing pending. system_call_exception() will call
|
|
||||||
* trace_hardirqs_off().
|
* trace_hardirqs_off().
|
||||||
*/
|
*/
|
||||||
li r11,IRQS_ALL_DISABLED
|
li r11,IRQS_ALL_DISABLED
|
||||||
|
|
|
@ -409,28 +409,6 @@ exc_##n##_common: \
|
||||||
#define EXCEPTION_COMMON_DBG(n) \
|
#define EXCEPTION_COMMON_DBG(n) \
|
||||||
EXCEPTION_COMMON_LVL(n, SPRN_SPRG_DBG_SCRATCH, PACA_EXDBG)
|
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 */
|
/* XXX FIXME: Restore r14/r15 when necessary */
|
||||||
#define BAD_STACK_TRAMPOLINE(n) \
|
#define BAD_STACK_TRAMPOLINE(n) \
|
||||||
exc_##n##_bad_stack: \
|
exc_##n##_bad_stack: \
|
||||||
|
@ -479,7 +457,6 @@ exc_##n##_bad_stack: \
|
||||||
START_EXCEPTION(label); \
|
START_EXCEPTION(label); \
|
||||||
NORMAL_EXCEPTION_PROLOG(trapnum, intnum, PROLOG_ADDITION_MASKABLE)\
|
NORMAL_EXCEPTION_PROLOG(trapnum, intnum, PROLOG_ADDITION_MASKABLE)\
|
||||||
EXCEPTION_COMMON(trapnum) \
|
EXCEPTION_COMMON(trapnum) \
|
||||||
INTS_DISABLE; \
|
|
||||||
ack(r8); \
|
ack(r8); \
|
||||||
CHECK_NAPPING(); \
|
CHECK_NAPPING(); \
|
||||||
addi r3,r1,STACK_FRAME_OVERHEAD; \
|
addi r3,r1,STACK_FRAME_OVERHEAD; \
|
||||||
|
@ -559,7 +536,6 @@ __end_interrupts:
|
||||||
mfspr r14,SPRN_DEAR
|
mfspr r14,SPRN_DEAR
|
||||||
mfspr r15,SPRN_ESR
|
mfspr r15,SPRN_ESR
|
||||||
EXCEPTION_COMMON(0x300)
|
EXCEPTION_COMMON(0x300)
|
||||||
INTS_DISABLE
|
|
||||||
b storage_fault_common
|
b storage_fault_common
|
||||||
|
|
||||||
/* Instruction Storage Interrupt */
|
/* Instruction Storage Interrupt */
|
||||||
|
@ -569,7 +545,6 @@ __end_interrupts:
|
||||||
li r15,0
|
li r15,0
|
||||||
mr r14,r10
|
mr r14,r10
|
||||||
EXCEPTION_COMMON(0x400)
|
EXCEPTION_COMMON(0x400)
|
||||||
INTS_DISABLE
|
|
||||||
b storage_fault_common
|
b storage_fault_common
|
||||||
|
|
||||||
/* External Input Interrupt */
|
/* External Input Interrupt */
|
||||||
|
@ -591,7 +566,6 @@ __end_interrupts:
|
||||||
PROLOG_ADDITION_1REG)
|
PROLOG_ADDITION_1REG)
|
||||||
mfspr r14,SPRN_ESR
|
mfspr r14,SPRN_ESR
|
||||||
EXCEPTION_COMMON(0x700)
|
EXCEPTION_COMMON(0x700)
|
||||||
INTS_DISABLE
|
|
||||||
std r14,_DSISR(r1)
|
std r14,_DSISR(r1)
|
||||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||||
ld r14,PACA_EXGEN+EX_R14(r13)
|
ld r14,PACA_EXGEN+EX_R14(r13)
|
||||||
|
@ -610,8 +584,7 @@ __end_interrupts:
|
||||||
beq- 1f
|
beq- 1f
|
||||||
bl load_up_fpu
|
bl load_up_fpu
|
||||||
b fast_interrupt_return
|
b fast_interrupt_return
|
||||||
1: INTS_DISABLE
|
1: addi r3,r1,STACK_FRAME_OVERHEAD
|
||||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
|
||||||
bl kernel_fp_unavailable_exception
|
bl kernel_fp_unavailable_exception
|
||||||
b interrupt_return
|
b interrupt_return
|
||||||
|
|
||||||
|
@ -631,7 +604,6 @@ BEGIN_FTR_SECTION
|
||||||
1:
|
1:
|
||||||
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
|
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
|
||||||
#endif
|
#endif
|
||||||
INTS_DISABLE
|
|
||||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||||
bl altivec_unavailable_exception
|
bl altivec_unavailable_exception
|
||||||
b interrupt_return
|
b interrupt_return
|
||||||
|
@ -642,7 +614,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
|
||||||
BOOKE_INTERRUPT_ALTIVEC_ASSIST,
|
BOOKE_INTERRUPT_ALTIVEC_ASSIST,
|
||||||
PROLOG_ADDITION_NONE)
|
PROLOG_ADDITION_NONE)
|
||||||
EXCEPTION_COMMON(0x220)
|
EXCEPTION_COMMON(0x220)
|
||||||
INTS_DISABLE
|
|
||||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||||
#ifdef CONFIG_ALTIVEC
|
#ifdef CONFIG_ALTIVEC
|
||||||
BEGIN_FTR_SECTION
|
BEGIN_FTR_SECTION
|
||||||
|
@ -691,7 +662,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
|
||||||
NORMAL_EXCEPTION_PROLOG(0xf20, BOOKE_INTERRUPT_AP_UNAVAIL,
|
NORMAL_EXCEPTION_PROLOG(0xf20, BOOKE_INTERRUPT_AP_UNAVAIL,
|
||||||
PROLOG_ADDITION_NONE)
|
PROLOG_ADDITION_NONE)
|
||||||
EXCEPTION_COMMON(0xf20)
|
EXCEPTION_COMMON(0xf20)
|
||||||
INTS_DISABLE
|
|
||||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||||
bl unknown_exception
|
bl unknown_exception
|
||||||
b interrupt_return
|
b interrupt_return
|
||||||
|
@ -827,7 +797,6 @@ kernel_dbg_exc:
|
||||||
*/
|
*/
|
||||||
mfspr r14,SPRN_DBSR
|
mfspr r14,SPRN_DBSR
|
||||||
EXCEPTION_COMMON_DBG(0xd08)
|
EXCEPTION_COMMON_DBG(0xd08)
|
||||||
INTS_DISABLE
|
|
||||||
std r14,_DSISR(r1)
|
std r14,_DSISR(r1)
|
||||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||||
ld r14,PACA_EXDBG+EX_R14(r13)
|
ld r14,PACA_EXDBG+EX_R14(r13)
|
||||||
|
@ -840,7 +809,6 @@ kernel_dbg_exc:
|
||||||
NORMAL_EXCEPTION_PROLOG(0x260, BOOKE_INTERRUPT_PERFORMANCE_MONITOR,
|
NORMAL_EXCEPTION_PROLOG(0x260, BOOKE_INTERRUPT_PERFORMANCE_MONITOR,
|
||||||
PROLOG_ADDITION_NONE)
|
PROLOG_ADDITION_NONE)
|
||||||
EXCEPTION_COMMON(0x260)
|
EXCEPTION_COMMON(0x260)
|
||||||
INTS_DISABLE
|
|
||||||
CHECK_NAPPING()
|
CHECK_NAPPING()
|
||||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||||
bl performance_monitor_exception
|
bl performance_monitor_exception
|
||||||
|
@ -870,7 +838,6 @@ kernel_dbg_exc:
|
||||||
PROLOG_ADDITION_NONE)
|
PROLOG_ADDITION_NONE)
|
||||||
EXCEPTION_COMMON(0x2c0)
|
EXCEPTION_COMMON(0x2c0)
|
||||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||||
INTS_RESTORE_HARD
|
|
||||||
bl unknown_exception
|
bl unknown_exception
|
||||||
b interrupt_return
|
b interrupt_return
|
||||||
|
|
||||||
|
@ -891,7 +858,6 @@ kernel_dbg_exc:
|
||||||
PROLOG_ADDITION_NONE)
|
PROLOG_ADDITION_NONE)
|
||||||
EXCEPTION_COMMON(0x310)
|
EXCEPTION_COMMON(0x310)
|
||||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||||
INTS_RESTORE_HARD
|
|
||||||
bl unknown_exception
|
bl unknown_exception
|
||||||
b interrupt_return
|
b interrupt_return
|
||||||
|
|
||||||
|
@ -901,7 +867,6 @@ kernel_dbg_exc:
|
||||||
PROLOG_ADDITION_NONE)
|
PROLOG_ADDITION_NONE)
|
||||||
EXCEPTION_COMMON(0x320)
|
EXCEPTION_COMMON(0x320)
|
||||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||||
INTS_RESTORE_HARD
|
|
||||||
bl unknown_exception
|
bl unknown_exception
|
||||||
b interrupt_return
|
b interrupt_return
|
||||||
|
|
||||||
|
@ -911,7 +876,6 @@ kernel_dbg_exc:
|
||||||
PROLOG_ADDITION_NONE)
|
PROLOG_ADDITION_NONE)
|
||||||
EXCEPTION_COMMON(0x340)
|
EXCEPTION_COMMON(0x340)
|
||||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||||
INTS_RESTORE_HARD
|
|
||||||
bl unknown_exception
|
bl unknown_exception
|
||||||
b interrupt_return
|
b interrupt_return
|
||||||
|
|
||||||
|
@ -991,7 +955,6 @@ alignment_more:
|
||||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||||
ld r14,PACA_EXGEN+EX_R14(r13)
|
ld r14,PACA_EXGEN+EX_R14(r13)
|
||||||
ld r15,PACA_EXGEN+EX_R15(r13)
|
ld r15,PACA_EXGEN+EX_R15(r13)
|
||||||
INTS_RESTORE_HARD
|
|
||||||
bl alignment_exception
|
bl alignment_exception
|
||||||
REST_NVGPRS(r1)
|
REST_NVGPRS(r1)
|
||||||
b interrupt_return
|
b interrupt_return
|
||||||
|
|
Loading…
Reference in New Issue