mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-05 01:54:09 +08:00
powerpc: add interrupt_cond_local_irq_enable helper
Simple helper for synchronous interrupt handlers (i.e., process-context) to enable interrupts if it was taken in an interrupts-enabled context. 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-30-npiggin@gmail.com
This commit is contained in:
parent
3a96570ffc
commit
e6f8a6c86c
@ -3,6 +3,7 @@
|
||||
#define _ASM_POWERPC_INTERRUPT_H
|
||||
|
||||
#include <linux/context_tracking.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <asm/ftrace.h>
|
||||
|
||||
struct interrupt_state {
|
||||
@ -298,4 +299,10 @@ DECLARE_INTERRUPT_HANDLER_ASYNC(TAUException);
|
||||
void replay_system_reset(void);
|
||||
void replay_soft_interrupts(void);
|
||||
|
||||
static inline void interrupt_cond_local_irq_enable(struct pt_regs *regs)
|
||||
{
|
||||
if (!arch_irq_disabled_regs(regs))
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
#endif /* _ASM_POWERPC_INTERRUPT_H */
|
||||
|
@ -343,8 +343,8 @@ static bool exception_common(int signr, struct pt_regs *regs, int code,
|
||||
|
||||
show_signal_msg(signr, regs, code, addr);
|
||||
|
||||
if (arch_irqs_disabled() && !arch_irq_disabled_regs(regs))
|
||||
local_irq_enable();
|
||||
if (arch_irqs_disabled())
|
||||
interrupt_cond_local_irq_enable(regs);
|
||||
|
||||
current->thread.trap_nr = code;
|
||||
|
||||
@ -1555,9 +1555,7 @@ static void do_program_check(struct pt_regs *regs)
|
||||
if (!user_mode(regs))
|
||||
goto sigill;
|
||||
|
||||
/* We restore the interrupt state now */
|
||||
if (!arch_irq_disabled_regs(regs))
|
||||
local_irq_enable();
|
||||
interrupt_cond_local_irq_enable(regs);
|
||||
|
||||
/* (reason & REASON_ILLEGAL) would be the obvious thing here,
|
||||
* but there seems to be a hardware bug on the 405GP (RevD)
|
||||
@ -1622,9 +1620,7 @@ DEFINE_INTERRUPT_HANDLER(alignment_exception)
|
||||
int sig, code, fixed = 0;
|
||||
unsigned long reason;
|
||||
|
||||
/* We restore the interrupt state now */
|
||||
if (!arch_irq_disabled_regs(regs))
|
||||
local_irq_enable();
|
||||
interrupt_cond_local_irq_enable(regs);
|
||||
|
||||
reason = get_reason(regs);
|
||||
|
||||
@ -1785,9 +1781,7 @@ DEFINE_INTERRUPT_HANDLER(facility_unavailable_exception)
|
||||
die("Unexpected facility unavailable exception", regs, SIGABRT);
|
||||
}
|
||||
|
||||
/* We restore the interrupt state now */
|
||||
if (!arch_irq_disabled_regs(regs))
|
||||
local_irq_enable();
|
||||
interrupt_cond_local_irq_enable(regs);
|
||||
|
||||
if (status == FSCR_DSCR_LG) {
|
||||
/*
|
||||
@ -2172,9 +2166,7 @@ DEFINE_INTERRUPT_HANDLER(SPEFloatingPointException)
|
||||
int code = FPE_FLTUNK;
|
||||
int err;
|
||||
|
||||
/* We restore the interrupt state now */
|
||||
if (!arch_irq_disabled_regs(regs))
|
||||
local_irq_enable();
|
||||
interrupt_cond_local_irq_enable(regs);
|
||||
|
||||
flush_spe_to_thread(current);
|
||||
|
||||
@ -2221,9 +2213,7 @@ DEFINE_INTERRUPT_HANDLER(SPEFloatingPointRoundException)
|
||||
extern int speround_handler(struct pt_regs *regs);
|
||||
int err;
|
||||
|
||||
/* We restore the interrupt state now */
|
||||
if (!arch_irq_disabled_regs(regs))
|
||||
local_irq_enable();
|
||||
interrupt_cond_local_irq_enable(regs);
|
||||
|
||||
preempt_disable();
|
||||
if (regs->msr & MSR_SPE)
|
||||
|
@ -434,9 +434,7 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
|
||||
return bad_area_nosemaphore(regs, address);
|
||||
}
|
||||
|
||||
/* We restore the interrupt state now */
|
||||
if (!arch_irq_disabled_regs(regs))
|
||||
local_irq_enable();
|
||||
interrupt_cond_local_irq_enable(regs);
|
||||
|
||||
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user