mirror of
https://github.com/torvalds/linux.git
synced 2026-06-04 12:35:52 +02:00
powerpc/64s: move NMI soft-mask handling to C
Saving and restoring soft-mask state can now be done in C using the interrupt handler wrapper functions. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20210130130852.2952424-41-npiggin@gmail.com
This commit is contained in:
parent
118178e62e
commit
6ecbb582b6
|
|
@ -95,6 +95,10 @@ static inline void interrupt_async_exit_prepare(struct pt_regs *regs, struct int
|
|||
|
||||
struct interrupt_nmi_state {
|
||||
#ifdef CONFIG_PPC64
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
u8 irq_soft_mask;
|
||||
u8 irq_happened;
|
||||
#endif
|
||||
u8 ftrace_enabled;
|
||||
#endif
|
||||
};
|
||||
|
|
@ -102,6 +106,20 @@ struct interrupt_nmi_state {
|
|||
static inline void interrupt_nmi_enter_prepare(struct pt_regs *regs, struct interrupt_nmi_state *state)
|
||||
{
|
||||
#ifdef CONFIG_PPC64
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
state->irq_soft_mask = local_paca->irq_soft_mask;
|
||||
state->irq_happened = local_paca->irq_happened;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/* Don't do any per-CPU operations until interrupt state is fixed */
|
||||
#endif
|
||||
/* Allow DEC and PMI to be traced when they are soft-NMI */
|
||||
if (TRAP(regs) != 0x900 && TRAP(regs) != 0xf00 && TRAP(regs) != 0x260) {
|
||||
state->ftrace_enabled = this_cpu_get_ftrace_enabled();
|
||||
|
|
@ -129,6 +147,13 @@ static inline void interrupt_nmi_exit_prepare(struct pt_regs *regs, struct inter
|
|||
#ifdef CONFIG_PPC64
|
||||
if (TRAP(regs) != 0x900 && TRAP(regs) != 0xf00 && TRAP(regs) != 0x260)
|
||||
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
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1008,20 +1008,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
|
||||
|
|
@ -1037,14 +1023,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_kernel_restore r9, r10
|
||||
EXCEPTION_RESTORE_REGS
|
||||
RFI_TO_USER_OR_KERNEL
|
||||
|
|
@ -1190,30 +1168,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
|
||||
|
|
@ -2818,17 +2777,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
|
||||
|
||||
|
|
@ -2836,14 +2784,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_kernel_restore r9, r10
|
||||
EXCEPTION_RESTORE_REGS hsrr=0
|
||||
RFI_TO_KERNEL
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user