powerpc/64s/exception: Move soft-mask test to common code

As well as moving code out of the unrelocated vectors, this allows the
masked handlers to be moved to common code, and allows the soft_nmi
handler to be generated more like a regular handler.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200225173541.1549955-12-npiggin@gmail.com
This commit is contained in:
Nicholas Piggin 2020-02-26 03:35:20 +10:00 committed by Michael Ellerman
parent 8729c26e67
commit 0eddf327e1
1 changed files with 49 additions and 57 deletions

View File

@ -411,36 +411,6 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948)
.if (!\virt && IKVM_REAL) || (\virt && IKVM_VIRT)
KVMTEST \name IHSRR IVEC
.endif
.if IMASK
lbz r10,PACAIRQSOFTMASK(r13)
andi. r10,r10,IMASK
/* Associate vector numbers with bits in paca->irq_happened */
.if IVEC == 0x500 || IVEC == 0xea0
li r10,PACA_IRQ_EE
.elseif IVEC == 0x900
li r10,PACA_IRQ_DEC
.elseif IVEC == 0xa00 || IVEC == 0xe80
li r10,PACA_IRQ_DBELL
.elseif IVEC == 0xe60
li r10,PACA_IRQ_HMI
.elseif IVEC == 0xf00
li r10,PACA_IRQ_PMI
.else
.abort "Bad maskable vector"
.endif
.if IHSRR == EXC_HV_OR_STD
BEGIN_FTR_SECTION
bne masked_Hinterrupt
FTR_SECTION_ELSE
bne masked_interrupt
ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
.elseif IHSRR
bne masked_Hinterrupt
.else
bne masked_interrupt
.endif
.endif
std r11,IAREA+EX_R11(r13)
std r12,IAREA+EX_R12(r13)
@ -524,6 +494,37 @@ DEFINE_FIXED_SYMBOL(\name\()_common_virt)
.endm
.macro __GEN_COMMON_BODY name
.if IMASK
lbz r10,PACAIRQSOFTMASK(r13)
andi. r10,r10,IMASK
/* Associate vector numbers with bits in paca->irq_happened */
.if IVEC == 0x500 || IVEC == 0xea0
li r10,PACA_IRQ_EE
.elseif IVEC == 0x900
li r10,PACA_IRQ_DEC
.elseif IVEC == 0xa00 || IVEC == 0xe80
li r10,PACA_IRQ_DBELL
.elseif IVEC == 0xe60
li r10,PACA_IRQ_HMI
.elseif IVEC == 0xf00
li r10,PACA_IRQ_PMI
.else
.abort "Bad maskable vector"
.endif
.if IHSRR == EXC_HV_OR_STD
BEGIN_FTR_SECTION
bne masked_Hinterrupt
FTR_SECTION_ELSE
bne masked_interrupt
ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
.elseif IHSRR
bne masked_Hinterrupt
.else
bne masked_interrupt
.endif
.endif
.if ISTACK
andi. r10,r12,MSR_PR /* See if coming from user */
mr r10,r1 /* Save r1 */
@ -2330,18 +2331,10 @@ EXC_VIRT_NONE(0x5800, 0x100)
#ifdef CONFIG_PPC_WATCHDOG
#define MASKED_DEC_HANDLER_LABEL 3f
#define MASKED_DEC_HANDLER(_H) \
3: /* soft-nmi */ \
std r12,PACA_EXGEN+EX_R12(r13); \
GET_SCRATCH0(r10); \
std r10,PACA_EXGEN+EX_R13(r13); \
mfspr r11,SPRN_SRR0; /* save SRR0 */ \
mfspr r12,SPRN_SRR1; /* and SRR1 */ \
LOAD_HANDLER(r10, soft_nmi_common); \
mtctr r10; \
bctr
INT_DEFINE_BEGIN(soft_nmi)
IVEC=0x900
ISTACK=0
INT_DEFINE_END(soft_nmi)
/*
* Branch to soft_nmi_interrupt using the emergency stack. The emergency
@ -2353,19 +2346,16 @@ EXC_VIRT_NONE(0x5800, 0x100)
* and run it entirely with interrupts hard disabled.
*/
EXC_COMMON_BEGIN(soft_nmi_common)
mfspr r11,SPRN_SRR0
mr r10,r1
ld r1,PACAEMERGSP(r13)
subi r1,r1,INT_FRAME_SIZE
__ISTACK(decrementer)=0
__GEN_COMMON_BODY decrementer
__GEN_COMMON_BODY soft_nmi
bl save_nvgprs
addi r3,r1,STACK_FRAME_OVERHEAD
bl soft_nmi_interrupt
b ret_from_except
#else /* CONFIG_PPC_WATCHDOG */
#define MASKED_DEC_HANDLER_LABEL 2f /* normal return */
#define MASKED_DEC_HANDLER(_H)
#endif /* CONFIG_PPC_WATCHDOG */
/*
@ -2384,7 +2374,6 @@ masked_Hinterrupt:
.else
masked_interrupt:
.endif
std r11,PACA_EXGEN+EX_R11(r13)
lbz r11,PACAIRQHAPPENED(r13)
or r11,r11,r10
stb r11,PACAIRQHAPPENED(r13)
@ -2393,26 +2382,30 @@ masked_interrupt:
lis r10,0x7fff
ori r10,r10,0xffff
mtspr SPRN_DEC,r10
b MASKED_DEC_HANDLER_LABEL
#ifdef CONFIG_PPC_WATCHDOG
b soft_nmi_common
#else
b 2f
#endif
1: andi. r10,r10,PACA_IRQ_MUST_HARD_MASK
beq 2f
xori r12,r12,MSR_EE /* clear MSR_EE */
.if \hsrr
mfspr r10,SPRN_HSRR1
xori r10,r10,MSR_EE /* clear MSR_EE */
mtspr SPRN_HSRR1,r10
mtspr SPRN_HSRR1,r12
.else
mfspr r10,SPRN_SRR1
xori r10,r10,MSR_EE /* clear MSR_EE */
mtspr SPRN_SRR1,r10
mtspr SPRN_SRR1,r12
.endif
ori r11,r11,PACA_IRQ_HARD_DIS
stb r11,PACAIRQHAPPENED(r13)
2: /* done */
ld r10,PACA_EXGEN+EX_CTR(r13)
mtctr r10
mtcrf 0x80,r9
std r1,PACAR1(r13)
ld r9,PACA_EXGEN+EX_R9(r13)
ld r10,PACA_EXGEN+EX_R10(r13)
ld r11,PACA_EXGEN+EX_R11(r13)
ld r12,PACA_EXGEN+EX_R12(r13)
/* returns to kernel where r13 must be set up, so don't restore it */
.if \hsrr
HRFI_TO_KERNEL
@ -2420,7 +2413,6 @@ masked_interrupt:
RFI_TO_KERNEL
.endif
b .
MASKED_DEC_HANDLER(\hsrr\())
.endm
TRAMP_REAL_BEGIN(stf_barrier_fallback)
@ -2527,7 +2519,7 @@ TRAMP_REAL_BEGIN(hrfi_flush_fallback)
* instruction code patches (which end up in the common .text area)
* cannot reach these if they are put there.
*/
USE_FIXED_SECTION(virt_trampolines)
USE_TEXT_SECTION()
MASKED_INTERRUPT EXC_STD
MASKED_INTERRUPT EXC_HV