powerpc/irq: Make alignment & program interrupt behave the same

Alignment was the last user of the ENABLE_INTS macro, which we can
now remove. All non-syscall exceptions now disable interrupts on
entry, they get re-enabled conditionally from C code. Don't
unconditionally re-enable in program check either, check the
original context.
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 56dfa7fa
...@@ -288,13 +288,6 @@ label##_hv: \ ...@@ -288,13 +288,6 @@ label##_hv: \
/* Exception addition: Hard disable interrupts */ /* Exception addition: Hard disable interrupts */
#define DISABLE_INTS SOFT_DISABLE_INTS(r10,r11) #define DISABLE_INTS SOFT_DISABLE_INTS(r10,r11)
/* Exception addition: Keep interrupt state */
#define ENABLE_INTS \
ld r11,PACAKMSR(r13); \
ld r12,_MSR(r1); \
rlwimi r11,r12,0,MSR_EE; \
mtmsrd r11,1
#define ADD_NVGPRS \ #define ADD_NVGPRS \
bl .save_nvgprs bl .save_nvgprs
......
...@@ -768,8 +768,8 @@ alignment_common: ...@@ -768,8 +768,8 @@ alignment_common:
std r3,_DAR(r1) std r3,_DAR(r1)
std r4,_DSISR(r1) std r4,_DSISR(r1)
bl .save_nvgprs bl .save_nvgprs
DISABLE_INTS
addi r3,r1,STACK_FRAME_OVERHEAD addi r3,r1,STACK_FRAME_OVERHEAD
ENABLE_INTS
bl .alignment_exception bl .alignment_exception
b .ret_from_except b .ret_from_except
......
...@@ -248,7 +248,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) ...@@ -248,7 +248,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
addr, regs->nip, regs->link, code); addr, regs->nip, regs->link, code);
} }
if (!arch_irq_disabled_regs(regs)) if (arch_irqs_disabled() && !arch_irq_disabled_regs(regs))
local_irq_enable(); local_irq_enable();
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
...@@ -1019,7 +1019,9 @@ void __kprobes program_check_exception(struct pt_regs *regs) ...@@ -1019,7 +1019,9 @@ void __kprobes program_check_exception(struct pt_regs *regs)
return; return;
} }
local_irq_enable(); /* We restore the interrupt state now */
if (!arch_irq_disabled_regs(regs))
local_irq_enable();
#ifdef CONFIG_MATH_EMULATION #ifdef CONFIG_MATH_EMULATION
/* (reason & REASON_ILLEGAL) would be the obvious thing here, /* (reason & REASON_ILLEGAL) would be the obvious thing here,
...@@ -1069,6 +1071,10 @@ void alignment_exception(struct pt_regs *regs) ...@@ -1069,6 +1071,10 @@ void alignment_exception(struct pt_regs *regs)
{ {
int sig, code, fixed = 0; int sig, code, fixed = 0;
/* We restore the interrupt state now */
if (!arch_irq_disabled_regs(regs))
local_irq_enable();
/* we don't implement logging of alignment exceptions */ /* we don't implement logging of alignment exceptions */
if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS))
fixed = fix_alignment(regs); fixed = fix_alignment(regs);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment