Skip to content

Commit

Permalink
powerpc/64s/exception: Move soft-mask test to common code
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Nicholas Piggin authored and Michael Ellerman committed Apr 1, 2020
1 parent 8729c26 commit 0eddf32
Showing 1 changed file with 49 additions and 57 deletions.
106 changes: 49 additions & 57 deletions arch/powerpc/kernel/exceptions-64s.S
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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
Expand All @@ -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 */

/*
Expand All @@ -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)
Expand All @@ -2393,34 +2382,37 @@ 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
.else
RFI_TO_KERNEL
.endif
b .
MASKED_DEC_HANDLER(\hsrr\())
.endm

TRAMP_REAL_BEGIN(stf_barrier_fallback)
Expand Down Expand Up @@ -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

Expand Down

0 comments on commit 0eddf32

Please sign in to comment.