Skip to content

Commit

Permalink
powerpc/irq: Make alignment & program interrupt behave the same
Browse files Browse the repository at this point in the history
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: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Benjamin Herrenschmidt committed May 8, 2012
1 parent 56dfa7f commit a3512b2
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 10 deletions.
7 changes: 0 additions & 7 deletions arch/powerpc/include/asm/exception-64s.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,13 +288,6 @@ label##_hv: \
/* Exception addition: Hard disable interrupts */
#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 \
bl .save_nvgprs

Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/kernel/exceptions-64s.S
Original file line number Diff line number Diff line change
Expand Up @@ -768,8 +768,8 @@ alignment_common:
std r3,_DAR(r1)
std r4,_DSISR(r1)
bl .save_nvgprs
DISABLE_INTS
addi r3,r1,STACK_FRAME_OVERHEAD
ENABLE_INTS
bl .alignment_exception
b .ret_from_except

Expand Down
10 changes: 8 additions & 2 deletions arch/powerpc/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
addr, regs->nip, regs->link, code);
}

if (!arch_irq_disabled_regs(regs))
if (arch_irqs_disabled() && !arch_irq_disabled_regs(regs))
local_irq_enable();

memset(&info, 0, sizeof(info));
Expand Down Expand Up @@ -1019,7 +1019,9 @@ void __kprobes program_check_exception(struct pt_regs *regs)
return;
}

local_irq_enable();
/* We restore the interrupt state now */
if (!arch_irq_disabled_regs(regs))
local_irq_enable();

#ifdef CONFIG_MATH_EMULATION
/* (reason & REASON_ILLEGAL) would be the obvious thing here,
Expand Down Expand Up @@ -1069,6 +1071,10 @@ void alignment_exception(struct pt_regs *regs)
{
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 */
if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS))
fixed = fix_alignment(regs);
Expand Down

0 comments on commit a3512b2

Please sign in to comment.